Public/Get-CMPendingRebootReport.ps1
|
function Get-CMPendingRebootReport { <# .SYNOPSIS Reports pending reboot state from the ConfigMgr client and Windows. .DESCRIPTION Live mode (default): CCM_ClientUtilities.DetermineIfRebootPending plus Windows registry indicators via Invoke-Command. Site mode (-SiteCode/-ProviderMachineName/-CollectionId): reads the SMS_CombinedDeviceResources.ClientState bitmask without contacting clients. .PARAMETER ComputerName Live mode targets. .PARAMETER SiteCode Site mode site code. .PARAMETER ProviderMachineName Site mode provider. .PARAMETER CollectionId Site mode collection. .EXAMPLE Get-CMPendingRebootReport -ComputerName PC01,PC02 .EXAMPLE Get-CMPendingRebootReport -SiteCode HOU -ProviderMachineName cm01 -CollectionId HOU00042 #> [CmdletBinding(DefaultParameterSetName = 'Live')] param( [Parameter(Mandatory, ParameterSetName = 'Live', ValueFromPipeline)][string[]]$ComputerName, [Parameter(Mandatory, ParameterSetName = 'Site')][string]$SiteCode, [Parameter(Mandatory, ParameterSetName = 'Site')][Alias('SiteServer')][string]$ProviderMachineName, [Parameter(Mandatory, ParameterSetName = 'Site')][string]$CollectionId ) process { if ($PSCmdlet.ParameterSetName -eq 'Site') { $ns = "root\SMS\site_$SiteCode" $ids = @((Get-CimInstance -ComputerName $ProviderMachineName -Namespace $ns -ErrorAction Stop ` -Query "SELECT ResourceID FROM SMS_FullCollectionMembership WHERE CollectionID='$CollectionId'").ResourceID) Get-CimInstance -ComputerName $ProviderMachineName -Namespace $ns -ErrorAction Stop ` -Query 'SELECT Name, ResourceID, ClientState FROM SMS_CombinedDeviceResources WHERE ClientState > 0' | Where-Object { $ids -contains $_.ResourceID } | ForEach-Object { [pscustomobject]@{ ComputerName = $_.Name ConfigMgr = [bool]($_.ClientState -band 1) FileRename = [bool]($_.ClientState -band 2) WindowsUpdate = [bool]($_.ClientState -band 4) Feature = [bool]($_.ClientState -band 8) Source = 'Site' } } return } foreach ($c in $ComputerName) { $o = [ordered]@{ ComputerName = $c; ConfigMgr = $null; HardReboot = $null; CBS = $null; WindowsUpdate = $null; FileRename = $null; Source = 'Live'; Error = $null } try { $r = Invoke-CimMethod -ComputerName $c -Namespace root\ccm\ClientSDK -ClassName CCM_ClientUtilities -MethodName DetermineIfRebootPending -ErrorAction Stop $o.ConfigMgr = [bool]$r.RebootPending; $o.HardReboot = [bool]$r.IsHardRebootPending } catch { $o.Error = "CCM: $($_.Exception.Message)" } try { $w = Invoke-Command -ComputerName $c -ErrorAction Stop -ScriptBlock { [pscustomobject]@{ CBS = Test-Path 'HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Component Based Servicing\RebootPending' WU = Test-Path 'HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\WindowsUpdate\Auto Update\RebootRequired' PFR = [bool](Get-ItemProperty 'HKLM:\SYSTEM\CurrentControlSet\Control\Session Manager' -Name PendingFileRenameOperations -ErrorAction SilentlyContinue) } } $o.CBS = $w.CBS; $o.WindowsUpdate = $w.WU; $o.FileRename = $w.PFR } catch { $o.Error = ($o.Error, "Registry: $($_.Exception.Message)" | Where-Object { $_ }) -join '; ' } [pscustomobject]$o } } } |