= Powershell Remoting: Check Windows Patch Status =
**Summary**: Goal of the script is to check the patch status for a Windows Server using PowerShell Remoting. \\
**Date**: Around 2022 \\
**Refactor**: 6 April 2025: Checked links and formatting. \\
{{tag>powershell windows}}
= Prepare =
Prepare the script by creating a variable containing the servername(s) and setting variables:
# Servervariable
$servers = "server01"
$servers = @("server01","server02","server03")
$servers = Get-ADComputer -Filter * -searchbase "OU=Servers,DC=shift,DC=local" | Select-Object -ExpandProperty Name | Sort-Object
# Credentials
$credentials = Get-Credential
= The Script =
# Powershell remoting settings
$remotePort = 5986
$pso = New-PSSessionOption -SkipCACheck -SkipCNCheck -SkipRevocationCheck
$Culture = "en-US"
$pso.Culture = $Culture
$pso.UICulture = $Culture
$sessionParams = @{}
$sessionParams.Add('UseSSL', $true)
$sessionParams.Add('Port', $remotePort)
$sessionParams.Add('Credential', $credentials)
# Function
function PatchStatus {
param (
[array] $servers
)
ForEach ($server in $servers){
Write-Host "`nName : " -NoNewline; Write-Host "$server" -ForegroundColor Green
if ((Test-Connection -computer $($server + "." + $domain) -count 1 -quiet) -AND ($session = New-PSSession -ComputerName $($server + "." + $domain) -EnableNetworkAccess -SessionOption $pso @sessionParams -ErrorAction SilentlyContinue)){
try {
Invoke-Command -Session $session -ScriptBlock {
Param($server, $domain);
# Check dor uptime
Write-Host "Uptime: $(((Get-Date) - (Get-CimInstance Win32_OperatingSystem).LastBootupTime).Days) days";
# Check for last 4 installed updates - note that patches with a pending reboot will not be shown due to a missing InstalledOn value
Write-Host "Last Patches: "
$patches = Get-HotFix | Sort-Object -Descending -Property InstalledOn -ErrorAction SilentlyContinue | Select-Object -First 4 -Property HotFixID,Description,InstalledOn
ForEach ($patch in $patches){Write-Host "$(($patch.InstalledOn).ToString("dd MMM yyyy")): $($patch.HotFixId) ($($patch.Description))"}
# Check for pending reboot
function Test-PendingReboot {
if (Get-ChildItem "HKLM:\Software\Microsoft\Windows\CurrentVersion\Component Based Servicing\RebootPending" -EA Ignore) { return $true }
if (Get-Item "HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\WindowsUpdate\Auto Update\RebootRequired" -EA Ignore) { return $true }
if (Get-ItemProperty "HKLM:\SYSTEM\CurrentControlSet\Control\Session Manager" -Name PendingFileRenameOperations -EA Ignore) { return $true }
try {
$util = [wmiclass]"\\.\root\ccm\clientsdk:CCM_ClientUtilities"
$status = $util.DetermineIfRebootPending()
if (($null -ne $status) -and $status.RebootPending) {
return $true
}
}
catch { }
return $false
}
if (Test-PendingReboot){
Write-Host "Pending reboot: " -NoNewline; Write-Host "True" -ForegroundColor Red
}else {
Write-Host "Pending reboot: " -NoNewline; Write-Host "False" -ForegroundColor Green
}
} -ArgumentList $server, $domain
} catch {
Write-Host "$server patch check failed"
Write-Host $_.ScriptStackTrace
Write-host $_.Exception.Message
} finally {
Remove-PSSession -Session $session
$server = $null
}
} else {
Write-Host "$server cannot be reached or remote session failed" -ForegroundColor Red
}
}
}
= Start the Script =
Start with {{{PatchStatus $servers}}}
= Useful Links =
* Check for pending reboot: https://stackoverflow.com/questions/47867949/how-can-i-check-for-a-pending-reboot/68627581#68627581