If you do decide to install PowerShell 5.1, I’ve created a technical how-to with some scripts to automate this process for you. Disclaimer: All code mentioned in this post is as-is. Some may work, some may not work in your environment but, if you have nothing, to begin with, it will act as a template for you to start with.
If you need help finding what version of PowerShell you’re running, I recommend checking out How to Check your PowerShell Version (All the Ways!).
Step #1: Discovery
Step #1 in performing an enterprise-wide PowerShell upgrade is discovery. What’s the landscape currently look like? You can’t change something without first understanding it, and surprisingly, lots of organization don’t have any idea what they have!
Existing Operating Systems
The first task is understanding what operating systems you currently have where you’d like to get up to PowerShell 5.1. Although, on some systems, you may already have decided to install PowerShell 5.1 and not know it. PowerShell 5.1 was released as a bundled tool in Windows 10 Anniversary Update and in the RTM version of Windows Server 2016 so if you’ve got either of those operating systems or newer you’re already good to go.
For the others, be sure to gather up a list. Don’t have a system management tool like SCCM? No problem! Use PowerShell to help PowerShell! If you have Active Directory, here’s a quick one-liner to get a bird’s eye view of what’s out there.
PS> Get-ADComputer -Filter "OperatingSystem -like 'Windows*'" -Properties OperatingSystem | group operatingsystem | sort name
Count Name Group
----- ---- -----
922 Windows 10 Enterprise XXXXXXXXXXXXXXXXXX
714 Windows 7 Enterprise XXXXXXXXXXXXXXXXXX
23 Windows 7 Professional XXXXXXXXXXXXXXXXXX
4 Windows 7 Ultimate XXXXXXXXXXXXXXXXXX
2 Windows 8 Consumer Pre... XXXXXXXXXXXXXXXXXX
1 Windows 8 Enterprise XXXXXXXXXXXXXXXXXX
What does your environment look like? Do you have any old Windows XP or Server 2003 machines? If so, you’re out of luck. The best you’re going to do there is PowerShell v2, but if you’ve still got some of those in your environment, PowerShell is the least of your concerns! For any operating system that has Windows 7 SP1/Windows Server 2008R2 SP1 or higher, PowerShell 5.1 can be installed.
Building a Prerequisite Target List
On applicable operating systems, PowerShell 5.1 has a few prerequisites and requirements to meet before it works.
- At least .NET Framework 4.5.2 installed. This isn’t an installation requirement, and the install will still proceed, but some features will not work so just do it already!
- PowerShell 5.1 Preview must not be installed
- On Windows 7 or Server 2008R2 machines with PowerShell v3 installed, you must either save the value of
PSModulePath
or first upgrade to v4 first. - On Windows 7 or Server 2008R2 machines if using DSC, be sure to enable WinRM.
- The installation will need a reboot so be sure you schedule this
Because I’m lazy and I intend for you to be the same, here’s a small script I whipped up to get you started figuring out what kind of prereq work is ahead of you. For the WinRM requirement, you could include code from this script of mine in there as well as you’re touching each machine. Although, know that this approach requires that each computer have PowerShell Remoting enabled.
## This could be Active Directory, a text file, a SQL database, whatever$computers = Get-AdComputer -Filter *foreach ($c in $computers.Name) { try { $session = New-PSSession -ComputerName $c $icmParams = @{ Session = $session } $output = @{ ComputerName = $c } ## In case they're running Powerhell v3 $icmParams.ScriptBlock = { $env:PSModulePath; [Environment]::GetEnvironmentVariable("PSModulePath", "Machine") } $output.PSModulePath = (Invoke-Command @icmParams) -split ';' | Select-Object -Unique | Sort-Object ## Grab the existing version $icmParams.ScriptBlock = { $PSVersionTable.BuildVersion.ToString() } $output.PSModulePath = Invoke-Command @icmParams ## Check .NET Framework 4.5.2 if (Get-ChildItem -Path "\$c\c$\windows\Microsoft.NET\Framework" -Directory | Where-Object {$_.Name -match '^v4.5.2.*' }) { $output.DotNetGood = $true } else { $output.DotNetGood = $false } [pscustomobject]$output } catch { } finally { Remove-PSSession -Session $session -ErrorAction Ignore }
Ensure existing scripts will run with PowerShell 5.1
Even though members of the PowerShell team themselves have told me that all scripts should work with PowerShell 5.1, that’s not necessarily the case all the time. For any code that’s running critical business processes, I always recommend installing 5.1 on the same operating system of another machine and running through all testing that way just to be sure.
Step #2: Deployment
Once you’ve got all of the prereqs out of the way and you’re ready to begin rolling out PowerShell 5.1, the next step is doing it! Rolling out 5.1 is similar to other software deployments. How you go about this is dependent on the tools you already have. For example, if you have Active Directory and would like to use GPOs, you could go that route, SCCM would work likewise. I try to be product agnostic here so here’s how I would do it with PowerShell of course!
First, I’ll create a folder on my local machine called C:\PowerShellDeployment
. Next, I’ll download the appropriate version(s) that I need into that folder and grab a copy of psexec while I’m at it. Next, since PowerShell cannot upgrade itself, we need to fall back on good ol’ VBScript. Here’s a little script I created long ago that will get you started. I’ll save it to C:\PowerShellDeployment\installPs.vbs
.
Set oShell = WScript.CreateObject("WScript.Shell")
Set oFso = CreateObject("Scripting.FileSystemObject")
strWorkingDir = oFso.GetParentFolderName(wscript.ScriptFullName)
'Change this to whatever file name it is
psInstallerPath = strWorkingDir & "\Windows6.1-KB2819745-x86-MultiPkg.msu"
Set swbemLocator = CreateObject("WbemScripting.SWbemLocator")
Set swbemServices = swbemLocator.ConnectServer(".", "Root\CIMV2")
if oFSO.GetFileVersion("c:\windows\system32\windowsPowerShell\v1.0\PowerShell.exe") = "6.0.6002.18111"
then
Set colArchs = swbemServices.ExecQuery("SELECT SystemType FROM Win32_ComputerSystem",,48)
For Each objArch in colArchs
if
InStr(objArch.SystemType,"x64-based PC") > 0
Then
oShell.Run "wusa.exe " & psInstallerPath & " /quiet /norestart",0,True
Else
Wscript.Quit(10)
End If
Next
End if
Once you’ve got the VBS saved on your local machine, create a PowerShell script like this and keep it somewhere.
## Again, doesn't have to be AD$computers = Get-AdComputer -Filter *foreach ($Computer in $Computers) { if (Test-Connection -Computername $Computer -Quiet -Count 1) { $folderPath = 'C:\PowerShellDeployment' Copy-Item -Path $folderPath -Destination "\$Computer\c$" psexec \$Computer cscript "$folderPath\installPs.vbs" Remove-Item "\$Computer\c$\PowerShellDeployment" -Recurse -Force Restart-Computer -Computername $Computer -Force}
Execute the above script, and it should check to see if the computer is online, copy the PowerShell installer and the VBS to the remote computer, execute it, clean up after itself and restart the computer. As always, schedule this in a maintenance window! Installing PowerShell requires a reboot, and this will just do it without remorse.