Thursday, June 25, 2015

Powershell Script - Get-LastBootTime - remotely find out when your servers where last rebooted

Here's another handy and simple function which lets you query a bunch of servers at once to find out when they were last rebooted.  It's taking advantage of Get-WmiObject and the root\civ2\Win32_OperatingSystem class.  For maximum parallelization, I've forced pipeline usage to first colapse the process block into a single array to create only one Get-WmiObject call.  This is significantly faster than the default pipeline behavior which is sequential, with 1000 servers completing under a minute (local LAN) vs sequential calls taking close to 10 minutes.

Here's it in action:

PS C:\> Get-Content .\serverlist.txt | Get-LastBootTime

Name      UpSince
----      -------
NOTSERVER Unknown             
SERVER001 6/20/2015 10:46:25 PM
SERVER002 6/20/2015 10:26:24 PM
SERVER003 6/20/2015 10:30:17 PM
SERVER004 6/20/2015 10:27:52 PM
SERVER005 6/20/2015 10:38:27 PM
SERVER006 6/20/2015 10:30:12 PM
SERVER007 6/20/2015 11:54:01 PM
SERVER008 6/20/2015 10:28:39 PM
SERVER009 6/20/2015 10:26:15 PM
SERVER010 6/20/2015 10:27:01 PM

Source Code:
#Requires -Version 2.0
Function Get-LastBootTime{
<#
.SYNOPSIS
Uses WMI to query one or more computers and returns a sorted table of names and date/times of since last boot.
.DESCRIPTION
Works with any windows computer that can accept remote WMI queries
.PARAMETER ComputerName
Specifies one or more server names.
.EXAMPLE
Get-Content .\serverlist.txt | Get-LastBootTime | export-csv .\report.csv
Reads in a list of servers, queries them for last boot time, writes report to csv.
.EXAMPLE
Get-LastBootTime -ComputerName 'server1','server2'
Queries two servers and returns their last boot time.
.LINK
http://www.bryanvine.com/2015/06/powershell-script-get-lastboottime.html
.LINK
Get-WmiObject
.NOTES
Author: Bryan Vine
Last updated: 6/25/2015
#>
[CmdletBinding()]
Param(
[Parameter(Mandatory=$true,valuefrompipeline=$true,Position=0)]
[alias("CN","MachineName","ServerName","Server")][ValidateNotNullOrEmpty()][string[]]
$ComputerName
)
BEGIN{
$allcomputers = @()
$reportoutput = @()
}
PROCESS{
#Little hack that allows you to use pipeline while still taking advantage of Get-WmiObject's multithreading capabilities
$allcomputers += $ComputerName
}
END{
#WMI call to all computers
$allwmi = Get-WmiObject -Class Win32_OperatingSystem -ComputerName $allcomputers -ErrorAction SilentlyContinue
#Error handling: Compare which computers failed WMI queries and output their uptime as unknown
if($allwmi){
Compare-Object -ReferenceObject $allcomputers -DifferenceObject ($allwmi | select -ExpandProperty CSName) | `
select -ExpandProperty inputobject | ForEach-Object{
$obj = New-Object PSObject
$obj | Add-Member NoteProperty Name $_
$obj | Add-Member NoteProperty UpSince 'Unknown'
$reportoutput += $obj
}
}
else{
#Error - all computers failed to query
$allcomputers | ForEach-Object{
$obj = New-Object PSObject
$obj | Add-Member NoteProperty Name $_
$obj | Add-Member NoteProperty UpSince 'Unknown'
$reportoutput += $obj
}
}
#For successful queries, return a nice PS object for each computer
foreach($wmi in $allwmi){
$obj = New-Object PSObject
$obj | Add-Member NoteProperty Name $wmi.CSName
$obj | Add-Member NoteProperty UpSince $wmi.ConvertToDateTime($wmi.LastBootUpTime)
$reportoutput += $obj
}
Write-Output ($reportoutput | sort Name)
}
}
view raw BV-Uptime.ps1 hosted with ❤ by GitHub

No comments:

Post a Comment