PowerShell for Windows Admins

December 30, 2017  6:58 AM

Cross platform PowerShell remoting

Richard Siddaway Richard Siddaway Profile: Richard Siddaway

An interesting article on the Scripting Guy blog – https://blogs.technet.microsoft.com/heyscriptingguy/2017/12/29/cross-platform-powershell-remoting-in-action/

discusses using SSH remoting in PowerShell v6.

Some of the code needs tightening up but its a good first step for combining v6 and v5.1

December 28, 2017  10:34 AM

2017 – a year of PowerShell

Richard Siddaway Richard Siddaway Profile: Richard Siddaway

This is a good time to review what happened in the PowerShell community in 2017. It’s my perspective so is obviously biased based on my experiences.

The 2017 PowerShell Summit was an early highlight of the year. We sold out in early February and all registrations were for the whole f0ur days. This was fantastic and also prompted us to make the Summit a true 4 day event for 2018 and beyond. The Summit itself went very well. A few scares on the Sunday due to the flight problems caused by Delta airlines – at one point on the Sunday morning it looked like most of the speakers wouldn’t get to the event! Luckily, all but one made it so we didn’t have any major problems. The feedback we got during and after the Summit suggests that the event was very well received and enjoyed by all who attended.

Planning for the 2018 Summit started during the 2017 event – yes we do work that far in advance! We have to to get everything done. We’re expanding the Summit a little bit so we’ll have four full days with 4 rooms in use for break out sessions. We’ll have the team day where the PowerShell team come in and show us what they’re working on now and we’ll have the Community Lightning Demos that were so successful in 2017. We’ve also got some other exciting things happening at the 2018 Summit that we’ll start talking about in early January. Registrations have been going faster than last year so if you want a place I’d recommend making your purchase in early January.

The second major highlight was the publication of PowerShell in Action, third edition. The second edition was written when PowerShell v2 appeared so there is a lot of new material in the third edition. We edited down the older material as it was important it was covered but we needed to make space for the new stuff. At one point we thought we may have to do the book as two volumes.

The major change in PowerShell has been the rate of change and the diversification of PowerShell environments. By that I mean that PowerShell v5.1 has been modified with the feature updates for Windows 10 in March and September. There have also been changes with the introduction of Windows Server 1709. Its difficult to determine if the version of PowerShell you’re using is EXACTLY the same between these platforms. i haven’t heard of any major problems but its something to be aware of.

2017 also saw clarity emerging around PowerShell v6 and its positioning with regard to v5.1 (Windows 10, Server 206 & 1709 and WMF 5.1). The differences in functionality narrowed but there are still PowerShell v5.1 modules that won’t run under v6. Some of that will be addressed with the .NET core Windows compatibility pack – the thought of which has to be one of ITs biggest ironies – – a Windows compatibility pack for something that originated on Windows!! In some cases it may be necessary to go back to scripting solutions rather than supplied cmdlets – Active Directory seems a likely candidate.

I’d sum 2017 up from a PowerShell perspective as a year of change – change that we haven’t seen the end of.

December 21, 2017  12:08 PM

Windows Updates CIM classes

Richard Siddaway Richard Siddaway Profile: Richard Siddaway
CIM, Powershell, WSUS

When Windows 10 and Server 2016 were released they contained a new CIM namespace – ROOT/Microsoft/Windows/WindowsUpdate

This contained a CIM class MSFT_WUOperationsSession that had 2 very useful methods – ScanForUpdates and ApplyApplicableUpdates.

These methods enabled you to find and install updates from the Windows Update site or a WSUS server if you’d configured the machine to use WSUS.

Best of all the CIM class could be accessed and used remotely which was a huge step forward over the old COM object that couldn’t be used remotely.

Things changed with Windows 10 Fall Creators Update (1709) and Windows Server 1709. MSFT_WUOperationsSession still exists but the methods you need to scan for updates and apply updates are now on the MSFT_WUOperations class. The great thing is that they’re static methods so using them is easier. The bad – no really, really bad – thing is that this class CAN’T BE ACCESSED REMOTELY through a Windows remoting session, a CIM session or a SSH remoting session.

This takes us back to the bad old days of using COM objects. There doesn’t seem to be any reason or explanation for this decision.

I have managed to use the class remotely through a PowerShell direct remoting session though which means that I can force updates in my lab. Its not really an answer for production though

December 19, 2017  12:19 PM

Test-Path -PathType

Richard Siddaway Richard Siddaway Profile: Richard Siddaway

Test-Path is a useful cmdlet for testing the validity of a path. You get a True/False return depending on if the path exists or not.

There’s also a way to add to the test by determining if the path points to a container (folder) or a leaf (file) using the –PathType parameter.

Here’s some examples that show how it works:

