PowerShell v6.1

PowerShell v6.1 was released last week – there’s no big ticket items like v6.0 but a lot of bug fixes and minor improvements.

You can download from https://github.com/PowerShell/PowerShell/releases

and find the release notes at

https://docs.microsoft.com/en-us/powershell/scripting/whats-new/what-s-new-in-powershell-core-61?view=powershell-6

Advertisements
Posted in PowerShell v6 | Leave a comment

Get-Date –DisplayHint

On the surface Get-Date is a simple cmdlet that’s been around since PowerShell v1. However, it has some interesting quirks. In this post I’ll show how Get-Date  –DisplayHint works.

By default Get-Date returns the data and time

PS>  Get-Date

13 September 2018 16:09:34

The DisplayHint parameter ( available in PowerShell v5.1, 6.0 and 6.1) modifies the data shown

PS>  Get-Date -DisplayHint Date

13 September 2018

PS>  Get-Date -DisplayHint DateTime

13 September 2018 16:11:18

PS>  Get-Date -DisplayHint Time

16:11:25

You might think that all –DisplayHint does is just force the display to be date, time or datetime and you’ve lost the rest of the data but in reality all that’s happening is that the default display of your object is constrained by the value of the DisplayHint property:

PS> Get-Date | Get-Member -Name DisplayHint

    TypeName: System.DateTime

Name        MemberType   Definition
—-        ———-   ———-
DisplayHint NoteProperty DisplayHintType DisplayHint=DateTime

PS>  Get-Date -DisplayHint Date | Get-Member -Name DisplayHint

    TypeName: System.DateTime

Name        MemberType   Definition
—-        ———-   ———-
DisplayHint NoteProperty DisplayHintType DisplayHint=Date

PS>  Get-Date -DisplayHint Time | Get-Member -Name DisplayHint

    TypeName: System.DateTime

Name        MemberType   Definition
—-        ———-   ———-
DisplayHint NoteProperty DisplayHintType DisplayHint=Time

Note that DateTime is the default setting if –DisplayHint isn’t used.

PS>  $t = Get-Date -DisplayHint Time
PS>  $t

16:16:59

But you can still access the other properties of the datetime object returned by get-date

PS>  $t.Date

13 September 2018 00:00:00

PS>  $t.Year
2018
PS>  $t.Hour
16

If you just need to see the date or time –DisplayHint is a good place to start

Posted in Powershell | Leave a comment

PowerShell new line

A PowerShell new line can be generated using `n. It’s one of a series of special characters recognised by PowerShell.

The full list of Windows PowerShell v5.1 special characters is:

`0    Null
`a    Alert
`b    Backspace
`f    Form feed
`n    New line
`r    Carriage return
`t    Horizontal tab
`v    Vertical tab
–%   Stop parsing

Here’s some examples:

`0 is a null character – empty space

PS> “abcd`0efg”
abcd efg

`a causes the machine to issue an alert – beep

PS> “`a Beep “; “`a Beep”
  Beep
  Beep

Two alerts are sent but you might only hear one.

The backspace character moves the cursor back one space overwriting the character that was there:

PS> “abcd`befg”
abcefg

Form feed is for printers only

A new line is added by `n

PS> “abc`nde`nfg”
abc
de
fg

The carriage return returns the cursor to the beginning of the line so any text before it will be overwrittem

PS> “This original text`rIs overwritten by this brand new text”
Is overwritten by this brand new text

A horizontal tab is added by `t

PS> “This`twill`ttab`tacross`tthe`tscreen”
This    will    tab     across  the     screen

And `v for vertical tabs but only when printing documents – it doesn’t work on screen output

You can use –% to stop interpreting input as PowerShell commands or expressions. In this case PowerShell attempts to evaluate $x

PS> Write-Host $x = a variable
  = a variable

but what you really want is

PS> Write-Host –%  $x = a variable
–% $x = a variable

Unfortunately, you also get the –% come through.

The about_parsing help file has an example using icacls.

You’ll have noticed that all of the examples were in double quotes – single quotes stop the special character being recognised:

PS> “This`twill`ttab`tacross`tthe`tscreen”
This    will    tab     across  the     screen
PS> ‘This`twill`ttab`tacross`tthe`tscreen’
This`twill`ttab`tacross`tthe`tscreen

PowerShell v6 introduced `u for working with unicode characters

