23 May 2017

Pending Reboot Reporting with Orchestrator

As we are implementing the ADR in SCCM for servers, we want to know if systems are pending a reboot without having to log into every server. Thankfully, Kent Agerlund, formulated and posted this awesome solution for tracking pending reboots using a compliance rule and baseline in SCCM. It reports systems that are waiting for a reboot to a non-compliance collection.

I wanted to take this to the next level with automated reporting via email. I wrote the script below that queries the non-compliance collection in SCCM and writes the results to a .CSV file and emails that file to the appropriate IT staff. I integrated this with Orchestrator so this process becomes an automated process.

To implement this in Orchestrator, you will need to use the monitor date/time activity to schedule the execution. I have it scheduled for every day.



Next, you link a Run Program activity to run the PowerShell script.



The next activity is the Get File Status. This will check to see if the .CSV file exists. The PowerShell script will delete the old .CSV file and will not create a new one if there are no systems pending a reboot.



The next thing is to customize the link between the Get File Status and Send Email activities. This stops the Send Email from taking place if the .CSV file is not present.


Finally, the Send Email activity is executed to send an email to the appropriate IT staff with the attached .CSV file.


Here is a screenshot of my runbook.

I have included in the script an example of how to implement this in the command line. You can download the PowerShell script from my GitHub site located here.