PS> Test-Path -Path C:\Scripts\
PS> Test-Path -Path C:\Scripts\ -PathType Any
PS> Test-Path -Path C:\Scripts\ -PathType Container
PS> Test-Path -Path C:\Scripts\ -PathType Leaf
PS> Test-Path -Path C:\Scripts\foo.txt -PathType Container
PS> Test-Path -Path C:\Scripts\foo.txt -PathType Leaf

C:\Scripts is a folder and foo.txt in a file in that folder.

Test-Path –PathType is a good way to focus your test to ensure you’re dealing with a file or a folder as appropriate.


December 16, 2017  9:20 AM

PowerShell v6: #9 Release candidate 2 features

Richard Siddaway Richard Siddaway Profile: Richard Siddaway

A couple of features of PowerShell v6 release candidate 2 need commenting on.

Firstly, I was surprised when installing RC 2 on a Windows 10 machine (Insider build) that RC1 was removed. In the past you’ve been able to run numerous versions of PowerShell v6 side-by-side. This has consequences if the behaviour continues into the GA version and the 6.1 alpha/beta releases as you’ll have to choose between the stable, production version and the changeable new version.

Secondly, and this one was publicised by the PowerShell team, Pester is no longer installed by default with PowerShell v6. You can download the latest version of Pester from the PowerShell gallery. Not sure on thinking behind this decision but the download is easy so it’s not a deal breaker –you just have to remember to do it. May be best to use Save-Module for the download so you don’t have to perform the download if a new version of PowerShell v6 becomes available and overwrites the current version.

Next job is to install the OpenSSH optional feature and see how that goes. Be very interested to see if and how its updated as new versions of the Windows Insider builds are released.


December 15, 2017  2:28 PM

PowerShell v6: #8 Release candidate 2

Richard Siddaway Richard Siddaway Profile: Richard Siddaway

Release candidate 2 for PowerShell v6 is available for download from – https://github.com/PowerShell/PowerShell/releases

One worrying point is the the OpenSSH implementation which is required for remoting to and from Linux systems doesn’t appear to be any where near a release candidate – https://github.com/PowerShell/Win32-OpenSSH/releases. The latest release as of this writing is The steps to install OpenSSH are still too complicated and time consuming. There is an installation script but it doesn’t complete all of the manual steps!

at the moment I’d really recommend that you only install OpenSSH where you need it and don’t consider it as a replacement for WinRM based remoting apart from a few narrow scenarios:

– Windows <-> Linux remoting

– Cross domain remoting

– Remoting to or from a non-domain system

Ducks need to be lined up if PowerShell v6 is going to GA in January 2018

December 13, 2017  9:51 AM

Using the Where method

Richard Siddaway Richard Siddaway Profile: Richard Siddaway

You don’t usually see people using the where method. A recent question on the forums highlighted using the where method.

PowerShell deals in collections and will automatically create a collection of objects if the are multiple objects returned for instance

$procs = Get-Process

Iterating over a process can take time. PowerShell introduced 2 methods on collection to make this easier and much  faster to execute – where and foreach.

As an example