PS>  “`u{2195}”

you can have 1 – 6 hex chacraters with a maximim value of 10FFFF

Posted in Powershell, PowerShell v5, PowerShell v6 | Leave a comment

PowerShell check file exists

There are times when you need to check if a file exists – this is how you do a PowerShell check file exists.

If you try to access a file that doesn’t exist you’ll get an error:

PS> Get-Content -Path c:\test\z27.txt
Get-Content : Cannot find path ‘C:\test\z27.txt’ because it does not exist.
At line:1 char:1
+ Get-Content -Path c:\test\z27.txt
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
     + CategoryInfo          : ObjectNotFound: (C:\test\z27.txt:String) [Get-Content], ItemNotFoundException
     + FullyQualifiedErrorId : PathNotFound,Microsoft.PowerShell.Commands.GetContentCommand

Rather than manage the error directly you can test to see if the file exists

PS> Test-Path -Path c:\test\z27.txt
False

Test-Path returns a boolean (true or false) so you can then test the file exists before accessing

PS> if (Test-Path -Path c:\test\z27.txt) {Get-Content -Path c:\test\z27.txt}

You’d obviously add an else block to deal with the case of the file not existing – possibly just a warning or a throw depending on what you were doing,

You can also test if a folder exists

PS> Test-Path -Path c:\test\
True
PS> Test-Path -Path c:\test27\
False

You can be more exact with whether you’re dealing with a folder or a file by using the –PathType parameter

PS> Test-Path -Path c:\test -PathType Any
True
PS> Test-Path -Path c:\test -PathType Container
True
PS> Test-Path -Path c:\test -PathType Leaf
False
PS> Test-Path -Path C:\test\p1.txt -PathType Container
False
PS> Test-Path -Path C:\test\p1.txt -PathType Leaf
True

Use container for a folder and leaf for a file.

Alternatively you can use –Filter, –Include and –Exclude but remember you’ll only get a boolean returned so

PS> Test-Path -Path C:\test\* -Filter *.txt
True

gives a single return even though there are 20 .txt files in the folder!

Your last alternative is to –OlderThan or –NewerThan to test against a files age

PS> Test-Path C:\test\* -Filter *.txt -NewerThan ((Get-Date).AddDays(-3))
False
PS> Test-Path C:\test\* -Filter *.txt -OlderThan ((Get-Date).AddDays(-7))
True

I do have .txt files older than 7 days but none younger than 3 days old.

The –LiteralPath parameter  means that the path is used exactly as given and ignores any possible interpretation of a character as anything else. use it instead of –Path.

Finally –IsValid tests the validity of the path syntax even if the path doesn’t exist so

PS> Test-Path -Path C:\test\z27.txt
False
PS> Test-Path -Path C:\test\z27.txt -IsValid
True

The file itself doesn’t exist but the path is valid.  Conversely

PS> Test-Path -Path C:\test\p1.txt
True
PS> Test-Path -Path C:\test\p1.txt -IsValid
True
PS> Test-Path -Path C:\test\p?1.txt -IsValid
False
PS> Test-Path -LiteralPath C:\test\p?1.txt -IsValid
False

p1.txt exists and has a valid path but p?1.txt isn’t a valid path.

On Windows folder and file names are case INSENSITIVE so

PS> Test-Path -Path C:\test\p1.txt
True
PS> Test-Path -Path C:\tEsT\p1.txt
True

both work.

On Linux folder and file names are case sensitive so be aware. How to deal with this situation is currently under discussion

https://github.com/PowerShell/PowerShell/issues/7578

Posted in Powershell | Leave a comment

Hyper-V book soon available

I’ve been working with Andy Syrewicze on a Hyper-V book that’ll be available in the next few months.

https://www.apress.com/gb/book/9781484241158

https://www.amazon.co.uk/Pro-Microsoft-Hyper-V-2019-Hands/dp/1484241150/ref=sr_1_1?s=books&ie=UTF8&qid=1536253236&sr=1-1&keywords=Hyper-V+siddaway

https://www.amazon.com/Pro-Microsoft-Hyper-V-2019-Hands/dp/1484241150/ref=sr_1_1?ie=UTF8&qid=1536253327&sr=8-1&keywords=hyper-v+siddaway

Its’s a rewrite and update of the Month of Lunches book I was working on a while back.

Pleased with the way it turned out and hope you’ll find it useful

Posted in Hyper-V, Powershell | Leave a comment

PowerShell string contains

How can you check if a PowerShell string contains a character or substring?

You might be tempted to try this:

PS> $s = ‘abcdefghijk’
PS> $s -contains ‘f’
False

But –contains is for working with the contents of arrays. So you could do this:

PS> ($s.ToCharArray()) -contains ‘f’
True

You’re implicitly converting the string ‘f’ to [char] to make the comparison. Your comparison is actually this

PS> ($s.ToCharArray()) -contains [char]’f’
True

That’s fine for a single character but if you want to test a substring

PS> $s -contains ‘def’
False
PS> ($s.ToCharArray()) -contains ‘def’
False

That approach won’t work.

You need to use the Indexof method

PS> $s.Indexof(‘f’)
5
PS> $s.Indexof(‘def’)
3

The value returned is the position of the FIRST character in the substring.

You can also test an an array of characters

PS> $a = ‘g’,’j’,’a’
PS> $s.IndexOfAny($a)
0

Again you get the FIRST character in this case the ‘a’  

Remember PowerShell is .NET based so the first index is 0

Lets get some repetition into our target

PS> $s = $s * 3

PS> $s
abcdefghijkabcdefghijkabcdefghijk

You also have the option of picking the LAST occurrence of the substring

PS> $s.LastIndexOf(‘f’)
27

PS> $s.LastIndexOfAny($a)
31

This last one is the last ‘j’ in the string – its the last occurrence of any of the characters you wanted to match.

If there isn’t a match you get –1 returned

PS> $s.IndexOf(‘z’)
-1
PS> $s.LastIndexOf(‘z’)
-1

Posted in Powershell | 1 Comment

PowerShell Day UK Agenda Update

There’s been a Powershell Day UK Agenda Update.

Looks like there’ll be three tracks for most of the day.

Full agenda and tickets from – https://psday.uk/

Posted in Powershell | Leave a comment