PowerShell for Windows Admins

June 22, 2019  3:59 AM

Windows Terminal

Richard Siddaway Richard Siddaway Profile: Richard Siddaway
Windows 10

Microsoft have released the first preview of the new Windows Terminal to the Windows store – https://devblogs.microsoft.com/commandline/windows-terminal-microsoft-store-preview-release/

Its currently only available for Windows 10 v18362 or later.

The terminal is a replacement for the very elderly Windows console – used for command prompt and PowerShell.

Some improvements over the old console include multiple tabs, Unicode and UTF-8 support and custom themes, styles and configurations.

Be interesting to see if its actually a good replacement or just makes life more complicated. I’ll post more after some experimentation.

June 21, 2019  5:32 AM

PowerShell 7 roadmap

Richard Siddaway Richard Siddaway Profile: Richard Siddaway

It was recently announced that the next version of PowerShell core will be 7.0 not 6.3. The PowerShell 7 roadmap is available at https://devblogs.microsoft.com/powershell/powershell-7-road-map/

The highlights are PowerShell 7 eventually replacing Windows PowerShell but I expect that’ll be 7.x rather than 7.0 as the mechanisms to update PowerShell aren’t in place. The Windows PowerShell modules that currently don’t work with PowerShell core will be updated to work directly in core – no more WindowsCompatibility module. Expect this to happen only on latest Windows 10 and windows server editions.

The PowerShell support life cycle changes to match .NET core

PowerShell 7 to use .NET Core 3.0 which will bring back some of the missing APIs including WPF and WinForms meaning Out-GridView will return on Windows

Three features are explicitly mentioned; – Secure Credentials management, Looging off the box and new version notifications.

Requested features are listed of which the most useful is probably Foreach-Object parallel as a (partial) replacement for workflows.

The opportunity is here for you to comment on RFCs and provide feedback to the PowerShell team. This is your chance to help shape PowerShell 7.

June 20, 2019  4:22 AM

Start Jobs with &

Richard Siddaway Richard Siddaway Profile: Richard Siddaway

You usually start background jobs using Start-Job. Now you can start jobs with &. As of PowerShell v6.0 putting & at the end of a pipeline causes the pipeline to be run as a PowerShell job, for instance this pipeline:

PS> Get-Process | Sort-Object -Property CPU -Top 5

Is run as a background job by adding & to the end of the pipeline:

PS> Get-Process | Sort-Object -Property CPU -Top 5 &

When a pipeline is backgrounded, a job object is returned. Once the pipeline is running as a job, all of the standard job cmdlets can be used to manage the job. Variables (ignoring process-specific variables) used in the pipeline are automatically copied to the job so

Copy-Item -Path $path -Destination $dest &

just works without the need for the $using scope modifier or an argument list.

I recommend this technique for interactive working but that you use Start-Job in your scripts for more control (such as naming the job).

June 19, 2019  9:22 AM

Install-Module and Update-Module Scope parameter

Richard Siddaway Richard Siddaway Profile: Richard Siddaway

I’ve written a couple of times this year on the problems around the PowerShellGet module and the Scope (Allusers or CurrentUsers). The situation is a lot easier now that Install-Module and Update-Module Scope parameter is available.

Install-Module has always had a Scope parameter.

Update-Module has a Scope parameter as of PowerShell v6.2.1 and Powershell v7.0 preview 1.

I’ve changed mu profile to define the Scope parameter for both cmdlets as a default parameter:

$PSDefaultParameterValues = @{‘Install-Module:Scope’=’AllUsers’; ‘Update-Module:Scope’=’AllUsers’}

The rules for Install-Module default scopes seem to have changed with them now being:

When no Scope is defined, the default is set based on the PowerShellGet version.

In PowerShellGet versions 2.0.0 and above, the default is CurrentUser, which does not require elevation for install.

In PowerShellGet 1.x versions, the default is AllUsers, which requires elevation for install.

The documentation hasn’t caught up to Update-Module but past experience suggests it follows the same rules.

This is a good change as it gives back control of where the user puts the module, Too much software these days forces the developer’s assumptions on the user with no option to override. Its good to get the control back

May 27, 2019  1:48 PM

Get-Date -UFormat

Richard Siddaway Richard Siddaway Profile: Richard Siddaway

The Get-Date -UFormat parameter formats the date using Unix format. The full list of format specifiers are in the Notes section of the Get-Date help file.

Some examples are:

PS> Get-Date -UFormat ‘%Y-%m-%d %H:%M%:%S%Z’
2019-05-27 20:40:11+01

4 digit year – two digit month and day. Hour in 24 hour format and minutes and seconds and finally time zone as offset from GMT

Date in locale format

PS> Get-Date -UFormat %x

though it shows a US format for a UK locale?

PS> Get-Date -UFormat ‘%A %d %B %Y’
Monday 27 May 2019

day of week – day – Month (full name) 4 digit year.

Between the Format parameter and the UFormat parameter you should be able to get the date information into any format you require

May 27, 2019  5:58 AM

Get-Date –Format

Richard Siddaway Richard Siddaway Profile: Richard Siddaway

Get-Date –Format enables you to control the formatting of the datetime object returned by the cmdlet.

A standard call to get date returns:

PS> Get-Date

27 May 2019 12:36:47