$Paths = @(
@{NodeName = ‘VMNAme1’; Instance = ‘Internal’ ; Path = ‘C:\Temp\’},
@{NodeName = ‘AnotherName’ ; Instance = ‘External’ ; Path = ‘C:\Temp2’},
@{NodeName = ‘VMNAME2’; Instance = ‘Internal’ ; Path = ‘C:\Temp1\’}

Get-ChildItem -Path $paths.where({$_.Nodename -eq $env:COMPUTERNAME}).Path

Depending on the machine on which you’re running you’ll get the appropriate folder.

The important bit is the $_.Nodename . You need to use the old style Where syntax when using the where method.



December 10, 2017  7:30 AM

Avoid the truncation in the display

Richard Siddaway Richard Siddaway Profile: Richard Siddaway

A question came up regarding my recent post about using the file system COM object to get folder sizes. The question was about the folder path and how you could see the whole path. In other words how to avoid the truncation in the display and the three dots.

When PowerShell displays objects it will automatically use a table format if the object has four properties or less. It uses a list if there are more properties. This behaviour can be overridden by PowerShell’s formatting system. This behaviour can lead to truncation of one or more fields.

This is the function to get folder sizes

function Get-FolderSize {
param (
 [string]$path = 'C:\MyData'

if (-not (Test-Path -Path $path)){
 Throw "$path - Path not found"

$fso = New-Object -ComObject "Scripting.FileSystemObject"

Get-ChildItem -Path $path -Directory -Recurse |
foreach {
 $size = ($fso.GetFolder("$($PSItem.FullName)")).Size
 $props = [ordered]@{
 Name = $PSItem.Name
 Created = $PSItem.CreationTime
 FilePath = $PSItem.FullName
 SizeMB = [math]::Round( ($size / 1mb), 2)

New-Object -TypeName PSObject -Property $props


If you just use the function as is

PS> Get-FolderSize -path C:\MyData\OneDrive\Data\Scripts

You can get truncated output – and you don’t see the size!

Office-Excel      10/02/2017 19:16:29 C:\MyData\OneDrive\Data\Scripts\Office-...
Office-OneNote    10/02/2017 19:16:26 C:\MyData\OneDrive\Data\Scripts\Office-...
Office-Outlook    10/02/2017 19:16:29 C:\MyData\OneDrive\Data\Scripts\Office-...
Office-PowerPoint 10/02/2017 19:16:29 C:\MyData\OneDrive\Data\Scripts\Office-...
Office-Visio      10/02/2017 19:18:00 C:\MyData\OneDrive\Data\Scripts\Office-...
Office-Word       10/02/2017 19:16:23 C:\MyData\OneDrive\Data\Scripts\Office-...


You could use Format-List

PS> Get-FolderSize -path C:\MyData\OneDrive\Data\Scripts | Format-List

which means you get lots of displays like this:

Name : Event Filters
Created : 10/02/2017 19:16:31
FilePath : C:\MyData\OneDrive\Data\Scripts\WMICookBook\PowerEvents\PowerEvents\Samples\Event 
SizeMB : 0.02
Using Format-Table with the –wrap parameter will avoid the truncation

PS> Get-FolderSize -path C:\MyData\OneDrive\Data\Scripts | Format-Table –AutoSize –Wrap

Samples         10/02/2017 19:16:31 C:\MyData\OneDrive\Data\Scripts\WMICookBook\PowerEvent
Event Consumers 10/02/2017 19:16:31 C:\MyData\OneDrive\Data\Scripts\WMICookBook\PowerEvent
 s\PowerEvents\Samples\Event Consumers 
Event Filters   10/02/2017 19:16:31 C:\MyData\OneDrive\Data\Scripts\WMICookBook\PowerEvent
 s\PowerEvents\Samples\Event Filters 
ConfigMgr       10/02/2017 19:16:31 C:\MyData\OneDrive\Data\Scripts\WMICookBook\PowerEvent
 s\PowerEvents\Samples\Event Consumers\ConfigMgr

Notice that the Size is again cut off. You need to ensure that your output pane in ISE or the PowerShell console is wide enough to display all the fields or PowerShell will truncate the display – without telling you


December 6, 2017  9:19 AM

PowerShell v6: #7 Module paths

Richard Siddaway Richard Siddaway Profile: Richard Siddaway

There is a very significant gap between the functionality available in PowerShell v6 as opposed to PowerShell v5.1. In part this is due to the underlying version of .NET but mainly to the defined module paths in the two versions.

In PowerShell v5.1 I have:

PS> $env:PSModulePath -split ‘;’
C:\Program Files\WindowsPowerShell\Modules

In PowerShell v6 I have

PS C:\scripts> $env:PSModulePath -split ‘;’
C:\Program Files\PowerShell\Modules
c:\program files\powershell\6.0.0-rc\Modules

The vast majority of the module supplied with PowerShell v5.1 reside in C:\WINDOWS\system32\WindowsPowerShell\v1.0\Modules which PowerShell v6 can’t see.

Unless you add it in yourself

$env:PSModulePath = $env:PSModulePath + ‘;C:\WINDOWS\system32\WindowsPowerShell\v1.0\Modules’

I’ve appended the PowerShell v5.1 modules to the PowerShell v6 module path.

There’s still no guarantee that the modules will work – it depends on the module code and if it accesses .NET classes that aren’t available in .NET core.

You’ll have to use trial and error to determine what works. For instance:


all work. BUT they’re from CDXML modules based on CIM classes not binary modules. As a rule thumb I’d expect the CIM based modules to just work. Binary module will definitely be trial and error.


December 5, 2017  3:23 PM

PowerShell v6: #6 Windows compatibility

Richard Siddaway Richard Siddaway Profile: Richard Siddaway

PowerShell v1 through v5.1 have been based on the full .NET framework. PowerShell v6 is based on .NET core which is a cross platform subset of .NET that’s available for Windows, Linux and mac. This has meant that Powershell v6 on Windows is a poor relation of PowerShell v5.1 in terms of the functionality available – for instance the Active Directory module won’t run on PowerShell v6. This makes v6 a backward step for administering Windows. Steps are being taken that will improve Windows compatibility of PowerShell v6.

The .NET core team are releasing a Windows compatibility pack – see https://blogs.msdn.microsoft.com/dotnet/2017/11/16/announcing-the-windows-compatibility-pack-for-net-core/ for what’s likely to be in it.

A number of cmdlets including:

WMI cmdlets

Eventlog cmdlets

PerCounter cmdlets

are ear marked for being ported to PowerShell v6 using the compatibility pack. When this happens and what else is will be included is unsure. You can follow the issue at https://github.com/PowerShell/PowerShell/issues/5603

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: