PowerShell for Windows Admins

January 4, 2018  2:44 PM

Relevance of Scripts

Richard Siddaway Richard Siddaway Profile: Richard Siddaway
Books, Powershell

I had a sudden thought today about the relevance of scripts – PowerShell Scripts –  today.

PowerShell v6 can’t run some of the modules that we’ve come to rely on – for instance the AD cmdlets. The Windows Compatibility Pack (see previous post) enables access to some of the underlying .NET classes that enable AD administration through PowerShell.

This means going back to the v1/v2 days and writing scripts – we may wrap them as advanced functions and modules these days but the basic code is the same – instead of using canned cmdlets.

My first two books

PowerShell in Practice – https://www.manning.com/books/powershell-in-practice


PowerShell and WMI – https://www.manning.com/books/powershell-and-wmi

supply lots of code examples for working with PowerShell Scripts including AD and WMI. If you haven’t got a copy they’ll help you get back to basics.

January 4, 2018  8:45 AM

Windows Compatibility Pack

Richard Siddaway Richard Siddaway Profile: Richard Siddaway
Active Directory, Powershell

As reported last month the Windows Compatibility Pack for .NET core is available. This adds back some of the functionality missing from .NET core. This functionality is ONLY of relevance on Windows machines.

A PowerShell module based on the Compatibility Pack is in the works – this will add a number of cmdlets including the WMI cmdlets back into PowerShell v6 on Windows. There’s no ETA on the module at this time.

There is a module on the PowerShell gallery that will add the .NET components of the Compatibility Pack into your PowerShell v6 session.

PS>  Find-Module -Name PSCoreWindowsCompat | ft -a

Version Name                Repository Description
------- ----                ---------- ----------- PSCoreWindowsCompat PSGallery  Provides the Microsoft.Windows.Compatibility Pack to PowerShell Core.

If you want to inspect the module

PS>  Save-Module -Name PSCoreWindowsCompat -Repository PSGallery -Path C:\Source\ -Force

To install the module:

PS>  Install-Module -Name PSCoreWindowsCompat -Repository PSGallery -Verbose -Force
 VERBOSE: Repository details, Name = 'PSGallery', Location = 'https://www.powershellgallery.com/api/v2/'; IsTrusted = 'False'; IsRegistered = 'True'.
 VERBOSE: Using the provider 'PowerShellGet' for searching packages.
 VERBOSE: Using the specified source names : 'PSGallery'.
 VERBOSE: Getting the provider object for the PackageManagement Provider 'NuGet'.
 VERBOSE: The specified Location is 'https://www.powershellgallery.com/api/v2/' and PackageManagementProvider is 'NuGet'.
 VERBOSE: Searching repository 'https://www.powershellgallery.com/api/v2/FindPackagesById()?id='PSCoreWindowsCompat'' for ''.
 VERBOSE: Total package yield:'1' for the specified package 'PSCoreWindowsCompat'.
 VERBOSE: Performing the operation "Install-Module" on target "Version '' of module 'PSCoreWindowsCompat'".
 VERBOSE: The installation scope is specified to be 'AllUsers'.
 VERBOSE: The specified module will be installed in 'C:\Program Files\PowerShell\Modules'.
 VERBOSE: The specified Location is 'NuGet' and PackageManagementProvider is 'NuGet'.
 VERBOSE: Downloading module 'PSCoreWindowsCompat' with version '' from the repository 'https://www.powershellgallery.com/api/v2/'.
 VERBOSE: Searching repository 'https://www.powershellgallery.com/api/v2/FindPackagesById()?id='PSCoreWindowsCompat'' for ''.
 VERBOSE: InstallPackage' - name='PSCoreWindowsCompat', version='',destination='C:\Users\Richard.MANTICORE\AppData\Local\Temp\51711061'
 VERBOSE: DownloadPackage' - name='PSCoreWindowsCompat', version='',destination='C:\Users\Richard.MANTICORE\AppData\Local\Temp\51711061\PSCoreWindowsCompat\PSCoreWindowsCompat.nupkg', uri='https://www.powershellgallery.com/api/v2/package/PSCoreWindowsCompat/'
 VERBOSE: Downloading 'https://www.powershellgallery.com/api/v2/package/PSCoreWindowsCompat/'.
 VERBOSE: Completed downloading 'https://www.powershellgallery.com/api/v2/package/PSCoreWindowsCompat/'.
 VERBOSE: Completed downloading 'PSCoreWindowsCompat'.
 VERBOSE: InstallPackageLocal' - name='PSCoreWindowsCompat', version='',destination='C:\Users\Richard.MANTICORE\AppData\Local\Temp\51711061'
 VERBOSE: Catalog file 'PSCoreWindowsCompat.cat' is not found in the contents of the module 'PSCoreWindowsCompat' being installed.
 VERBOSE: Module 'PSCoreWindowsCompat' was installed successfully to path 'C:\Program Files\PowerShell\Modules\PSCoreWindowsCompat\'.

Notice the installation path is OUTSIDE of the current version of PowerShell v6 so should remain available through any upgrades.

