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 ----------------------
<#
.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