PowerShell How-To

How To Deploy PowerShell in an Enterprise Environment

Here's how to streamline the process, even when multiple machines are running multiple OSes.

PowerShell has all kinds of environments where it can help solve problems. I've written PowerShell scripts to manage my personal music files, to burn hundreds of CDs for a photography business and even automate testing of my ISP's promised speed. These are all personal uses but we all know there's no better place that PowerShell shines than in a business environment.

In a business environment, PowerShell can be leveraged to automate countless tasks at the server level and also at the client level. If you'd like to utilize PowerShell's capabilities, there's one small task that you must do before that can happen: get it installed. Lucky for us, starting with Windows 7 and Server 2003, PowerShell had become installed by default. Now we have Windows 8.1 and Windows Server 2012 R2 with v4 installed by default.

This is all well and good if you've got a dozen Windows 8.1 clients all connecting to a couple Windows Server 2012 R2 servers. If you do, I envy you! Most of us, whether in a SMB or enterprise, have to deal with a much more heterogeneous environment with a lot more systems. Currently, the client I'm working with has 5,000 or so systems with operating systems ranging from client operating systems from Windows XP to Windows 8.1, and from server operating systems like Windows Server 2003 all the way up to Windows Server 2012 R2. To ensure a consistent PowerShell experience across all of these systems and depending on the default PowerShell version would not be a wise idea.

Coming from experience, when you write and test a PowerShell script on a computer with PowerShell v4 installed and expect it to run on all systems with PowerShell v2 or even v3 installed, you may be sadly mistaken. Even though a lot of your code may work in both version never assume so.

In order to obtain a consistent experience across all of your systems it's important to standardize on a single version of PowerShell (if possible) or, at a maximum, two versions of PowerShell. This all depends on your OS landscape. If you're lucky enough to have only Windows 7/Windows Server 2008 systems or higher then, by all means, get everything up to v4 and write your scripts for v4. However, if you still have some XP or Windows Server 2003 clients in your environment you're forced with using two versions: v2 and v4 (since older clients cannot run v4).

Once you've got an idea on the OS landscape you can then turn your attention to getting a deployment strategy put together. This strategy all depends on the tools you have at your disposal. The tools don't necessarily matter. In the end, all that matters is if the appropriate installer is executed on the appropriate systems. You can use ConfigMgr, Zendesk, Altiris or good old fashioned psexec if you want. Whatever allows you to execute the installer with the appropriate switches on all your systems will work.

In order to apply to the widest audience I'm not going to focus on a particular tool. Rather I'll be using a simple folder copy and kick off the installer with a remote WMI process execution.

The first task you need to check off is to download the appropriate versions and architectures. Get a good inventory of what you've got in your environment. Do you have a mix of x86 and x64 Windows 7 systems out there? Download both versions of PowerShell v4. Do you have some XP still along with Windows Server 2008 R2? You'll need the v2 and v4 installers. You get the point.

Here's the links you'll need:

Again, be sure to download both architectures of each even if you're unsure if you need them or not. I'll be showing you a script I use that'll be run on each system and will choose which version to install on the fly.

Once you've got all the versions and architectures of each version in a folder, we're going to have to go a little old school and create a VBscript because PowerShell doesn't like upgrading itself. We have to use VBscript to kick off the upgrades. Go ahead and create a file called install.vbs in this folder and copy/paste this content into the VBS.

 

Set oShell = WScript.CreateObject("WScript.Shell")
Set oFso = CreateObject("Scripting.FileSystemObject")
strWorkingDir = oFso.GetParentFolderName(wscript.ScriptFullName)

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,"X86-based PC") > 0 Then
oShell.Run "wusa.exe " & strWorkingDir & "\Windows6.1-KB2819745-x86-MultiPkg.msu /quiet /norestart",0,True
ElseIf InStr(objArch.SystemType,"x64-based PC") > 0 Then
oShell.Run "wusa.exe " & strWorkingDir & "\Windows6.1-KB2819745-x64.msu /quiet /norestart",0,True
Else
Wscript.Quit(10)
End If
Next
end if

