- SolarWinds Server Performance and Configuration Bundle - Tue, Jun 18 2019
- SolarWinds Patch Manager: Updating Windows and third-party software - Tue, Apr 30 2019
- Monitor file changes in Windows with PowerShell and pswatch - Fri, Feb 1 2019
Installing PSWindowsUpdate
Since PSWindowsUpdate is not installed on Windows by default, we have to first install the module. Luckily, we can do this easily from the PowerShell Gallery. Note I am using an older version from July 2017 (1.5.2.6).
PS C:\WINDOWS\system32> Install-Module PSWindowsUpdate -MaximumVersion 1.5.2.6
If we run Get-Command we can see all of the commands in the PSWindowsUpdate module:
PS C:\WINDOWS\system32> Get-Command -Module PSWindowsUpdate CommandType Name Version Source ----------- ---- ------- ------ Alias Get-WindowsUpdate 1.5.2.6 pswindowsupdate Alias Hide-WindowsUpdate 1.5.2.6 pswindowsupdate Alias Install-WindowsUpdate 1.5.2.6 pswindowsupdate Alias Uninstall-WindowsUpdate 1.5.2.6 pswindowsupdate Function Add-WUOfflineSync 1.5.2.6 pswindowsupdate Function Add-WUServiceManager 1.5.2.6 pswindowsupdate Function Get-WUHistory 1.5.2.6 pswindowsupdate Function Get-WUInstall 1.5.2.6 pswindowsupdate Function Get-WUInstallerStatus 1.5.2.6 pswindowsupdate Function Get-WUList 1.5.2.6 pswindowsupdate Function Get-WURebootStatus 1.5.2.6 pswindowsupdate Function Get-WUServiceManager 1.5.2.6 pswindowsupdate Function Get-WUUninstall 1.5.2.6 pswindowsupdate Function Hide-WUUpdate 1.5.2.6 pswindowsupdate Function Invoke-WUInstall 1.5.2.6 pswindowsupdate Function Remove-WUOfflineSync 1.5.2.6 pswindowsupdate Function Remove-WUServiceManager 1.5.2.6 pswindowsupdate
How Invoke-WUInstall works
One different aspect of using Invoke-WUInstall is that it does not use traditional PowerShell remoting methods to perform Windows update installs. When you look at the source code, it actually creates and immediately runs a scheduled task on the remote machine under the SYSTEM account.
Write-Verbose "Create schedule service object" $Scheduler = New-Object -ComObject Schedule.Service $Task = $Scheduler.NewTask(0) $RegistrationInfo = $Task.RegistrationInfo $RegistrationInfo.Description = $TaskName $RegistrationInfo.Author = $User.Name $Settings = $Task.Settings $Settings.Enabled = $True $Settings.StartWhenAvailable = $True $Settings.Hidden = $False $Action = $Task.Actions.Create(0) $Action.Path = "powershell" $Action.Arguments = "-Command $Script" $Task.Principal.RunLevel = 1
A typical use of Invoke-WUInstall would be:
Invoke-WUInstall -ComputerName Test-1 -Script {ipmo PSWindowsUpdate; Get-WUInstall -AcceptAll | Out-File C:\PSWindowsUpdate.log } -Confirm:$false –Verbose
In this command we see Get-WUInstall, which is the command PSWindowsUpdate uses to install updates, usually from your Windows Server Update Services (WSUS) server. Get-WUInstall simply uses a COM object for Windows updates to perform the tasks needed. Notice also the use of the -AcceptAll parameter, which means it will automatically accept any updates to install.
One nice feature of Invoke-WUInstall is that it actually installs the PSWindowsUpdate module on the remote machine (if it isn't there already). This is great when you are using the module on a new machine, or when you decide to use it for the first time.
C:\ > $cim = New-CimSession -ComputerName Test-1 C:\ > $cim Id : 2 Name : CimSession2 InstanceId : afa8c63d-fb1f-46f9-8082-c66238750a92 ComputerName : Test-1 Protocol : WSMAN C:\Scripts\PowerShell> (Get-ScheduledTask -TaskPath "\" -CimSession $cim -TaskName PSWindowsUpdate).actions Id : Arguments : -Command ipmo PSWindowsUpdate; Get-WUInstall -AcceptAll -AutoReboot | Out-File C:\PSWindowsUpdate.log Execute : powershell WorkingDirectory : PSComputerName : Test-1
As you can see, the scheduled task is going to run ipmo PSWindowsUpdate; Get-WUInstall -AcceptAll -AutoReboot | Out-File C:\PSWindowsUpdate.log. Using Out-File will ensure the logs of downloading and installing updates are visible so we can check against them later.
Install updates on multiple machines
The true power of Invoke-WUInstall is when you have to install updates on many machines at once. This is very easy to do, all you need is to add machines to the ‑ComputerName parameter, which then processes them in a loop (not in parallel unfortunately).
C:\ > Invoke-WUInstall -ComputerName Test-1,Test-2,Test-3,Test-4 -Script {ipmo PSWindowsUpdate; Get-WUInstall -AcceptAll | Out-File C:\ PSWindowsUpdate.log } -Confirm:$false -Verbose VERBOSE: Populating RepositorySourceLocation property for module PSWindowsUpdate. VERBOSE: Loading module from path 'C:\Program Files\WindowsPowerShell\Modules\PSWindowsUpdate\1.5.2.6\PSWindowsUpdate.psm1'. VERBOSE: Create schedule service object VERBOSE: Performing the operation "Invoke WUInstall" on target "Test-1".
Finding errors
One great reason to output to a log on the remote machine is to confirm that no errors installing updates on these remote machines occurred. With some simple PowerShell, we can query these log files and search for failures.
Here is what a typical log looks like after using Get-WUInstall -AcceptAll | Out-File C:\ PSWindowsUpdate.log:
It includes the status of the update, its KB number, size, and title—all great information to have handy when installing updates.
Using Invoke-Command, Get-Item, and Select-String, we can use a quick technique to easily work through any computers used with Invoke-WUInstall and find Windows updates that failed to install:
Subscribe to 4sysops newsletter!
C:\> Invoke-Command -ComputerName Test-1,Test-2,Test-3 -ScriptBlock { >> Get-Item C:\PSWindowsUpdate.log | Select-String -Pattern "failed" -SimpleMatch | >> Select-Object -Property line } | Select-Object -Property Line,PSComputerName Line PSComputerName ---- -------------- 4 Failed KB4103712 30 MB 2018-05 Security Only Quality Update for Windo... Test-1
Conclusion
While there are other solutions for managing Windows update deployment, PSWindowsUpdate provides a Windows admin a free and very powerful tool to manage updates. With some simple PowerShell scripting, an admin can orchestrate updates across the enterprise in conjunction with WSUS as well.
I don’t have the Invoke-WUInstall cmd
Sorry should have specified this. Its not a builtin PowerShell module.
https://www.powershellgallery.com/packages/PSWindowsUpdate/2.0.0.4
Install by doing:
Install-Module PSWindowsUpdate
I just installed this module, and the “Invoke-WUInstall’ cmdlet is not available.
Sorry its in version 1 it seems. I never realized major changes were made to newer versions.
They changed the name of the command from Invoke-WUInstall => Invoke-WUJob
The newer version 2.1.1.2 doesn't utilize the Invoke-WUInstall.
I believe the cmdlet Get-WindowsUpdate is the switch to use I believe. I am looking into this to see about making it work for me as well.
I also don’t have this cmdlet on my PS. But i found this one: Install-WUUpdates, wight does the same thing?
Maybe I’m wrong but I think the cmd-let is included on Michael Gajda’s
Windows Update PowerShell Module
You can’t see the source code anymore since version 2.0. It also is significantly slower. Has anyone had any luck getting in contact with Michael Gadja the creator?
Darn thats a shame. I couldnt find it on Github. Maybe he is going to try and sell it lol.
The Invoke-WUInstall was removed from this module starting with version 2.0.0.0 last October.
Yep, I am going to update the article specifying I was using an older version.
I discovered the new version a few weeks ago and there are some breaking changes but also new interesting cmdlets.
So PS cmdlet on above article works only if you have the old version?
There is no other way of doing this? Because this could be very handy for me.
@Jimmy, I believe this is how you run the command on the newer version:
That command would run the updates at 6:00pm today.
I think this wont work in 2016 server, does it?
@Octavio
Yes I use it on Win 2016 servers too.
Hi
Does anyone knows if this works on Azure VM’s?
@Stiven Castro
Yes it works also on Azure VMs.
If you want to run it locally, just install the module.
If you want to run it remotely you have to open the remoting ports and also ensure your local account is an administrator of the remove VM.
Running this command on a 2016 server it seems to complete but no updates are accually installed, does this work for 2016 server or is there a different command for it.
@nanodroid
The Get-WUInstall is misleading because the cmdlet only lists updates. You must use the -Install parameter in order to effectively install updates.
is there any option to get system restart notification if restart is required during windows update ?
In this version not if done remotely while in the shell. You can do a few things to get around that though like using the PendingReboot module to run it on the remote machine. https://www.powershellgallery.com/packages/PendingReboot/0.9.0.6
You've mentioned, this Module will actually install the module on the remote server if its missing – but how? Will it use the local resources?
Does that mean, that all servers must have internet connectivity? If yes – how can I implement it without internet connection?
Hi Antonio, Powershell Gallery is the default repository for the Module lookup. You could set up a local/Internal repository for the systems isolated from the internet, check the below article for the explanation and implementation instructions.
https://4sysops.com/archives/how-to-create-a-file-share-powershell-repository/
https://4sysops.com/archives/how-to-create-a-nuget-feed-powershell-repository/
I want to use this script to remotely install ONLY a particular update. The latest Windows feature version(1903 today). I don't want to start an all out update of all the latest updates on the remote computer, just the 1903 feature update. How can i use this script to achieve that?
Diddo. I somehow doubt it. I've not found a good way to do this without system center. I have lots of remotely managed devices. I'm a small MSP, and I've not found a good way to push 1903 out yet. Anyone have a comment on that?
Only think i have seen is downloaded the iso, extracting it to a folder, and then I'd have to push that entire folder out and could run a command to force the update. But it would be much better if a powershell command could initiate the process including the download from Microsoft.
I use PDQ in my company using an extracted ISO, I copy the files locally (but you could probably run from a network location too).
I use the command line:
We use this method because we have issues with windows index/windows search corruption and have to stop the service before the update – probably because we have gpo-restricted cortana/windows search significantly.
I am trying to install update remotely on a Windows 2016 server and it wasn't success. I used the following cmdlet.
pswindowsupdate 2.0 is installed locally on the server
invoke-wujob -comp server1 -runnow -cred $(get-credential) -script {get-windowsupdate -install -acceptall}
It always said access denied. The account I used is domain admin. I am however able to use invoke-command and run the scriptblock get-windows update. What other permission I need for this?
Thanks
Where you mention, that PSWindowsUpdate will install on the remote server if it is not there, does the remote server need Internet access to install PSWindowsUpdate? Or does it take from an internal location? Can we specify a location?
You might want to include the following commands:
Set-ExecutionPolicy RemoteSigned
This allows you to run the script on the comptuer
Import-Module PSWindowsUpdate
This imports the module so you can use it
If the PC doesn't have internet access, you can copy the PSWindowsUpdate folder from C:\Windows\System32\WindowsPowerShell\v1.0 folder from a computer with internet to the same folder on the non-internet computer. Then run:
Set-ExecutionPolicy RemoteSigned
Import-Module PSWindowsUpdate
Just ran across this. I am trying the below command but always get prompted for "RunNow" parameter. What his that?
Invoke-WUJob -ComputerName COMPUTER -Script "ipmo PSWindowsUpdate; Install-WindowsUpdate -AcceptAll | Out-File C:\PSWindowsUpdate.log"
To see the examples, type: "get-help Invoke-WUJob -examples"
How does one get this to work with no wifi or Bluetooth chip in the machine?
You can update a computer without an Internet connection with third party tools like WSUS Offline Update.
This script work !!!
Invoke-WUInstall -ComputerName comp1 -Script {ipmo PSWindowsUpdate; Set-ExecutionPolicy Bypass -Scope Process -Force ; Import-Module PSWindowsUpdate; Get-WUInstall -AcceptAll | Out-File C:\pswu.log } -Confirm:$false –Verbose
How did you get an "Invoke-WUInstall" command?
You need to get the proper module. Its described in the article! 🙂
I keep getting an error when trying to send the update to a single computer or variable created.
[Invoke-WUJob -ComputerName TRJWIN10-9 -Script {ipmo PSWindowsUpdate; Install-WindowsUpdate -MicrosoftUpdate -AcceptAll -AutoReboot} -RunNow -Confirm:$false]
It then prompts a RunNow:, so I put $true.
Then gives me the error: Invoke-WUJob : cannot convert 'system.string' to the type 'system.management.automation.switchparameter' required by parameter 'RunNow'.
I have enabled PSRemoting on client and PC I am using, setting Execution-Policy to Unrestricted, and setting a list of trusted hosts.
Any tips?
Thank you!
This script works for 2012 and 2016 servers. I found they can not run the same command.
Create a text file with your server names, one server per line. Save this as a script and run that, it will create task on each server to run immediately, but not reboot. You can adjust accordingly. Also noticed that if the folder for the log files does not exist, the script fails. The email part also works, just edit for your server and name.