When you think about it, software deployment is just the act of copying some files to a remote computer, executing an installer, and maybe reporting success or failure. That's it! PowerShell does all this easily.

Adam Bertram

Adam is a Microsoft Cloud and Datacenter Management Most Valuable Profressional (MVP) who specializes in Windows PowerShell. You can reach Adam at adamtheautomator.com or on Twitter at @adbertram.

PowerShell never ceases to amaze me with its flexibility. One reason I love it so much is that it can do just about anything you'd like. If you're good enough, PowerShell code can replace just about any piece of software you have. I might argue, though, that just because you can doesn't mean you should. However, there are times when you need a simple solution to get a job done. One of those jobs is software deployment.

I come from a Microsoft System Center Configuration Manager (SCCM) background. SCCM is expensive; it’s a huge product that does a lot of stuff. Software deployment is one of its features. SCCM is for large software deployments, and I always thought it was overkill for small deployments of fewer than a dozen computers. That's why I sometimes used good ol' PowerShell to do the job. Let's go into how to do that.

I'm going to assume you've already figured out how to install the software silently. Depending on the installer type, you're probably using Windows Installer, InstallShield, or perhaps some other homegrown installer. Regardless, test the install, get it working locally, and then you can look into deploying it remotely.

The next step will require PowerShell remoting. You'll need to ensure the appropriate firewall ports are open and that you have a WinRM listener configured on each computer. For the super-quick way, just run 'winrm quickconfig' on each computer and it will do the rest. I'm also going to assume that your computers are in a domain. This technique is still usable for computers in a workgroup but requires further tweaking to make WinRM work.

Next, you should have a shared folder on your network that contains one folder for each piece of software you'd like to deploy. Here I have folders called SomeClient and vnc representing all the files necessary to install each piece of software.

Directory of all the files necessary

Directory of all the files necessary

Now that we have a source repository set up, we need a list of computers to target. For simplicity, I'll use a text file, but as long as you're able to pull a list of computer names from somewhere like Active Directory or some other database, that works too.

Generate list of computers to target using Get-Content

Generate list of computers to target using Get-Content

I have three PCs I'd like to deploy software to, as you can see.

Next, we'll copy each of the software folders to each of the clients. I prefer copying the entire folder (temporarily) to the client to remove any network hiccups that might occur during install. To do this, I'll use Copy-Item to copy each folder to a temporary location on each client.

This will create a C:\Windows\Temp\vnc and a C:\Windows\Temp\SomeClient folder on each computer.

We now need to execute the installer on each computer and pass it the correct arguments. I'm going to assume each piece of software is an MSI file, the MSI is called install.msi, and each installs silently with the following syntax locally.

With this, I can execute the command on each computer by using PowerShell to issue the remote command with the Invoke-Command cmdlet inside the loop.

Notice that I had to add some code to account for the software folder names. This was because I needed a way to reference the folder name inside of the scriptblock that Invoke-Command uses. This will ensure install.msi executes on each computer for each piece of software.

Finally, the only thing left to do is to clean up our temporary mess.

Win the monthly 4sysops member prize for IT pros


Related Posts

  1. Phonce 2 years ago

    Nice job.  But is there a way to retrieve status codes for the installation?  Just to know if the installation went fine,  wrong or have a reboot pending?



  2. Author
    Adam Bertram 2 years ago

    Yes. You can use $LastExitCode or you could use the ResultCode property from Start-Process.


  3. Dan Bone 2 months ago

    "Adam the Automator". Deltron 3030 fan?


Leave a reply

Your email address will not be published. Required fields are marked *



Please ask IT administration questions in the forum. Any other messages are welcome.

© 4sysops 2006 - 2017

Log in with your credentials


Forgot your details?

Create Account