Many thanks to @Fnilsen80 for his original thread here: https://communities.vmware.com/t5/VMware-PowerCLI-Discussions/Get-VM-with-uptime-reports-incorrect/m...
I'm a complete newbie at using the PowerCLI stuff and after some issues with the syntax, I have it working.
Except it's providing me incorrect values for uptime !
I'm experincing a issue with VMs randomly rebooting and we're still trying to determine what causes these reboot - we currently suspect it might be an issue with ESXi 7.0.3 build 21053776.. Anyway.
In order to pick up these random reboots, I've been looking for a way of obtaining this automatically via a script or otherwise instead of having to log onto each machine individually and run an uptime command.
So in searching here, I came across various threads, some old ones don't appear to work or give the correct values, and the script I'm reusing seems to be the latest one. However, I'm getting massively wrong values.
Here's what I have:
Get-VM |
select Name, @{N="DNSName";E={$_.ExtensionData.Guest.Hostname}}, @{N="FolderName";E={ $_.Folder.Name}},
@{N='FolderPath';E={
$path = $_.Name
$parent = Get-View -Id $_.ExtensionData.Parent
while($parent){
$path = "$($parent.Name)\$path"
if($parent.Parent){
$parent = Get-View -Id $parent.Parent
}
else{
$parent = $null
}
}
$path}},
NumCpu, MemoryGB,
@{N="Up Time";E={$Timespan = New-Timespan -Seconds (Get-Stat -Entity $_.Name -Stat sys.uptime.latest -Realtime -MaxSamples 1).Value
"" + $Timespan.Days + " Days, "+ $Timespan.Hours + " Hours, " +$Timespan.Minutes + " Minutes"}}, Notes | Export-Csv "C:\uptimetest_$((Get-Date).ToString("yyyy-MM-dd")).csv" -NoTypeInformationBut I get really wrong values.
In sorting in the resulting CSV file, I get uptimes of a few hours on certain VMs, yet when I look at them, they've been up for 100+ days.
Am I doing something wrong or is there an issue here?
System is a Nutanix based cluster running VCSA 7.0. build 20990077 with three ESXi nodes, each running v7.0.3 build 21053776
Any thoughts most appreciated!
You can add a Where-clause for that
Get-VM |
Where{$_.PowerState -eq "PoweredOn"} |
select @{N="Cluster";E={Get-Cluster -VM $_}},
@{N="ESX Host";E={Get-VMHost -VM $_}}, Name,
@{N="FolderName";E={ $_.Folder.Name}},
@{N="Up Time";E={
$upTime = (Get-Stat -Entity $_.Name -Stat sys.osuptime.latest -Realtime -MaxSamples 1).Value
$bootTime = (Get-Date).AddSeconds(-$upTime)
$bootTime.ToString("yyyy-MM-dd_HH:mm:ss")
}} |
Export-Csv "C:\VMware\uptime_$((Get-Date).ToString("yyyyMMdd-HHmmss")).csv" -NoTypeInformation
Blog: lucd.info Twitter: @LucD22 Co-author PowerCLI Reference
There is a difference between the Guest OS rebooting and the VM itself restarting.
You might want to look at the system.osuptime.latest metric instead.
Blog: lucd.info Twitter: @LucD22 Co-author PowerCLI Reference
Thanks @LucD , but if the sys.uptime.latest is since the VM was started was system.osuptime.latest is the guest OS then surely the sys.uptime.latest should be greater of the two. Yet I'm still getting minutes for some VMs when the Guest OS hasn't been restarted or the VM itself hasn't been restarted.
I'll experiment with the system.osuptime.latest as well ![]()
Could it be that your VMs are vMotioned around due to DRS?
Blog: lucd.info Twitter: @LucD22 Co-author PowerCLI Reference
Yes, I guess a vMotion resets that kind of clock.
I do have another small request: having the uptime is useful, but in the current format, it makes sorting tricky as it doesn't include leading zeroes.
Is it possible instead of having the uptime, have the actual time/date of the last boot? That would probably be a format in which a spreadsheet can recognise and filter, and it would then be easy to convert that to an uptime.
If you have the uptime in seconds you can use one of the DateTime methods to get the boottime.
For example
(Get-Date).AddSeconds(-$uptime)
Blog: lucd.info Twitter: @LucD22 Co-author PowerCLI Reference
Sorry for the late reply.
Here's what I have:
Get-VM |
select @{N="Cluster";E={Get-Cluster -VM $_}}, @{N="ESX Host";E={Get-VMHost -VM $_}}, Name, @{N="FolderName";E={ $_.Folder.Name}},
@{N="Up Time";E={$Timespan = New-Timespan -Seconds (Get-Stat -Entity $_.Name -Stat sys.osuptime.latest -Realtime -MaxSamples 1).Value
"" + $Timespan.Days + "d "+ $Timespan.Hours + "h " +$Timespan.Minutes + "m"}} | Export-Csv "C:\VMware\uptime_$((Get-Date).ToString("yyyyMMdd-HHmmss")).csv" -NoTypeInformationHow do I modify the $Timespan thing to get the uptime ?
Sorry for the noob question, still trying to get my head around powershell ![]()
Thanks!
Try something like this
Get-VM |
select @{N="Cluster";E={Get-Cluster -VM $_}},
@{N="ESX Host";E={Get-VMHost -VM $_}}, Name,
@{N="FolderName";E={ $_.Folder.Name}},
@{N="Up Time";E={
$now = Get-Date
$upTime = (Get-Stat -Entity $_.Name -Stat sys.osuptime.latest -Realtime -MaxSamples 1).Value
$Timespan = New-Timespan -Start $now.AddSeconds(- $upTime) -End $now
"$($Timespan.Days)d $($Timespan.Hours)h $($Timespan.Minutes)m"
}} |
Export-Csv "C:\VMware\uptime_$((Get-Date).ToString("yyyyMMdd-HHmmss")).csv" -NoTypeInformation
Blog: lucd.info Twitter: @LucD22 Co-author PowerCLI Reference
Thanks @LucD but it still gives me exactly the same thing.
What exactly does it give you?
And what do you want to see?
Blog: lucd.info Twitter: @LucD22 Co-author PowerCLI Reference
It currently gives me an uptime like this:
The problem is it's not possible to sort and filter as it's just "text" so 11d is sorted before 2d for example.
Ideally, if a boot time could be there in a date "format" that's compatible, that would allow sorting, for example a "year-month-day_hour:minute:second", i.e. "2023-06-06_09:12:40" would allow the data to be read as a "date" and then manipulated / sorted as desired. Or maybe just an uptime in seconds (but not in days and hours) that would be an integer allowing easy sorting. Alternatively, if leading zeroes could be inserted for days, hours and minutes, then a sort would be easier.
Failing that, I can do some spreadsheet manipulation to convert those values with formulae within Excel / LibreOffice, but it would be nice if the data could be presented natively in a format already allowing sorting.
If you want the boottime (in any format you desire), you could use the ToString method on a DateTime object.
Like this for example
@{N="Up Time";E={
$upTime = (Get-Stat -Entity $_.Name -Stat sys.osuptime.latest -Realtime -MaxSamples 1).Value
$bootTime = (Get-Date).AddSeconds(-$upTime)
$bootTime.ToString("yyyy-MM-dd_HH:mm:ss")
}} |
Blog: lucd.info Twitter: @LucD22 Co-author PowerCLI Reference
Ooh that seems to work.
Just one minor annoyance, it still lists the boot time for VMs which are powered off. I think the time is the time at which the script obtained info for that VM.
So is it possible to filter so that the generated table only outputs VMs which are powered on, and does not list any VMs that are powered off?
You can add a Where-clause for that
Get-VM |
Where{$_.PowerState -eq "PoweredOn"} |
select @{N="Cluster";E={Get-Cluster -VM $_}},
@{N="ESX Host";E={Get-VMHost -VM $_}}, Name,
@{N="FolderName";E={ $_.Folder.Name}},
@{N="Up Time";E={
$upTime = (Get-Stat -Entity $_.Name -Stat sys.osuptime.latest -Realtime -MaxSamples 1).Value
$bootTime = (Get-Date).AddSeconds(-$upTime)
$bootTime.ToString("yyyy-MM-dd_HH:mm:ss")
}} |
Export-Csv "C:\VMware\uptime_$((Get-Date).ToString("yyyyMMdd-HHmmss")).csv" -NoTypeInformation
Blog: lucd.info Twitter: @LucD22 Co-author PowerCLI Reference
Thank you so much @LucD , I've managed to put something together that works for me! ![]()