This script is for upgrading PowerShell v2 clients to v4. It first checks the system's architecture that it's executing on and then silently installs the correct version. This example would work great if you're all on Windows 7 and Windows Server 2008 or higher.

Once you've got your folder of installers and the install.vbs, it's just a matter of getting this onto remote systems. You can do this a number of ways, either by using a tool like ConfigMgr or even using PowerShell's Active Directory module and pulling computers from AD. The choice is yours. All that matters is that you are able to get a list of computers you'd like to upgrade PowerShell on.

For simplicity, I'll just use a simple text file. On my admin machine, I have a text file with system names, one per line. I want to read each of these systems and perform a task on them. To do this I'll use PowerShell's Get-Content cmdlet:

$Computers = Get-Content C:\computers.txt

I now have my computers in an array that I can loop over. The next task is copying our folder full of installers and the installer script to the remote machine. I'll just issue a file copy for this and only do this for machines that are online.

$Computers = Get-Content C:\computers.txt
foreach ($Computer in $Computers) {
if (Test-Connection -Computername $Computer -Quiet -Count 1) {
Copy-Item -Path C:\MyPowerShellInstalls\* -Destination "\\$Computer\c$"
}
}

Once I do this I then need to execute the install.vbs installer on each machine. I'll use psexec to do this.

$Computers = Get-Content C:\computers.txt
foreach ($Computer in $Computers) {
if (Test-Connection -Computername $Computer -Quiet -Count 1) {
Copy-Item -Path C:\MyPowerShellInstalls\* -Destination "\\$Computer\c$"
psexec \\$Computer cscript C:\MyPowerShellInstalls\install.vbs
}
}

After the install, let's clean up after ourselves:

$Computers = Get-Content C:\computers.txt
foreach ($Computer in $Computers) {
if (Test-Connection -Computername $Computer -Quiet -Count 1) {
Copy-Item -Path C:\MyPowerShellInstalls\* -Destination "\\$Computer\c$"
psexec \\$Computer cscript C:\MyPowerShellInstalls\install.vbs
Remove-Item "\\$Computer\c$\MyPowerShellInstalls" -Recurse -Force
}
}

PowerShell needs a reboot so our final step would be to force a reboot.

$Computers = Get-Content C:\computers.txt
foreach ($Computer in $Computers) {
if (Test-Connection -Computername $Computer -Quiet -Count 1) {
Copy-Item -Path C:\MyPowerShellInstalls\* -Destination "\\$Computer\c$"
psexec \\$Computer cscript C:\MyPowerShellInstalls\install.vbs
Remove-Item "\\$Computer\c$\MyPowerShellInstalls" -Recurse -Force
Restart-Computer -Computername $Computer -Force
}
}

That's it! This tutorial wasn't meant to be an end-all solution to deploying PowerShell. I know that there are as many different ways to do this as there are hairs on my head. I hope you're able to take my examples and just run with them. If not, at least make a copy and modify to your heart's content. I should have at least saved you a couple hours of Googling around, right?

About the Author

Adam Bertram is a 20-year veteran of IT. He's an automation engineer, blogger, consultant, freelance writer, Pluralsight course author and content marketing advisor to multiple technology companies. Adam also founded the popular TechSnips e-learning platform. He mainly focuses on DevOps, system management and automation technologies, as well as various cloud platforms mostly in the Microsoft space. He is a Microsoft Cloud and Datacenter Management MVP who absorbs knowledge from the IT field and explains it in an easy-to-understand fashion. Catch up on Adam's articles at adamtheautomator.com, connect on LinkedIn or follow him on Twitter at @adbertram or the TechSnips Twitter account @techsnips_io.


comments powered by Disqus
Most   Popular

Upcoming Training Events