Thursday, February 25, 2016

Getting an overview of reboots revisited

In my previous post I mentioned invoke-command using the -AsJob option. But then I saw a post from Tommy Maynard that made things even quicker and certainly a bit easier.

Instead of doing a "foreach server in serverlist" loop to run the invoke-command scriptblock, you can do an invoke-command on the entire serverlist in one go!

$ServerList = Get-Content C:\Scripts\ServerList.txt.txt

$block = {Get-EventLog System | Where-Object {$_.EventID -eq "1074" -or $_.EventID -eq "6008" -or $_.EventID -eq "1076"} | Select Machinename, TimeWritten, UserName, EventID, Message}

Invoke-Command -ComputerName $ServerList -ScriptBlock $block | ft -AutoSize -Wrap |Out-File C:\scripts\ServerRestart.txt

This certainly cuts down on scriptsize :-)

How much time you save depends on the amount of servers, but I tested it with 5 VM's, and saw some surprising things in my test: Invoke-command feeding the serverlist as described above actually took longer than invoke-command using the -Asjob option.

Usually I get 14 seconds for the old fashioned "foreach" test, then about 6 seconds for the invoke-command feeding the serverlist, and about 2 seconds for the invoke-command with -Asjob.

Here's the test I ran a few times after another:

$ServerList = Get-Content C:\Scripts\ServerList.txt.txt

# Test 1: Old fashioned way

Write-Host -ForegroundColor green "Foreach server in serverlist"
Measure-Command {foreach ($server in $ServerList){Get-EventLog System -ComputerName "$server" | Where-Object {$_.EventID -eq "1074" -or $_.EventID -eq "6008" -or $_.EventID -eq "1076"} | ft Machinename, TimeWritten, UserName, EventID, Message -AutoSize}}|select Seconds|ft -AutoSize

# Test 2: Doing the test with invoke-command, feeding the serverlist in one go

$block = {Get-EventLog System | Where-Object {$_.EventID -eq "1074" -or $_.EventID -eq "6008" -or $_.EventID -eq "1076"}}

Write-Host -ForegroundColor green "invoke with serverlist"
Measure-Command {Invoke-Command -ComputerName $ServerList -ScriptBlock $block}|select Seconds|ft -AutoSize

# Test 3: Doing the test with "Job" functionality

Write-Host -ForegroundColor green "Job Functionality"
Measure-Command {
foreach ($Server in $ServerList){
Invoke-Command -ComputerName $Server -ScriptBlock $block -AsJob
}

While (Get-Job -State "Running") {
}    

Get-Job| Receive-Job |ft -AutoSize
Get-Job | Remove-Job
Write-Host -ForegroundColor Yellow "Done!"
}|select Seconds|ft -AutoSize

The weird thing however, is if I swap test 2 and 3 around, invoke-command using -Asjob consistently works slower than the invoke-command with serverlist.  The old fashioned test still took  14 seconds, but the invoke-command with -Asjob took 2 to 6 seconds, and invoke-command feeding the serverlist consistently took 1 second.

Last try:

So I wasn't sure why the last piece of the script went faster than the middle part, but swapping it consistently made the latter one faster. So I ran each of the two tests in a loop for about 10 times in a row, and lo and behold: The invoke-command using -Asjob was running at 1-2 seconds, and feeding the serverlist in one go ran consistently for 1 second. For both tests, the first run took about 6 seconds, and this could be the same delay that is apparent in the test I listed above.

I assume that somehow a connection is made using Invoke-Command, and this session somehow stays alive.

In the end: Feed invoke-command the serverlist as a whole. It's easier to manage. and a little bit faster consistently.

No comments:

Post a Comment