Wednesday, October 21, 2015

Find when servers were last updated

My colleague is just starting to learn powershell so I was giving him a hand on an idea he had. He wanted to do a script that would check when the last time servers had updates applied. I'm not saying we came to the best solution but here is what we came up with.

I think my favourite part of this is the evolution of making the script. So I'll show you the evolution that my script went through.

I knew that 'get-hotfix' would return the installed updates as well as when they were installed. I figured I could run that, sort it by date, and select the last line.

(Get-HotFix | sort InstalledOn | select -Last 1).installedon
This will return the date of the last update. I also realized that even though it returns a time for "installedon" they are always midnight so it must not actually record that info.

The next evolution was to get this to run against multiple computers. I figured a for-each loop would be easiest to get him started.

 $servers = 'Server1','Server2' foreach ($server in $servers)
{  (Get-HotFix -ComputerName $server | sort InstalledOn | select -Last 1).installedon
Well it turns out that Get-Hotfix doesn't like this. I got a bunch of red text so I decided to use Invoke-Command instead.

 $servers = 'Server1','Server2' foreach ($server in $servers)
{  $date = invoke-command -ComputerName $Server -ScriptBlock {(Get-HotFix | sort InstalledOn | select -Last 1).installedon }  write-host $server $date
This worked much better but it would be nice to grab the servers from AD instead of having to know the server names.

 $servers = Get-ADComputer -Filter {OperatingSystem -Like "Windows Server 2012*"} | select name
 foreach ($server in $servers)
{  invoke-command -ComputerName $Server -ScriptBlock {(Get-HotFix | sort InstalledOn | select -Last 1).installedon }write-host $server $date
 
So that will grab every server 2012 or 2012 R2 box in AD. The output of this isn't great though, it's just a list of server names and dates on the screen. Sorry Don Jones, I used 'write-host'.

A better solution would be to output this to a csv. Luckily the easiest way to do this will also speed up the command. Rather than use a loop and get the results serially I'm going to use a session and get the results in parallel.

$computers = Get-ADComputer -Filter {OperatingSystem -Like "Windows Server 2012*"} | select -expand Name  $session = New-PSSession -ComputerName $computers  invoke-command -session $session -ScriptBlock {(Get-HotFix | sort InstalledOn | select PSComputername,Installedon -Last 1)} | export-csv c:\temp\servers.csv
I think this is much better. Now we're getting the results faster and it's going out to a CSV file. It's still far from perfect. Error handling isn't great and I'm getting a couple extra columns in my CSV that I don't want.

This gets him the data he wants so I'm going to leave it in his hands to try to refine.

No comments:

Post a Comment