Javascript required
Skip to content Skip to sidebar Skip to footer

How to Install Software on Remote Computer Using Powershell

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.

  • Author
  • Recent Posts

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.

$computers = Get-Content –Path C:\Computers.txt foreach ($pc in $computers) {     Get-ChildItem \\MEMBERSRV1\Software -Recurse | Copy-Item \\$pc\c$\Windows\Temp -Force     }

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.

Msiexec /I install.msi /qn

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.

$softwareFolders = Get-ChildItem \\MEMBERSRV1\Software -Directory foreach ($pc in $computers) {     foreach ($sw in $softwareFolders) {         Copy-Item –Path $sw.FullName  -Destination  \\$pc\c$\Windows\Temp -Force -Recurse         Invoke-Command –ComputerName $pc –ScriptBlock {msiexec /I "C:\Windows\Temp\$($using:sw.Name)\install.msi" /qn}     } }

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.

Subscribe to 4sysops newsletter!

$softwareFolders = Get-ChildItem \\MEMBERSRV1\Software -Directory foreach ($pc in $computers) {     foreach ($sw in $softwareFolders) {         Copy-Item -Path $sw.FullName  -Destination "\\$pc\c$\Windows\Temp" -Force -Recurse         Invoke-Command –ComputerName $pc –ScriptBlock {msiexec /I "C:\Windows\Temp\$($using:sw.Name)\install.msi" /qn}     }     Remove-Item -Path "\\$pc\c$\Windows\Temp" -Recurse -Force }

avatar

How to Install Software on Remote Computer Using Powershell

Source: https://4sysops.com/archives/using-powershell-to-deploy-software/