I have been way too active on this forum lately and have learned more than I really have a right too thanks to my peers and the Guru LucD. My new problem, which I have experimented with in a 100 ways and taxed my Google-Fu to the limits and have failed. I have a wonderful report that I am tasked with running monthly for the Windows/Linux engineering team. I have recently been converting it get-view as opposed to the original of get-vm to increase the performance. A full run of get-vm took nearly 6 hours while the get-view takes under 2 hours. I have had to change some of the results but no big deal. I am setting a version with menus for ad-hoc runs and that works great but want to add some flare. I need to get into the OS and report on actual OS uptime since VM uptime is pretty much vanity and just makes the VM engineers look good and the OS guys bad. I also want to break down the last WSUS updates in a view. I have many snippets of code that work for each but I can't get them to work in the @{N='xxx';E={} format. I am looking for help.
Get-HotFix -ComputerName 'dc2' -Credential $ADcreds |?{$_.InstalledOn -gt ((Get-Date).AddDays(-60))}
Returns
Source | Description | HotFixID | InstalledBy | InstalledOn |
------ | ----------- | -------- | ----------- | ----------- |
DC2 | Security Update | KB4516044 | NT AUTHORITY\SYSTEM | 9/22/2019 12:00:00 AM |
Get-View -ViewType VirtualMachine -Filter @{'Runtime.PowerState'='poweredOn'} |
Select -First 5 Name,
@{N='Last WSUS Security Update';E={
Get-HotFix -ComputerName ($_) -Credential $ADcreds |?{$_.InstalledOn -gt ((Get-Date).AddDays(-90))} | Select-Object -ExpandProperty Description | Where-Object {$_.Description -eq 'Security Update'} | select -First 1}},
@{N='Last WSUS Update Date';E={
Get-HotFix -ComputerName ($_) -Credential $ADcreds |?{$_.InstalledOn -gt ((Get-Date).AddDays(-90))} | Select-Object -ExpandProperty InstalledOn | select -First 1}}
Returns blanks, I have tried very various combos for the -ComputerName $_.id, tried foreach($vm in $vms), tried get-view virtual machine in a variable, etc...
As far as the UPTIME goes. I have pulled threads from tons of sources including the get-uptime:
#No Worky
@{N='Uptime (d.hh:mm:ss)';E={
Get-WmiObject win32_operatingsystem -ComputerName $_.id -Credential $ADcreds | select $_.ConverttoDateTime($_.lastbootuptime)}
}
#No Worky
@{N='Uptime (d.hh:mm:ss)';E={
Invoke-Command -Credential $ADcreds -ScriptBlock {
New-TimeSpan -Start (Get-Date) -End (
[System.Management.ManagementDateTimeConverter]::ToDateTime(
(Get-WmiObject -Class Win32_OperatingSystem).LastBootUpTime
)
)
}
}
}
#No Worky
@{N='Uptime (d.hh:mm:ss)';E={
Get-Stat -Entity ($_) -Realtime -MaxSamples 1 -stat sys.osuptime.latest -ErrorAction SilentlyContinue -f [timespan]::FromSeconds($_.value)}}
#No Worky
@{N='Uptime (d.hh:mm:ss)';E={
$Servers = Get-ADComputer -Filter {(OperatingSystem -like "*Server*") -and (Enabled -eq $true)} -Properties OperatingSystem | select -ExpandProperty Name | Sort-Object
#$Servers = (Get-View -id $_.id) -and (Get-ADComputer -Filter {(OperatingSystem -like "*Server*") -and (Enabled -eq $true))} -Properties OperatingSystem | select -ExpandProperty Name | Sort-Object
$Servers = Get-Uptime -computerName $Servers -credential $ADcreds | select LastBootTime
$Servers
}
}
#No Worky
@{N='Uptime (d.hh:mm:ss)';E={
$stat = 'sys.osuptime.latest'
$vms = Get-VM
Get-Stat -Entity $vms -Stat $stat -Realtime -MaxSamples 1
$date.AddSeconds(- $_.Value)}}
Help Please!!
You could do something like this
select @{N='VM';E={$_.Name}},
@{N='Uptime';E={
$stat = Get-Stat -Entity $_.Name -Realtime -MaxSamples 1 -Stat 'sys.osuptime.latest' -ErrorAction SilentlyContinue
$duration = New-TimeSpan -Seconds $stat.Value
"{0} days, {1} hours, {2} minutes" -f $duration.days,$duration.Hours,$duration.Minutes
}}
Blog: lucd.info Twitter: @LucD22 Co-author PowerCLI Reference
For the patch question, can you try the following?
Note that I changed Description to HotFixId, because Description most of the time just says 'Update' or 'SecurityUpdate'
Select -First 5 -Property Name,
@{N='Last WSUS Security Update';E={
$script:fix = Get-HotFix -ComputerName $_.Name -Credential $ADcreds |
Sort-Object -Property InstalledOn -Descending
$script:fix | where{$_.InstalledOn -gt ((Get-Date).AddDays(-90)) -and $_.Description -eq 'Security Update'} |
Select-Object -First 1 -ExpandProperty HotFixId}},
@{N='Last WSUS Update Date';E={
$script:fix | where{$_.InstalledOn -gt ((Get-Date).AddDays(-90))} |
Select-Object -First 1 -ExpandProperty InstalledOn}}
For the uptime, the sys.osuptime.latest works for me.
Like this for example
select @{N='VM';E={$_.Entity.Name}},
@{N='Uptime';E={
$duration = New-TimeSpan -Seconds $_.Value
"{0} days, {1} hours, {2} minutes" -f $duration.days,$duration.Hours,$duration.Minutes
}}
Blog: lucd.info Twitter: @LucD22 Co-author PowerCLI Reference
Thanks LucD!!
So the next question is how to format the Uptime into the rest of the script that uses the get-view command.
You could do something like this
select @{N='VM';E={$_.Name}},
@{N='Uptime';E={
$stat = Get-Stat -Entity $_.Name -Realtime -MaxSamples 1 -Stat 'sys.osuptime.latest' -ErrorAction SilentlyContinue
$duration = New-TimeSpan -Seconds $stat.Value
"{0} days, {1} hours, {2} minutes" -f $duration.days,$duration.Hours,$duration.Minutes
}}
Blog: lucd.info Twitter: @LucD22 Co-author PowerCLI Reference
You are truly amazing. Thank you for your help.