Scripts/WindowsUpdate.ps1
[CmdletBinding()] param ( [Parameter(Mandatory = $true)] [System.String] $Id, [Parameter(Mandatory = $true)] [System.String] $Update ) $ErrorActionPreference = 'Stop' # Enum definition $operationResultCode = @( 'Not Started' 'In Progress' 'Succeeded' 'Succeeded With Errors' 'Failed' 'Aborted' ) # Parse input update GUID's $updates = $Update.Split(',') # Status object $status = [PSCustomObject] @{ Search = [PSCustomObject] @{ Status = $false Result = $null Message = '' } Download = [PSCustomObject] @{ Status = $false Result = $null Message = '' } Install = [PSCustomObject] @{ Status = $false Result = $null Message = '' } } # Export current status $status | Export-Clixml -Path "C:\Windows\Temp\WindowsUpdate-$Id.xml" -Force ## Part 1: Search Update Start-Sleep -Seconds 2 try { $updateSession = New-Object -ComObject 'Microsoft.Update.Session' $updateSearcher = $updateSession.CreateUpdateSearcher() $searchResult = $updateSearcher.Search("IsInstalled=0 and Type='Software'") $updateDownload = New-Object -ComObject 'Microsoft.Update.UpdateColl' foreach ($currentUpdate in $searchResult.Updates) { if ($updates -contains $currentUpdate.Identity.UpdateID) { $updateDownload.Add($currentUpdate) } } if ($updateDownload.Count -eq 0) { throw 'No updates selected!' } $status.Search.Status = $true $status.Search.Result = $true $status.Search.Message = '{0} update(s) selected, download now...' -f $updateDownload.Count } catch { $status.Search.Status = $true $status.Search.Result = $false $status.Search.Message = [String] $_ exit } finally { $status | Export-Clixml -Path "C:\Windows\Temp\WindowsUpdate-$Id.xml" -Force } ## Part 2: Download Updates Start-Sleep -Seconds 2 try { $updateDownloader = $updateSession.CreateUpdateDownloader() $updateDownloader.Updates = $updateDownload $downloadResult = $updateDownloader.Download() if ($downloadResult.ResultCode -ne 2) { throw ('Download not succeeded with status {0}' -f $operationResultCode[$downloadResult.ResultCode]) } $updateInstall = New-Object -ComObject 'Microsoft.Update.UpdateColl' foreach ($currentUpdate in $searchResult.Updates) { if ($updates -contains $currentUpdate.Identity.UpdateID -and $currentUpdate.IsDownloaded) { $updateInstall.Add($currentUpdate) | Out-Null } } if ($updateInstall.Count -eq 0) { throw 'No updates downloaded!' } $status.Download.Status = $true $status.Download.Result = $true $status.Download.Message = '{0} update(s) downloaded, install now...' -f $updateInstall.Count } catch { $status.Download.Status = $true $status.Download.Result = $false $status.Download.Message = [String] $_ exit } finally { $status | Export-Clixml -Path "C:\Windows\Temp\WindowsUpdate-$Id.xml" -Force } ## Part 3: Install Updates Start-Sleep -Seconds 2 try { $updateInstaller = $updateSession.CreateUpdateInstaller() $updateInstaller.Updates = $updateInstall $installResult = $updateInstaller.Install() if ($installResult.ResultCode -ne 2) { throw ('Install not succeeded with status {0}' -f $operationResultCode[$downloadResult.ResultCode]) } $status.Install.Status = $true $status.Install.Result = $true $status.Install.Message = '{0} update(s) installed, reboot {1} required' -f $updateInstall.Count, $(if ($installResult.RebootRequired) { 'is' } else { 'is not' }) } catch { $status.Install.Status = $true $status.Install.Result = $false $status.Install.Message = [String] $_ exit } finally { $status | Export-Clixml -Path "C:\Windows\Temp\WindowsUpdate-$Id.xml" -Force } |