SCCM
Install Windows Updates on remote machine
Use this script to install all available windows update on a remote machine
<#
.SYNOPSIS
This script will automatically install all avaialable windows updates on a device and will automatically reboot if needed, after reboot, windows updates will continue to run until no more updates are available.
.PARAMETER URL
User the Computer parameter to specify the Computer to remotely install windows updates on.
#>
function install-OSUpdate {
[CmdletBinding()]
param (
[parameter(Mandatory=$true,Position=1)]
[string[]]$computer
)
ForEach ($c in $computer){
#install pswindows updates module on remote machine
[Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12
$nugetinstall = invoke-command -ComputerName $c -ScriptBlock {Install-PackageProvider -Name NuGet -MinimumVersion 2.8.5.201 -Force}
invoke-command -ComputerName $c -ScriptBlock {
[Net.ServicePointManager]::SecurityProtocol += [Net.SecurityProtocolType]::Tls12
install-module pswindowsupdate -force
}
invoke-command -ComputerName $c -ScriptBlock {Import-Module PSWindowsUpdate -force}
Do{
#Reset Timeouts
$connectiontimeout = 0
$updatetimeout = 0
#starts up a remote powershell session to the computer
do{
$session = New-PSSession -ComputerName $c
"reconnecting remotely to $c"
sleep -seconds 10
$connectiontimeout++
} until ($session.state -match "Opened" -or $connectiontimeout -ge 10)
#retrieves a list of available updates
"Checking for new updates available on $c"
$updates = invoke-command -session $session -scriptblock {Get-wulist -MicrosoftUpdate -verbose}
#counts how many updates are available
$updatenumber = ($updates.kb).count
write-host "$updatenumber updates available"
#if there are available updates proceed with installing the updates and then reboot the remote machine
if ($updates -ne $null){
#remote command to install windows updates, creates a scheduled task on remote computer
#invoke-command -ComputerName $c -ScriptBlock { Invoke-WUjob -ComputerName localhost -Script "ipmo PSWindowsUpdate; Install-WindowsUpdate -AcceptAll | Out-File C:\PSWindowsUpdate.log" -Confirm:$false -RunNow}
#Show update status until the amount of installed updates equals the same as the amount of updates available
sleep -Seconds 30
do {$updatestatus = Get-Content \\$c\c$\PSWindowsUpdate.log
"Currently processing the following update:"
Get-Content \\$c\c$\PSWindowsUpdate.log | select-object -last 1
sleep -Seconds 10
$ErrorActionPreference = ‘SilentlyContinue’
$installednumber = ([regex]::Matches($updatestatus, "Installed" )).count
$Failednumber = ([regex]::Matches($updatestatus, "Failed" )).count
$ErrorActionPreference = ‘Continue’
$updatetimeout++
}until ( ($installednumber + $Failednumber) -eq $updatenumber -or $updatetimeout -ge 720)
#restarts the remote computer and waits till it starts up again
"restarting remote computer"
#removes schedule task from computer
invoke-command -computername $c -ScriptBlock {Unregister-ScheduledTask -TaskName PSWindowsUpdate -Confirm:$false}
# rename update log
$date = Get-Date -Format "MM-dd-yyyy_hh-mm-ss"
Rename-Item \\$c\c$\PSWindowsUpdate.log -NewName "WindowsUpdate-$date.log"
Restart-Computer -Wait -ComputerName $c -Force
}
}until($updates -eq $null)
"Windows is now up to date on $c"
}
}