PS>  Import-Module -Name PSCoreWindowsCompat

Now you’ve got it how do you use it? The module DOESN’T have any functions – it just loads the .NET namespaces.

Its back to PowerShell v1 days – everything is a script instead of a cmdlet. For instance the Compatibility pack contains the System.DirectoryServices so you can script against AD.

Let’s say you want to see all the users in the domain:

$dom = [System.DirectoryServices.ActiveDirectory.Domain]::GetCurrentDomain()
 $root = $dom.GetDirectoryEntry()

$search = [System.DirectoryServices.DirectorySearcher]$root
 $search.Filter = "(&(objectclass=user)(objectcategory=user))"
 $search.SizeLimit = 3000
 $result = $search.FindAll()

foreach ($user in $result){

Use System.DirectoryServices.ActiveDirectory.Domain to get the current domain. Create a System.DirectoryServices.DirectorySearcher object and set the filter to users. Find all of the users and display their distinguishedname

Its a lot more complicated than using the cmdlet:

PS>  Get-ADUser -Filter * | select DistinguishedName

but it gets the job done.

If you need to administer AD and you need the cross platform capabilities of PowerShell maybe you should use the  PSCoreWindowsCompat module (with aplogies to A-Team fans everywhere)

January 3, 2018  12:37 PM

PowerShell arrays

Richard Siddaway Richard Siddaway Profile: Richard Siddaway

An array is a collection of objects. PowerShell arrays can be created manually

PS> $a = 1,2,3,4


$b = @(1,2,3,4)

PowerShell will also create arrays automatically when needed:

PS> $ps = Get-Process

All three options are arrays:

PS> $a.GetType()

IsPublic  IsSerial  Name     BaseType
 -------- --------  ----     --------
 True     True      Object[] System.Array

PS> $b.GetType()

IsPublic  IsSerial Name     BaseType
 -------- -------- ----     --------
 True     True     Object[] System.Array

PS> $ps.GetType()

IsPublic  IsSerial Name     BaseType
 -------- -------- ----     --------
 True     True     Object[] System.Array

The individual elements in an array are accessed using an index that starts at 0

PS> $a[0]

You can use a range of indices

PS> $a[1..2]

You can use negative indices to count from the end of the array

PS> $a[-1]

PS> $a[-1..-2]

PowerShell arrays are polymorphic by default meaning you can store any type of object in an array – and can store multiple types of objects in a single array

PS> $a += ‘Hello World’

PS> $a
Hello World

We haven’t actually extended the array – a new array is created that contains the old array and the new element. Any time you find yourself adding elements to an array in a loop – STOP and think about how you could do this as a pipeline.

PS> $x = @()
PS> 1..5 | foreach {$x += $_}
PS> $x -join ‘ ‘
1 2 3 4 5

is very inefficient compared to

PS> $y = 1..5 | foreach {$_}
PS> $y -join ‘ ‘
1 2 3 4 5

As you saw earlier you can add elements to an existing array. You can also remove elements from an array:

PS> $a = $a -ne 3
PS> $a
Hello World

Iterating over the contents of an array is as simple as

PS> $a | foreach {$_}


PS> foreach ($i in $a){$i}

PowerShell arrays are powerful tools that can make your coding much easier. This post has covered the most likely tasks you’ll face using arrays in PowerShell

December 31, 2017  2:30 PM

PowerShell in 2018

Richard Siddaway Richard Siddaway Profile: Richard Siddaway

So what is going to happen for PowerShell in 2018?

In April we have the Summit. Our biggest ever Summit with many more speakers, more sessions and new things including Iron Scripter. We’ll be starting the build up in early January so keep an eye on powershell.org.

PowerShell v6 will be GA in January. This is the point where you have decisions to make. Do you ignore v6; try and use v6 only or attempt some kind of dual use. Only your needs can answer what is the right solution for you but multiple PowerShell versions combined with multiple versions of Windows server – there’ll be feature updates in Match and September if plans remain the same – will definitely raise complications.

What should you be doing in 2018?

If you haven’t booked a Summit place and want to go then don’t be too late in registering. Sales have been much faster than last year and I suspect we’ll sell out early in 2018. We will have another batch of places available on alumni discount in January.

The Windows compatibility pack for .NET core (still seems ironic that’s its needed) will become available. That will plug some, but not all, of the gaps in functionality between v6 and v5.1. I’d recommend learning, or possibly re-learning, how to write scripts using System.DirectoryServices as it seems likely to be the only way to administer AD from v6 in the near future.

If you haven’t evaluated v6 then do so – side by side install with v5.1 makes that easier.

If you follow the PowerShell project on github you’ll see that v6.1 is already under discussion. I’d recommend that you join the discussion and help shape the future of PowerShell.

What would I like to see in 2018?

All the Windows inbuilt and RSAT modules modified to work with v6.

A simple and effective way to install and configure OpenSSH for PowerShell remoting on Windows – without having to install chocolaty or other third party features

A good set of cmdlets for managing containers

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

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: