Here are two PowerShell scripts, one that checks what updates have been delivered to a computer via SCCM and the second that invokes the installation of them.
Why do you ask? Well I build servers and need to make sure all windows updates (to an approved released are installed on the newly built computer).
This can take a while for SCCM client to get its act together and download them. These two scripts allow me to easily check the status of a computer and initiate the installation remotely.
Get-UpdatesAvailableOnServer.ps1 lists the updates ready for installation
#Requires -RunAsAdministrator <# .Synopsis Lists available Windows Updates on the Server that have been delivered via SCCM .DESCRIPTION Lists available Windows Updates on the Server that have been delivered via SCCM. This does NOT list what should be installed on server. You should use MSBA on the server for that. .EXAMPLE Get-UpdatesAvailableOnServer -ComputerName Server1 .EXAMPLE Get-UpdatesAvailableOnServer This will prompt you for ComputerName to check .AUTHOR http://britv8.com Version 2 - Returns Powershell object rather than just Write-Output, for more usability #> Param ( # Pass the Server name [Parameter(Mandatory=$true, ValueFromPipelineByPropertyName=$true, Position=0)] $ComputerName ) Begin { } Process { # This is a simple get of all instances of CCM_SoftwareUpdate from root\CCM\ClientSDK $MissingUpdates = Get-WmiObject -Class CCM_SoftwareUpdate -Filter ComplianceState=0 -Namespace root\CCM\ClientSDK -Computername $ComputerName foreach ($item in $MissingUpdates) { $object = New-Object –TypeName PSObject –Prop ([ordered]@{ Computername = $Computername ArticleID = $item.ArticleID Name = $item.Name URL = $item.URL }) $object } } End { }
Invoke-UpdatesAvailableOnServer.ps1 lists the updates ready for installation AND kicks off the installation process
<# .Synopsis Invokes the installation of available Windows Updates on the Server that have been delivered via SCCM .DESCRIPTION Invokes the installation of available Windows Updates on the Server that have been delivered via SCCM. .EXAMPLE Invoke-UpdatesAvailableOnServer -ServerName Server1 .EXAMPLE Invoke-UpdatesAvailableOnServer This will prompt you for Servername to check .AUTHOR http://britv8.com #> Param ( # Pass the Server name [Parameter(Mandatory=$true, ValueFromPipelineByPropertyName=$true, Position=0)] $ServerName ) Begin { } Process { # This is a simple get of all instances of CCM_SoftwareUpdate from root\CCM\ClientSDK $MissingUpdates = Get-WmiObject -Class CCM_SoftwareUpdate -Filter ComplianceState=0 -Namespace root\CCM\ClientSDK -Computername $ServerName Write-host "List of Updates Available for install on Server $ServerName" foreach ($item in $MissingUpdates) { Write-Host $item.ArticleID $item.Name $item.URL } # The following is done to do 2 things: Get the missing updates (ComplianceState=0) # and take the PowerShell object and turn it into an array of WMI objects $MissingUpdatesReformatted = @($MissingUpdates | ForEach-Object {if($_.ComplianceState -eq 0){[WMI]$_.__PATH}}) # The following is the invoke of the CCM_SoftwareUpdatesManager.InstallUpdates with our found updates # NOTE: the command in the ArgumentList is intentional, as it flattens the Object into a System.Array for us # The WMI method requires it in this format. $InstallReturn = Invoke-WmiMethod -Class CCM_SoftwareUpdatesManager -Name InstallUpdates -ArgumentList (,$MissingUpdatesReformatted) -Namespace root\ccm\clientsdk -Computername $ServerName Write-host "Install of updates initiated on Server $ServerName , A Manual reboot will be required once updates installed" } End { }
Source for these was based on https://gallery.technet.microsoft.com/scriptcenter/Install-All-Missing-8ffbd525
I just split it out into just a read, then an invoke.
Also enabled it to be run against a remote computer.
Thank you for the script, that is the only script to check pending updates that works for me “out of the box”.
Your Welcome!
Awesome script!!! Thank you for sharing. I have been playing around with taking what you’ve done above and update it to grab an update status from a list of servers using the get-content command. Once done, I also want to push those updates out to that same list of servers but so far, I haven’t had much luck as of yet. Would you have any suggestions or have you done something like this already? Thank you again in advance…