Hello all,
I need a script to monitor a pending reboot after a windows update on my systems.
Until now I have a pure Powershell script but this is not yet adapted to PRTG. The inputs and outputs do not fit yet.
I have very little knowledge about scripting.
Can someone please help me here.
Script:
____________________________________________________________________________________________________________
[CmdletBinding()]
[string[]]$ComputerName=$args[0]
param( [Parameter(Mandatory)] [ValidateNotNullOrEmpty()] [string[]]$ComputerName,
[Parameter()] [ValidateNotNullOrEmpty()] [pscredential]$Credential )
$ErrorActionPreference = 'Stop'
$scriptBlock = {
$VerbosePreference = $using:VerbosePreference function Test-RegistryKey { [OutputType('bool')] [CmdletBinding()] param ( [Parameter(Mandatory)] [ValidateNotNullOrEmpty()] [string]$Key )
$ErrorActionPreference = 'Stop'
if (Get-Item -Path $Key -ErrorAction Ignore) { $true } }
function Test-RegistryValue { [OutputType('bool')] [CmdletBinding()] param ( [Parameter(Mandatory)] [ValidateNotNullOrEmpty()] [string]$Key,
[Parameter(Mandatory)] [ValidateNotNullOrEmpty()] [string]$Value )
$ErrorActionPreference = 'Stop'
if (Get-ItemProperty -Path $Key -Name $Value -ErrorAction Ignore) { $true } }
function Test-RegistryValueNotNull { [OutputType('bool')] [CmdletBinding()] param ( [Parameter(Mandatory)] [ValidateNotNullOrEmpty()] [string]$Key,
[Parameter(Mandatory)] [ValidateNotNullOrEmpty()] [string]$Value )
$ErrorActionPreference = 'Stop'
if (($regVal = Get-ItemProperty -Path $Key -Name $Value -ErrorAction Ignore) -and $regVal.($Value)) { $true } }
- Added "test-path" to each test that did not leverage a custom function from above since
- an exception is thrown when Get-ItemProperty or Get-ChildItem are passed a nonexistant key path $tests = @( { Test-RegistryKey -Key 'HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Component Based Servicing\RebootPending' } { Test-RegistryKey -Key 'HKLM:\Software\Microsoft\Windows\CurrentVersion\Component Based Servicing\RebootInProgress' } { Test-RegistryKey -Key 'HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\WindowsUpdate\Auto Update\RebootRequired' } { Test-RegistryKey -Key 'HKLM:\Software\Microsoft\Windows\CurrentVersion\Component Based Servicing\PackagesPending' } { Test-RegistryKey -Key 'HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\WindowsUpdate\Auto Update\PostRebootReporting' } { Test-RegistryValueNotNull -Key 'HKLM:\SYSTEM\CurrentControlSet\Control\Session Manager' -Value 'PendingFileRenameOperations' } { Test-RegistryValueNotNull -Key 'HKLM:\SYSTEM\CurrentControlSet\Control\Session Manager' -Value 'PendingFileRenameOperations2' } {
- Added test to check first if key exists, using "ErrorAction ignore" will incorrectly return $true 'HKLM:\SOFTWARE\Microsoft\Updates' | Where-Object { test-path $_ -PathType Container } | ForEach-Object { (Get-ItemProperty -Path $_ -Name 'UpdateExeVolatile' | Select-Object -ExpandProperty UpdateExeVolatile) -ne 0 } } { Test-RegistryValue -Key 'HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\RunOnce' -Value 'DVDRebootSignal' } { Test-RegistryKey -Key 'HKLM:\SOFTWARE\Microsoft\ServerManager\CurrentRebootAttemps' } { Test-RegistryValue -Key 'HKLM:\SYSTEM\CurrentControlSet\Services\Netlogon' -Value 'JoinDomain' } { Test-RegistryValue -Key 'HKLM:\SYSTEM\CurrentControlSet\Services\Netlogon' -Value 'AvoidSpnSet' } {
- Added test to check first if keys exists, if not each group will return $Null
- May need to evaluate what it means if one or both of these keys do not exist ( 'HKLM:\SYSTEM\CurrentControlSet\Control\ComputerName\ActiveComputerName' | Where-Object { test-path $_ } | %{ (Get-ItemProperty -Path $_ ).ComputerName } ) -ne ( 'HKLM:\SYSTEM\CurrentControlSet\Control\ComputerName\ComputerName' | Where-Object { Test-Path $_ } | %{ (Get-ItemProperty -Path $_ ).ComputerName } ) } {
- Added test to check first if key exists 'HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\WindowsUpdate\Services\Pending' | Where-Object { (Test-Path $_) -and (Get-ChildItem -Path $_) } | ForEach-Object { $true } } )
foreach ($test in $tests) { Write-Verbose "Running scriptblock: [$($test.ToString())]" if (& $test) { $true break } } }
foreach ($computer in $ComputerName) { try { $connParams = @{ 'ComputerName' = $computer } if ($PSBoundParameters.ContainsKey('Credential')) { $connParams.Credential = $Credential }
$output = @{ ComputerName = $computer IsPendingReboot = $false }
$psRemotingSession = New-PSSession @connParams
if (-not ($output.IsPendingReboot = Invoke-Command -Session $psRemotingSession -ScriptBlock $scriptBlock)) { $output.IsPendingReboot = $false } [pscustomobject]$output } catch { Write-Error -Message $_.Exception.Message } finally { if (Get-Variable -Name 'psRemotingSession' -ErrorAction Ignore) { $psRemotingSession | Remove-PSSession } } }
____________________________________________________________________________________________________________
With kind regards Nico
Hello Nico,
In order for the script to work with PRTG, the output has to be in the correct syntax. You'll find examples here.
This script might also be of interest for you.
Aug, 2022 - Permalink