Test-sthWindowsUpdateRebootRequired.ps1

<#
.synopsis
Function for testing and rebooting computers on reboot pending after update installation
 
.description
Function for testing local and remote computers on reboot pending after update installation.
 
Checks Component Based Servicing registry key - HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Component Based Servicing\RebootPending
and Windows Update registry key - HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\WindowsUpdate\Auto Update\RebootRequired.
 
Also have the possibility to initiate reboot on remote computers (not local) which need it by specifying -Restart and -YesIAmSerious parameters.
Does not initiate reboot on local computer (can be specified as 'localhost', 'hostname' or 'hostname.domainname.com')
 
By default function skips computers, that can not be accessed.
You can see, which computers were skipped by specifying -Verbose.
 
.example
Test-sthWindowsUpdateRebootRequired
 
ComputerName ComponentBasedServicing WindowsUpdate
------------ ----------------------- -------------
localhost False False
 
Get information about localhost.
 
.example
Test-sthWindowsUpdateRebootRequired -ComputerName comp-1, comp-2, localhost
 
ComputerName ComponentBasedServicing WindowsUpdate
------------ ----------------------- -------------
comp-1 False False
comp-2 True True
localhost False False
 
Get information from several computers by specifying -ComputerName parameter.
 
.example
'comp-1', 'comp-2', 'localhost' | Test-sthWindowsUpdateRebootRequired
 
ComputerName ComponentBasedServicing WindowsUpdate
------------ ----------------------- -------------
comp-1 False False
comp-2 True True
localhost False False
 
Get information from several computers by piping names of the computers into the function.
 
.example
 
Test-sthWindowsUpdateRebootRequired -ComputerName comp-1,comp-2,localhost,nonaccessiblecomputer -Verbose
 
VERBOSE: Computer nonaccessiblecomputer is not accessible.
 
ComputerName ComponentBasedServicing WindowsUpdate
------------ ----------------------- -------------
comp-1 False False
comp-2 True True
localhost False False
 
Get information from several computers by specifying -ComputerName.
Also get information about nonaccessible computers by specifying -Verbose parameter.
 
(By default nonaccessible computers is silently skipped.)
 
.example
Test-sthWindowsUpdateRebootRequired -ComputerName comp-1,comp-2,localhost -Restart -YesIAmSerious
 
ComputerName ComponentBasedServicing WindowsUpdate
------------ ----------------------- -------------
comp-1 False False
comp-2 True True
localhost True True
 
Get information from several computers and restart computers that needs it. (does not restarts localhost)
In this example comp-2 will be restarted.
 
(Both -Restart and -YesIAmSerious parameters must be specified.)
#>


function Test-sthWindowsUpdateRebootRequired
{
    [CmdletBinding()]
    Param(
        #Computer Name.
        #By default = 'localhost'
        [Parameter(ValueFromPipeline=$True)]
        [string[]]$ComputerName = 'localhost',
        #Restart computers which need it (remote only)
        [switch]$Restart,
        #Explicit reboot confirmation
        [switch]$YesIAmSerious
    )
    
    begin
    {
        $result = @()
    }

    process
    {
        foreach ($c in $ComputerName)
        {
            $i++
            Write-Progress -Activity "Testing computers" -CurrentOperation $c
            
            if(($c -eq 'localhost') -or ($c -eq $env:COMPUTERNAME) -or ($c -eq $($env:COMPUTERNAME, $env:USERDNSDOMAIN -join '.')))
            {
                $CBS = Test-Path 'HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Component Based Servicing\RebootPending'
                $WU = Test-Path 'HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\WindowsUpdate\Auto Update\RebootRequired'
            }

            else
            {
                if($sess = New-PSSession -ComputerName $c -ErrorAction SilentlyContinue)
                {
                    $CBS = Invoke-Command -ScriptBlock {Test-Path 'HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Component Based Servicing\RebootPending'} -Session $sess
                    $WU = Invoke-Command -ScriptBlock {Test-Path 'HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\WindowsUpdate\Auto Update\RebootRequired'} -Session $sess

                    if($Restart -and $YesIAmSerious -and ($CBS -or $WU))
                    {
                        Invoke-Command -ScriptBlock {Restart-Computer -Force} -Session $sess
                    }
                    
                    Remove-PSSession -Session $sess
                }
                else
                {
                    Write-Verbose -Message "Computer $c is not accessible."
                    continue
                }

            }

            $hash = [ordered]@{
                ComputerName = $c
                ComponentBasedServicing = $CBS
                WindowsUpdate = $WU
            }

            $result += New-Object -TypeName PSCustomObject -Property $hash
        }
    }

    end
    {
        Write-Output $result
    }
}