The –Format parameter takes a value from the DateTimeFormatInfo class – https://docs.microsoft.com/en-us/dotnet/api/system.globalization.datetimeformatinfo?view=netframework-4.8 – to specify how you want the information to be formatted.

For instance:

Short and long forms of the date with no time

PS> Get-Date -Format d
PS> Get-Date -Format D
27 May 2019

Full date and short or long time

PS> Get-Date -Format f
27 May 2019 12:48
PS> Get-Date -Format F
27 May 2019 12:48:38

No year or time

PS> Get-Date -Format m
27 May
PS> Get-Date -Format M
27 May

RFC1123 compliant

PS> Get-Date -Format R
Mon, 27 May 2019 12:50:07 GMT
PS> Get-Date -Format r
Mon, 27 May 2019 12:50:10 GMT


PS> Get-Date -Format s

Short and long time only

PS> Get-Date -Format t
PS> Get-Date -Format T

Sortable Universal time

PS> Get-Date -Format u
2019-05-27 12:51:55Z

Z refers to the time zone

Specify day month year format

PS> Get-Date -Format ‘dd/MM/yyyy’

May 26, 2019  3:37 PM

Exclusive OR

Richard Siddaway Richard Siddaway Profile: Richard Siddaway

PowerShell has a number of logical operators – – -and, –or, –not (or !). One I’ve really thought about is the exclusive OR operator –xor.

With a standard –or operator the result is TRUE if one of the statements is TRUE

PS> (‘a’ -eq ‘A’) -or (‘a’ -eq ‘z’)

The standard –or operator is also TRUE if both statements are true

PS> (‘a’ -eq ‘A’) -or (‘Z’ -eq ‘z’)

The exclusive OR is only TRUE when one of the statements is TRUE and the other is FALSE. So this returns TRUE

PS> (‘a’ -eq ‘A’) -xor (‘a’ -eq ‘z’)

But when both statements are TRUE it returns FALSE

PS> (‘a’ -eq ‘A’) -xor (‘Z’ -eq ‘z’)

The exclusive OR seems like bit of an oddity to me.

PowerShell has a bitwise xor operator — -bxor but outside of that I’m struggling to find a use for –xor. Certainly as an admin I can’t think of a situation where I’d use it.

Just out curiosity have you used –xor and if so how?

May 26, 2019  2:01 PM

Useful constants

Richard Siddaway Richard Siddaway Profile: Richard Siddaway

PowerShell provides easy access to some useful constants. I often see people calculating these values rather than using the constants.

PowerShell recognises kb, mb, gb, tb and pb for kilobyte, megabyte, gigabyte, terabyte and petabyte respectively. You can use them like this:

PS> 1kb; 1mb; 1gb, 1tb, 1pb

Don’t leave a space between the value and the constant.

You can use them in calculations:

PS> 7247437567256292 / 1gb
PS> 7247437567256292 / 1tb
PS> 7247437567256292 / 1pb

Fractional values are allowed:

PS> 27.457gb

You can use upper case or lower case to denote the constant

PS> 27.457gb
PS> 27.457GB

Next time you need to work with megabytes or other common constants don’t calculate them use the constants in PowerShell

May 25, 2019  3:54 PM

Articles published in 2019

Richard Siddaway Richard Siddaway Profile: Richard Siddaway

I’ve had the following articles published in 2019





May 25, 2019  3:42 PM

Stable sort

Richard Siddaway Richard Siddaway Profile: Richard Siddaway

In Windows PowerShell if you do something like this:

PS> (1..20 | Sort-Object -Property {$_ % 3}) -join ‘ ‘
9 6 12 15 3 18 19 16 13 10 4 1 7 20 17 2 8 11 5 14

The results come back in an unexpected order. This is not a stable sort as the results are sorted by their modulus result but lose the order within each group.

If you want a stable sort – where the results come back from a calculation like this in the order in they were received you need to add the –Stable switch. BUT that was added to PowerShell v6.1 and later

PS> (1..20 | Sort-Object -Property {$_ % 3} -Stable ) -join ‘ ‘
3 6 9 12 15 18 1 4 7 10 13 16 19 2 5 8 11 14 17 20

The results are sorted by modulus result and correctly within each group of modulus results

You could also use the Top or Bottom parameters:

PS> (1..20 | Sort-Object -Property {$_ % 3} -Top 20 ) -join ‘ ‘
3 6 9 12 15 18 1 4 7 10 13 16 19 2 5 8 11 14 17 20
PS> (1..20 | Sort-Object -Property {$_ % 3} -Bottom 20 ) -join ‘ ‘
3 6 9 12 15 18 1 4 7 10 13 16 19 2 5 8 11 14 17 20

If you alter the values presented to Top and Bottom you’ll get a subset of the results

PS> (1..20 | Sort-Object -Property {$_ % 3} -Top 10 ) -join ‘ ‘
3 6 9 12 15 18 1 4 7 10
PS> (1..20 | Sort-Object -Property {$_ % 3} -Bottom 10 ) -join ‘ ‘
13 16 19 2 5 8 11 14 17 20

Sort-Object in PowerShell Core has an interesting set of additions compared to Windows PowerShell.

Forgot Password

No problem! Submit your e-mail address below. We'll send you an e-mail containing your password.

Your password has been sent to: