Last active
February 10, 2016 22:26
-
-
Save TheRickOlson/68dd74b5e5699fc44da0 to your computer and use it in GitHub Desktop.
January 2016 Script Puzzle
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<# | |
.SYNOPSIS | |
Gets the uptime of one or more computers. | |
.PARAMETER Name | |
The name of the computer(s) that you want to run this command against. By default it will run against the local machine. You can pass multiple computers separated with comma, or pass objects to it via the pipe. | |
.EXAMPLE | |
Get-Uptime | |
With no parameters passed, this will get the uptime of the local machine | |
ComputerName : TS-SA-12345 | |
StartTime : 2/10/2016 7:35:21 AM | |
Uptime (Days) : 0.3 | |
Status : OK | |
MightNeedPatched : False | |
.EXAMPLE | |
Get-Uptime -Name SERVER1 | |
Check the uptime of a single computer named SERVER1 | |
ComputerName : SERVER1 | |
StartTime : 1/31/2016 12:00:00 AM | |
Uptime (Days) : 10.3 | |
Status : OK | |
MightNeedPatched : False | |
.EXAMPLE | |
Get-Uptime -Name SERVER1,SERVER2,SERVER3 | Format-Table -Autosize | |
This example passes three computer names to Get-Uptime named SERVER1, SERVER2 and SERVER3 | |
ComputerName StartTime Uptime (Days) Status MightNeedPatched | |
------------ --------- ------------- ------ ---------------- | |
SERVER1 1/31/2016 5:54:26 AM 10.3 OK False | |
SERVER2 1/31/2016 5:45:40 AM 10.3 OK False | |
SERVER3 OFFLINE False | |
.EXAMPLE | |
Get-ADComputer SERVER1 | Get-Uptime | |
In this example, we use Get-ADComputer (from the ActiveDirectory module) to get the SERVER1 computer object. Then we pass that object to Get-Uptime. | |
ComputerName : SERVER1 | |
StartTime : 1/31/2016 12:00:00 AM | |
Uptime (Days) : 10.3 | |
Status : OK | |
MightNeedPatched : False | |
.INPUTS | |
String. You can pass computer name via the $Name parameter to Get-Uptime | |
.OUTPUTS | |
System.Management.Automation.PSCustomObject | |
#> | |
function Get-Uptime{ | |
# This sets the function up to accept objects as input | |
[CmdletBinding()] | |
param ( | |
[Parameter(ValueFromPipeline=$true,ValueFromPipelinebyPropertyName=$true)] | |
[string[]]$Name=$env:computername) | |
PROCESS { | |
foreach ($comp in $Name) | |
{ | |
try { | |
# Pre-build our object | |
$outputObject = [Ordered]@{ | |
'ComputerName' = $comp | |
'StartTime' = $null | |
'Uptime (Days)' = $null | |
'Status' = $null | |
'MightNeedPatched' = $false | |
} | |
#Test to see if the computer is alive | |
Write-Verbose -Message "[$comp]: Attempting to connect with computer." | |
if (-not(Test-Connection -ComputerName $comp -Count 1 -Quiet)) { | |
# Set the status to offline and throw an exception | |
$outputObject.Status = "OFFLINE" | |
throw "The computer [$($comp)] is offline." | |
} | |
# Set the status to OK | |
$outputObject.Status = "OK" | |
# Get the time object and calculate length of time since last boot | |
Write-Verbose -Message "[$comp]: Calculating uptime days." | |
$obj = Get-WmiObject -Class Win32_OperatingSystem -ComputerName $comp | |
$time = $obj.ConvertToDateTime($obj.LocalDateTime) - $obj.ConvertToDateTime($obj.LastBootUpTime) | |
# Set the Start Time | |
$outputObject.StartTime = $obj.ConvertToDateTime($obj.LastBootUpTime) | |
# Set the Uptime (Days) parameter and format it to only extend one decimal point | |
$outputObject.'Uptime (Days)' = "{0:N1}" -f $time.TotalDays | |
# Make patching determination based on total days since last boot | |
Write-Verbose -Message "[$comp]: Checking if computer may need patching." | |
if ($time.TotalDays -gt '30') { | |
$outputObject.MightNeedPatched = $true | |
} else { $outputObject.MightNeedPatched = $false } | |
} | |
catch | |
{ | |
# This assumes a problem with communicating to the computer object | |
Write-Verbose -Message $_.Exception.Message | |
} | |
finally | |
{ | |
# output the object regardless of thrown error. | |
[pscustomobject]$outputObject | |
} # try | |
}# foreach | |
}# process | |
}# function |
Thank you for the tips! I'll see if I can incorporate them all and maybe make the code a little cleaner, I appreciate it!
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
3 quick tips:
1: if you name your Gist with a .ps1 extension, it will automatically add syntax highlighting
2: Unless you have a really good reason to, you should never clear the error counter (there are exceptions, certain cmdlets don't throw errors in a way try/catch can use, so you have to get creative). You should capture the error in your catch block and handle it there. Also, setting your error action to "SilentlyContinue" effectively makes your try/catch block useless.
3: You don't need to build a PSSession for this; Get-CimInstance and Get-WmiObject both have a -ComputerName argument that will work just fine and handle the session automatically (no set up or tear down needed)