Click an Ad

If you find this blog helpful, please support me by clicking an ad!

Monday, July 7, 2014

Using Powershell to find out which Windows Updates were Installed since $Date?

I wrote this script some time ago, and now I am going back through my old scripts and making functions out of them.

The purpose of this script was to enable me to find out which Windows Update patches were installed on a server in the past X days. I wanted to be able to fully answer the "what changed" question when it came up to troubleshoot some server issue.

Here is the script as it was originally:

#------------- BEGIN SCRIPT ----------------------

#Prompt for the computer name and how far to go back
$HostChoice = (Read-Host -Prompt "Please Enter the computer name you'd like to query")
$DaysBackChoice = (Read-Host -Prompt "How many days would you like to go back?")

#Get the date from X Days ago
$DateXDaysAgo = ((get-date).adddays(-$DaysBackChoice).toshortdatestring())
$DateXDaysAgo = ($DateXDaysAgo + " 12:00:00 AM")

#Get the info from the remote computer and pass it to GridView
Get-WMIObject -ComputerName $HostChoice -Class Win32_QuickFixEngineering | 
where {$_.InstalledOn -ge $DateXDaysAgo} | sort InstalledOn | 
out-gridview

#------------- END SCRIPT ----------------------

Since writing this, I've learned that "Read-Host" kills puppies every time you use it. Or something. I've therefore decided to turn this script into a full-blown function using this as a template:

#------------- BEGIN SCRIPT ----------------------

function Do-Something {
  <#
  .SYNOPSIS
  What does this script do?
  .DESCRIPTION
  A better list of what the script does
  .EXAMPLE
  Command example
  .PARAMETER <ParameterName>
  What is the purpose of this parameter?
  #>
  [CmdletBinding()]
  param($ParameterName)
  (
    [Parameter(Mandatory=$True,
    ValueFromPipeline=$True,
    ValueFromPipelineByPropertyName=$True,
      HelpMessage='What does this parameter do?')]
    [Alias('AliasHere')]
    [ValidateLength(3,30)]
    [string]$ParameterVariableName
  )

#Put the meat of your function inside the Process block
  process {
    write-verbose "Beginning process loop"
  } #End Process
} #End Function

#------------- END SCRIPT ----------------------

After much trial and error - I had to reformat the dates for some reason, here is the final product:

#------------- BEGIN SCRIPT ----------------------


function Get-UpdatesInstalled{
  <#
  .SYNOPSIS
  Find out which updates have been installed on a computer in the past X days
  .DESCRIPTION
  This script is passed two arguments, Computername and DaysBack. You should be a member of the local administrators group on the target machine. The script then returns, in GridView, which updates have been installed within that timeframe.
  .EXAMPLE
  Get-UpdatesInstalled -ComputerName <NameString> -DaysBack <PositiveInteger>
  .PARAMETER <ComputerName>
  This sets the target computer to query.
  .PARAMETER <DaysBack>
  This sets how far back to query for updates.
  #>
  [CmdletBinding()]
  param(
    [Parameter(Mandatory=$True,
    Position=1,
    ValueFromPipeline=$True,
    ValueFromPipelineByPropertyName=$True,
      HelpMessage='Name of computer to query')]
    [ValidateLength(3,30)]
    [string]$ComputerName, 

    [Parameter(Mandatory=$True,
    Position=2,
    ValueFromPipeline=$True,
    ValueFromPipelineByPropertyName=$True,
      HelpMessage='Updates installed within how many days?')]
    [string]$DaysBack
  ) #End Param


#Put the meat of your function inside the Process block
  process {
    write-verbose "Beginning process loop"
      #Ping Test
      $PingTest = test-connection $ComputerName -quiet
      
      If ($PingTest -eq $true){
        Write-Verbose "Ping Test Successful"
#Get the date from X Days ago and reformat for use in this context
$DaysBack = "-" + $DaysBack
        $DaysBackDouble = $DaysBack -as [double]
        $DateXDaysAgo = ((get-date).adddays($DaysBackDouble).toshortdatestring())
$DateXDaysAgo = ($DateXDaysAgo + " 12:00:00 AM")

#Get the info from the remote computer and pass it to GridView
$Updates = Get-WMIObject -ComputerName $ComputerName -Class Win32_QuickFixEngineering | 
        where {$_.InstalledOn -ge $DateXDaysAgo} | sort InstalledOn | 
        out-gridview -Title "Updates installed on $ComputerName since $DateXDaysAgo"
      } #End If Pingtest
      Else {
      Write-Host "Unable to Ping Host"
      } #End Else
  } #End Process
} #End Function

#------------- END SCRIPT ----------------------



No comments:

Post a Comment