Monthly Archive


PowerShell Line continuation

There are a number of ways to signal PowerShell line continuation in your code. probably the most common is to have a pipeline symbol at the end of the line:

Get-Process |
Sort-Object -Property CPU -Descending -Top 5


because there’s nothing after the pipe symbol PowerShell assumes that the next line of code is actually a continuation and treats the 2 lines of code as a single pipeline. This is especially good if you have a very long pipeline with incorporating numerous cmdlets.


Since the days of PowerShell v1 many people have asked to be able to the pipe symbol at the beginning of the continuation line rather than at the end of the first line. The only way you could do that was to use the backtick ` symbol to signify line continuation:

Get-Process `
| Sort-Object -Property CPU -Descending -Top 5


This is an ugly approach as the back tick is a very small character its often overlooked when reading or working with the code which can lead to bugs.


PowerShell 7 allows you to use the pipe symbol at the start of a line as a continuation character without needing the backtick:

| Sort-Object -Property CPU -Descending -Top 5


Over the years many people, especially those new to PowerShell, have complained that there are sometimes too many different ways in PowerShell to achieve the result you want. To my mind this change of one of those unnecessary changes that just add complexity (of choice) for no real benefit. PowerShell is an open source project and if someone wants to add something like this then the opportunity is there. I’ll be sticking to the pipe symbol at the endo of the line approach as I don’t see any advantage to changing and I find the original approach easier to understand.

Test DNS servers

Had a recent comment about testing DNS servers which got me thinking how do I test DNS servers.

I decided I wanted to get the DNS server address from the client, ping the DNS server to test network connectivity and test if DNS was up and working. The current result is this:

function test-dnsserver {

## get-dns server address
$addresses = Get-DnsClientServerAddress -AddressFamily IPv4 -InterfaceAlias LAN |
Select-Object -ExpandProperty ServerAddresses

## test servers
foreach ($address in $addresses){
$resolved = $false
$ping = Test-Connection -TargetName $address -Quiet -Count 1
$server = Resolve-DnsName -Name $address -Server $address

if ($server.NameHost) {
$serverName = $server.NameHost
$resolved = $true
else {
$serverName = 'DNS unreachable'

$props = [ordered]@{
DNSserverName = $serverName
DNSserverIP = $address
Pingable = $ping
Resolved = $resolved

New-Object -TypeName PSObject -Property $props


I always set my network interface alias to LAN so you may want to change that or even make it a parameter.


Use Get-DNSCleintServerAddress from the DNSclient module to get the DNS server addresses.


Loop through the addresses – you could make this a single pipeline if you wanted rather than using foreach loop.


Run a ping test using Test-Connection. the version of Test-Connection in PowerShell core is truly horrible as it prints a whole load of stuff to screen even in quiet mode. One of these days I need to write a ping type function that actually works like I want – similar to the Windows PowerShell Test-Connection.


Use Resolve-DNSname, again from the DNSclient module, to resolve the server address on the DNS server. If thsi works you should get the DNS server name back in the NameHost property even if you don’t have a reverses lookup zone! Change resolved to $true in this case.


The results give you the DNS server name, IP address, if its ping able and if it can perform DNS resolution. If you can’t ping it then either the servers down or you have network problems. If it can’t perform the resolution then DNS is down or it doesn’t have a record for itself. Further investigation is then required.


Test isn’t perfect but it does give you a reasonable idea of where problems might be.

Windows Terminal

Microsoft have released the first preview of the new Windows Terminal to the Windows store -


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.

PowerShell 7 roadmap

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


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.

Start Jobs with &

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).

Install-Module and Update-Module Scope parameter

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

Get-Date -UFormat

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

Get-Date –Format

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 - – 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'

Exclusive OR

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?

Useful constants

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