I found this script to produce uptime on a computer. The original script starts at the “Function Get-Uptime {” line and the original $ComputerName variable was set to $ENV:ComputerName.
The script works but I want to process a list of computers. That’s why I changed the $ComputerName variable to $Server and added the first three lines (including the “{” and a final “}”.
The script processes but only displays the last name in my list. It is not processing all the names in my list. How can I get it to process a list instead of just one machine?
$Servers=Get-Content C:\temp\ServersTest.txt
ForEach ($Server in $Servers)
{
Function Get-Uptime {
[CmdLetBinding()]
Param(
[Parameter(ValueFromPipeline = $True, ValueFromPipelineByPropertyName = $True)]
[ValidateNotNullOrEmpty()]
[String]$ComputerName = $Server,
[Int32]$Days = 41,
[Switch]$Ping
)
Begin {
$StartUpID = 6005
$ShutDownID = 6006
$StartingDate = (Get-Date).Date.AddDays(-$Days)
}
Process {
If ($Ping) {
$PingResult = Test-Connection $ComputerName -Quiet -Count 1
} Else {
# Fabricate success, we're not running this test
$PingResult = $True
}
Try {
$EventLogData = Get-EventLog -LogName System -After $startingDate -Source EventLog -EntryType Information -ComputerName $ComputerName |
Where-Object { $_.EventID -eq $StartUpID -Or $_.EventID -eq $ShutDownID }
} Catch { }
# If the previous command was successful (we didn't catch an exception) and $PingResult is true (see the note above about use)
If ($? -And $PingResult) {
# Initialise the counters
$Uptime = [TimeSpan]0; $DownTime = [TimeSpan]0
# To speed up execution or it'll enumerate this collection every time it loops
$Count = $EventLogData.Count
# The data should be sorted, but we should not assume that all values are correctly paired
For ($i = 0; $i -lt $Count; $i++) {
If ($EventLogData[$i].EventID -eq $StartUpID -And $EventLogData[$i + 1].EventID -eq $ShutDownID) {
# This is the critical one, sum up all downtime intervals
$Downtime += New-TimeSpan $EventLogData[$i + 1].TimeGenerated $EventLogData[$i].TimeGenerated
} ElseIf ($EventLogData[$i].EventID -eq $ShutDownID -And $EventLogData[$i + 1].EventID -eq $StartUpID) {
# Record this, even if it's not used for calculations.
$Uptime += New-TimeSpan $EventLogData[$i + 1].TimeGenerated $EventLogData[$i].TimeGenerated
} Else {
Write-Debug "Could not correlate index $i"
}
}
# Notes on properties:
# Uptime - An assumed value. Uptime is assumed to be $Days minus any explicit downtime intervals
# RecordedUptime - Here for information only, not used in calculations as a server that is up all the
# time will have no RecodedUptime in the given period.
# Downtime - From above
# Percentage - A calculation based on 100% uptime minus each downtime interval
"" | Select-Object `
@{n='ComputerName';e={ $ComputerName }},
@{n='Status';e={ "OK" }},
@{n='Uptime';e={ (New-TimeSpan -Days $Days) - $DownTime }},
@{n='RecordedUptime';e={ $Uptime }},
@{n='Downtime';e={ $Downtime }},
@{n='Percentage';e={ '{0:P2}' -f (1 - $Downtime.Ticks / (New-TimeSpan -Days $Days).Ticks) }}
} Else {
# Create a simple return object
"" | Select-Object `
@{n='ComputerName';e={ $ComputerName }},
@{n='Status';e={ If (!$PingResult) { "Ping failed" } Else { $Error[0].Exception.Message.Trim() } }},
Uptime, RecordedUptime, Downtime, Percentage
}
}
}
}