I also wanted to say how much easier SAPIEN's PowerShell Studio made writing this script. PowerShell studio is a fantastic PowerShell editing tool that takes coding to a whole new level.

 <#  
      .SYNOPSIS  
           Reboot Report  
        
      .DESCRIPTION  
           This script will query SCCM for a list of machines pending a reboot. It will then write the list to a .CSV file.  
        
      .PARAMETER CollectionName  
           Name of the collection to query for a list of machines  
        
      .PARAMETER SCCMServer  
           Name of the SCCM Server  
        
      .PARAMETER SCCMDrive  
           Drive of the SCCM server  
        
      .PARAMETER ReportFile  
           Name of the file to write the list of systems pending a reboot.  
        
      .EXAMPLE  
           powershell.exe -file RebootReporting.ps1 -CollectionName "All Servers" -SCCMServer ACMESCCM -SCCMDrive CMG -ReportFile "PendingRebootReport.csv"  
   
           ===========================================================================  
           Created with:     SAPIEN Technologies, Inc., PowerShell Studio 2017 v5.4.139  
           Created on:       5/22/2017 2:42 PM  
           Created by:       Mick Pletcher  
           Organization:  
           Filename:         RebootReporting.ps1  
           ===========================================================================  
 #>  
 [CmdletBinding()]  
 param  
 (  
      [ValidateNotNullOrEmpty()][string]$CollectionName,  
      [ValidateNotNullOrEmpty()][string]$SCCMServer,  
      [ValidateNotNullOrEmpty()][string]$SCCMDrive,  
      [ValidateNotNullOrEmpty()][string]$ReportFile  
 )  
   
 function Import-SCCMModule {  
 <#  
      .SYNOPSIS  
           Import SCCM Module  
        
      .DESCRIPTION  
           Locate the ConfigurationManager.psd1 file and import it.  
        
      .PARAMETER SCCMServer  
           Name of the SCCM server to connect to.  
        
      .NOTES  
           Additional information about the function.  
 #>  
        
      [CmdletBinding()]  
      param  
      (  
           [ValidateNotNullOrEmpty()][string]$SCCMServer  
      )  
        
      #Get the architecture of the specified SCCM server  
      $Architecture = (get-wmiobject win32_operatingsystem -computername $SCCMServer).OSArchitecture  
      #Get list of installed applications  
      $Uninstall = Invoke-Command -ComputerName $SCCMServer -ScriptBlock { Get-ChildItem -Path REGISTRY::"HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall" -Force -ErrorAction SilentlyContinue }  
      If ($Architecture -eq "64-bit") {  
           $Uninstall += Invoke-Command -ComputerName $SCCMServer -ScriptBlock { Get-ChildItem -Path REGISTRY::"HKEY_LOCAL_MACHINE\SOFTWARE\WOW6432Node\Microsoft\Windows\CurrentVersion\Uninstall" -Force -ErrorAction SilentlyContinue }  
      }  
      #Get the registry key that specifies the location of the SCCM installation drive and directory  
      $RegKey = ($Uninstall | Where-Object { $_ -like "*SMS Primary Site*" }) -replace 'HKEY_LOCAL_MACHINE', 'HKLM:'  
      $Reg = Invoke-Command -ComputerName $SCCMServer -ScriptBlock { Get-ItemProperty -Path $args[0] } -ArgumentList $RegKey  
      #Parse the directory listing  
      $Directory = (($Reg.UninstallString).Split("\", 4) | Select-Object -Index 0, 1, 2) -join "\"  
      #Locate the location of the SCCM module  
      $Module = Invoke-Command -ComputerName $SCCMServer -ScriptBlock { Get-ChildItem -Path $args[0] -Filter "ConfigurationManager.psd1" -Recurse } -ArgumentList $Directory  
      #If more than one module is present, use the latest one  
      If ($Module.Length -gt 1) {  
           foreach ($Item in $Module) {  
                If (($NewModule -eq $null) -or ($Item.CreationTime -gt $NewModule.CreationTime)) {  
                     $NewModule = $Item  
                }  
           }  
           $Module = $NewModule  
      }  
      #format the $Module unc path  
      [string]$Module = "\\" + $SCCMServer + "\" + ($Module.Fullname -replace ":", "$")  
      #Import the SCCM module  
      Import-Module -Name $Module  
 }  
   
 function Get-RebootPendingSystems {  
 <#  
      .SYNOPSIS  
           Reboot Pending Systems  
        
      .DESCRIPTION  
           This function connects to SCCM and retrieves the list of systems pending a reboot.  
        
      .EXAMPLE  
                     PS C:\> Get-RebootPendingSystems  
        
      .NOTES  
           Additional information about the function.  
 #>  
        
      [CmdletBinding()]  
      param ()  
        
      #Create Report array  
      $Report = @()  
      #If the SCCM drive does not have a colon at the end, add it  
      If ($SCCMDrive[$SCCMDrive.Length - 1] -ne ":") {  
           $SCCMDrive = $SCCMDrive + ":"  
      }  
      #Change the location to the SCCM drive  
      Set-Location $SCCMDrive  
      #Get list of systems in the SCCM collection that are pending a reboot  
      $Systems = (Get-CMDevice -collectionname $CollectionName).Name | Sort-object  
      foreach ($System in $Systems) {  
           $Object = New-Object -TypeName System.Management.Automation.PSObject  
           $Object | Add-Member -MemberType NoteProperty -Name ComputerName -Value $System.ToUpper()  
           $Report += $Object  
      }  
      #Change location back to the system homedrive  
      Set-Location $env:HOMEDRIVE  
      #Return the list of systems  
      Return $Report  
 }  
   
 function Get-RelativePath {  
 <#  
      .SYNOPSIS  
           Get the relative path  
        
      .DESCRIPTION  
           Returns the location of the currently running PowerShell script  
        
      .NOTES  
           Additional information about the function.  
 #>  
        
      [CmdletBinding()][OutputType([string])]  
      param ()  
        
      $Path = (split-path $SCRIPT:MyInvocation.MyCommand.Path -parent) + "\"  
      Return $Path  
 }  
   
 Clear-Host  
 #Find and import the PowerShell SCCM Module  
 Import-SCCMModule -SCCMServer $SCCMServer  
 #Get a list of systems pending a reboot  
 $Report = Get-RebootPendingSystems  
 #Get the path this script is being executed from  
 $RelativePath = Get-RelativePath  
 #Add the relative path to the filename  
 $ReportFile = $RelativePath + $ReportFile  
 #Delete Report File if it exists  
 If ((Test-Path $ReportFile) -eq $true) {  
      Remove-Item -Path $ReportFile -Force  
 }  
 If (($Report -ne $null) -and ($Report -ne "")) {  
      #Display the list of systems to the screen  
      $Report  
      #Export the list of systems to a CSV file  
      $Report | Export-Csv -Path $ReportFile -Encoding UTF8 -Force -NoTypeInformation  
 }  
   

Related Posts:

  • Configuring BIOS Settings during the SCCM/MDT Imaging Process You want to set the BIOS settings during an imaging process, but you can't get it correctly sequenced into the task sequencing. The BIOS can be set in the task sequencing process, but it can only function correctly after the… Read More
  • Microsoft Office 2010 Deployment Script As all deployment administrators know, deploying huge packages to laptop users is a challenge because of users possibly being in meetings with clients and such. To rectify these issues, the best method I have found is being… Read More
  • SMS 2003 Changing Cache Size in Windows 7 64-Bit If you are in the situation we are in which you are still using SMS 2003 with Windows 7 64-Bit, there are some functions that are not compatible in SMS. For one, any function that addresses the UIResource.UIResourceMGR in a… Read More
  • Office 2010 Deployment Project Template Microsoft originally created the Project 2007 template for the deployment of Office 2007 but has not created one for Office 2010. I am beginning the process of deploying Office 2010 and decided to convert the 2007 Project de… Read More
  • SCCM/MDT Move the Installation Progress Window This script is to allow you to see the pop-ups that occur during software installations which are hidden by the Installation Progress Window. This script moves the window to the top of the screen. The Deployment Guys origina… Read More

0 comments:

Post a Comment