10 August 2015

Windows Updates Reporting Tool

My firm uses MDT to build all of our computers. The windows updates are setup as packages so they can be applied to the OS before it is laid down on the PC. MDT will then download any new updates and apply them to the PC after the OS has been laid down. In order to keep track of new updates needing to be integrated as a package, I have written the following PowerShell script that will generate a CSV file listing all of the updates installed during the build and in the exact order they were installed. This gives a clean report of the updates instead of having to dig through the ZTIWindowsUpdate.log, which is what this report is generated from. I have integrated this script into the task sequence to execute immediately after the task Windows Update (Post-Application Installation). There are two parameters that need to be defined when calling the script. These are:

  1. OutputFile - give the name of the file you desire such as BaseBuildUpdatesReport.csv
  2. Path - Defines the location where you want the OutputFile to be written to
Here is an example of a command line:
  • powershell.exe -executionpolicy bypass -file WindowsUpdatesReport.ps1 -OutputFile BaseBuild.csv -Path \\NetworkLocation\Directory
Here is a screenshot setting it up as a task sequence in MDT:

You can download the code from here.




 <#       
      .NOTES  
      ===========================================================================  
       Created with:      SAPIEN Technologies, Inc., PowerShell Studio 2015 v4.2.90  
       Created on:       8/7/2015 9:54 AM  
       Created by:       Mick Pletcher  
       Filename:        WindowsUpdatesReport.ps1  
      ===========================================================================  
      .DESCRIPTION  
           This script will extract the list of windows updates installed   
           during an MDT installation.  
      .EXAMPLE  
           powershell.exe -executionpolicy bypass -file WindowsUpdatesReport.ps1 -OutputFile BaseBuild.csv -Path \\NetworkLocation\Directory  
 #>  
   
 param ([string]$OutputFile, [string]$Path)  
   
 function Get-RelativePath {  
      #Declare Local Variables  
      Set-Variable -Name RelativePath -Scope Local -Force  
        
      $RelativePath = (split-path $SCRIPT:MyInvocation.MyCommand.Path -parent) + "\"  
      Return $RelativePath  
        
      #Cleanup Local Variables  
      Remove-Variable -Name RelativePath -Scope Local -Force  
 }  
   
 function ProcessTextFile {  
      #Declare Local Variables   
      Set-Variable -Name RelativePath -Scope Local -Force  
        
      $RelativePath = Get-RelativePath  
      If ((Test-Path -Path $RelativePath$OutputFile) -eq $true) {  
           Remove-Item -Path $RelativePath$OutputFile -Force  
      }  
        
      #Cleanup Local Variables   
      Remove-Variable -Name RelativePath -Scope Local -Force  
 }  
   
 function Get-Updates {  
      #Declare Local Variables  
      Set-Variable -Name File -Scope Local -Force  
      Set-Variable -Name Line -Scope Local -Force  
      Set-Variable -Name LogFile -Scope Local -Value $env:SystemDrive"\MININT\SMSOSD\OSDLOGS\ZTIWindowsUpdate.log" -Force  
      Set-Variable -Name Name -Scope Local -Force  
      Set-Variable -Name Output -Scope Local -Force  
      Set-Variable -Name RelativePath -Scope Local -Force  
        
      $OutputArray = @()  
      $RelativePath = Get-RelativePath  
      $File = Get-Content -Path $LogFile  
      $Global:OutputFile = $RelativePath + $Global:OutputFile  
      $Output = "KB Article" + "," + "Description"  
      Out-File -FilePath $Global:OutputFile -InputObject $Output -Append -Force -Encoding UTF8  
      If ($File -ne $null) {  
           foreach ($Line in $File) {  
                Set-Variable -Name KB -Scope Local -Force  
                If ($Line -like "*INSTALL - *") {  
                     $Name = $Line  
                     $Name = $Name -replace 'x64-based', 'x64 based'  
                     $Name = $Name -replace '32-Bit', '32 Bit'  
                     $Name = $Name.split('-')  
                     If ($Name[7] -like "*Definition*") {  
                          $KB = $Name[7]  
                          $KB = $KB.Trim()  
                          $KB = $KB.split(' ')  
                          $KB = $KB.Trim()  
                          [string]$KB = $KB[0]  
                          $Name = $Name[6]  
                          $Name = $Name.Trim()  
                     } else {  
                          $KB = $Name[6]  
                          $KB = $KB.split('(')  
                          $KB = $KB.split(')')  
                          $KB = $KB.Trim()  
                          $KB = $KB[1]  
                          $Name = $Name[6]  
                          $Name = $Name.split('(')  
                          $Name = $Name[0]  
                          $Name = $Name.Trim()  
                     }  
                     $Output = $KB + "," + $Name  
                     $OutputArray = $OutputArray + $Output  
                     Remove-Variable -Name KB -Scope Local -Force  
                }  
           }  
           $Line = $null  
           $OutputArray = $OutputArray | select -Unique  
           foreach ($Line in $OutputArray) {  
                Out-File -FilePath $Global:OutputFile -InputObject $Line -Append -Force -Encoding UTF8  
           }  
      } else {  
           $Output = "No User Input Properties Exist"  
           Write-Host $Output  
           Out-File -FilePath $Global:OutputFile -InputObject $Output -Append -Force -Encoding UTF8  
      }  
        
      #Cleanup Local Variables  
      Remove-Variable -Name File -Scope Local -Force  
      Remove-Variable -Name KB -Scope Local -Force  
      Remove-Variable -Name Line -Scope Local -Force  
      Remove-Variable -Name Name -Scope Local -Force  
      Remove-Variable -Name Output -Scope Local -Force  
      Remove-Variable -Name RelativePath -Scope Local -Force  
 }  
   
 cls  
 ProcessTextFile  
 Get-Updates  
   

Related Posts:

  • Removing Outlook Data Files Automating the removal of Outlook data files is a tedious process that is difficult to automate. The registry key is a data hash that is unique on each system. Here is a script I wrote that will do just that. This script wi… Read More
  • SCCM Client Installer Installing the SCCM client takes a few minutes. This script was written so that it will wait for the ccmsetup.exe to complete. I have encountered issues with the setup not completing before the system reboots during a build… Read More
  • Transferring data between user profiles Sometimes when you use USMT, it fails for one reason or another. This script is here to transfer user files from one profile to another. It was written so that in the event USMT fails, there is still a means to automate the… Read More
  • Pinning Shortcuts to the Taskbar and Start Menu There are already scripts out there that will do this, but I have taken it a little further. I have added checking to make sure the application is installed first so that the script does not error out. I have also added on-… Read More
  • Enable Bitlocker on a Dell System After much research and troubleshooting, here is how to enable bitlocker on a Dell system, including clearing the TPM. The documentation by Dell, Trusted Computing Group, and advice from this thread and this one sa… Read More

0 comments:

Post a Comment