I have created annotations for my VMs called LastPowerOn and LastPowerOff, which I planned to populate with the CreationDate of the event log entry for "VmPoweredOnEvent" and "VmPoweredOffEvent" respectively. Unfortunately, It seems that not all power events in the logs are driven by that event name. In vCenter, I can see power on/off events that are not reflected as such.
After trying my hand at it and coming up short, I borrowed a script written by RvdNieuwendijk, which was designed to parse the VM event logs for exactly this info. That script also resulted in blank info for many servers. So looking at the event log, this event appears to not be reflected as the same as a normal power event:
DRS powered On the virtual machine on
esx1.jeff.com
info
10/28/2011 1:57:25 PM
Power On virtual machine
server100
This is the code I am using to test:
Get-VIEvent -Entity $vm -MaxSamples 500 | Sort-Object -Property CreatedTime -Descending | Where-Object { $_.Gettype().Name -eq "VmPoweredOnEvent" } | Select-Object -First 1
I bumped the MaxSamples up to 500 to see if that was the problem.
I can find the exact event I am looking for:
Template : False
Key : 11657
ChainId : 11651
CreatedTime : 10/28/2011 1:57:25 PM
UserName :
Datacenter : VMware.Vim.DatacenterEventArgument
ComputeResource : VMware.Vim.ComputeResourceEventArgument
Host : VMware.Vim.HostEventArgument
Vm : VMware.Vim.VmEventArgument
Ds :
Net :
Dvs :
FullFormattedMessage : DRS powered On server100 on esx1.jeff.com in
DataCenter1
ChangeTag :
DynamicType :
DynamicProperty :
Any suggestions on where to go from here would be very helpful.
I was thinking about going to the datastore and pulling the last modified date of the vmdk to establish a "rough" power off date.
Thanks,
Jeff
Hi jeff,
thanks for your question. You found a serious flaw in my script from the thread Get a VMs last power off date based on the VM's events.
And thanks to your suggestion it was not difficult for me to change the line:
Where-Object { $_.Gettype().Name -eq "VmPoweredOnEvent" } | `
into:
Where-Object { $_.GetType().Name -eq "VmPoweredOnEvent" -or $_.GetType().Name -eq "DrsVmPoweredOnEvent"} | `
to solve your problem.
While looking again at my previous script, I found two other flaws myself. You can probably say: "age comes with insight".
The most serious one is that the Get-VIEvent cmdlet returns by default only 100 events. This might be too few for some VM's. So I added the MaxSamples parameter with value 10000. Although necessary to make the script run good, it will make the script much slower.
The other minor problem was that the previous script did the Sort-Object cmdlet in the pipeline before the Where-Object cmdlet. It is better to do this the other way round. This is much faster because the Sort-Object cmdlet has to sort fewer records.
Here is the new script will all the changes:
function Get-VMLastPoweredOffDate { param([Parameter(Mandatory=$true,ValueFromPipeline=$true)] [VMware.VimAutomation.ViCore.Impl.V1.Inventory.VirtualMachineImpl] $vm) process { $Report = "" | Select-Object -Property Name,LastPoweredOffDate,UserName $Report.Name = $vm.Name $Event = Get-VIEvent -Entity $vm -MaxSamples 10000 | ` Where-Object { $_.GetType().Name -eq "VmPoweredOffEvent" } | ` Sort-Object -Property CreatedTime -Descending | ` Select-Object -First 1 $Report.LastPoweredOffDate = $Event.CreatedTime $Report.UserName = $Event.UserName $Report } } function Get-VMLastPoweredOnDate { param([Parameter(Mandatory=$true,ValueFromPipeline=$true)] [VMware.VimAutomation.ViCore.Impl.V1.Inventory.VirtualMachineImpl] $vm) process { $Report = "" | Select-Object -Property Name,LastPoweredOnDate,UserName $Report.Name = $vm.Name $Event = Get-VIEvent -Entity $vm -MaxSamples 10000 | ` Where-Object { $_.GetType().Name -eq "VmPoweredOnEvent" -or $_.GetType().Name -eq "DrsVmPoweredOnEvent"} | ` Sort-Object -Property CreatedTime -Descending |` Select-Object -First 1 $Report.LastPoweredOnDate = $Event.CreatedTime $Report.UserName = $Event.UserName $Report } } New-VIProperty -Name LastPoweredOffDate -ObjectType VirtualMachine -Value {(Get-VMLastPoweredOffDate -vm $Args[0]).LastPoweredOffDate} -Force New-VIProperty -Name LastPoweredOffUserName -ObjectType VirtualMachine -Value {(Get-VMLastPoweredOffDate -vm $Args[0]).UserName} -Force New-VIProperty -Name LastPoweredOnDate -ObjectType VirtualMachine -Value {(Get-VMLastPoweredOnDate -vm $Args[0]).LastPoweredOnDate} -Force New-VIProperty -Name LastPoweredOnUserName -ObjectType VirtualMachine -Value {(Get-VMLastPoweredOnDate -vm $Args[0]).UserName} -Force Get-VM | Select-Object -property Name,LastPoweredOnDate,LastPoweredOnUserName,LastPoweredOffDate,LastPoweredOffUserName
Regards, Robert
Message was edited by: RvdNieuwendijk Added the -Force parameter to the New-VIProperty commands.
Hi jeff,
thanks for your question. You found a serious flaw in my script from the thread Get a VMs last power off date based on the VM's events.
And thanks to your suggestion it was not difficult for me to change the line:
Where-Object { $_.Gettype().Name -eq "VmPoweredOnEvent" } | `
into:
Where-Object { $_.GetType().Name -eq "VmPoweredOnEvent" -or $_.GetType().Name -eq "DrsVmPoweredOnEvent"} | `
to solve your problem.
While looking again at my previous script, I found two other flaws myself. You can probably say: "age comes with insight".
The most serious one is that the Get-VIEvent cmdlet returns by default only 100 events. This might be too few for some VM's. So I added the MaxSamples parameter with value 10000. Although necessary to make the script run good, it will make the script much slower.
The other minor problem was that the previous script did the Sort-Object cmdlet in the pipeline before the Where-Object cmdlet. It is better to do this the other way round. This is much faster because the Sort-Object cmdlet has to sort fewer records.
Here is the new script will all the changes:
function Get-VMLastPoweredOffDate { param([Parameter(Mandatory=$true,ValueFromPipeline=$true)] [VMware.VimAutomation.ViCore.Impl.V1.Inventory.VirtualMachineImpl] $vm) process { $Report = "" | Select-Object -Property Name,LastPoweredOffDate,UserName $Report.Name = $vm.Name $Event = Get-VIEvent -Entity $vm -MaxSamples 10000 | ` Where-Object { $_.GetType().Name -eq "VmPoweredOffEvent" } | ` Sort-Object -Property CreatedTime -Descending | ` Select-Object -First 1 $Report.LastPoweredOffDate = $Event.CreatedTime $Report.UserName = $Event.UserName $Report } } function Get-VMLastPoweredOnDate { param([Parameter(Mandatory=$true,ValueFromPipeline=$true)] [VMware.VimAutomation.ViCore.Impl.V1.Inventory.VirtualMachineImpl] $vm) process { $Report = "" | Select-Object -Property Name,LastPoweredOnDate,UserName $Report.Name = $vm.Name $Event = Get-VIEvent -Entity $vm -MaxSamples 10000 | ` Where-Object { $_.GetType().Name -eq "VmPoweredOnEvent" -or $_.GetType().Name -eq "DrsVmPoweredOnEvent"} | ` Sort-Object -Property CreatedTime -Descending |` Select-Object -First 1 $Report.LastPoweredOnDate = $Event.CreatedTime $Report.UserName = $Event.UserName $Report } } New-VIProperty -Name LastPoweredOffDate -ObjectType VirtualMachine -Value {(Get-VMLastPoweredOffDate -vm $Args[0]).LastPoweredOffDate} -Force New-VIProperty -Name LastPoweredOffUserName -ObjectType VirtualMachine -Value {(Get-VMLastPoweredOffDate -vm $Args[0]).UserName} -Force New-VIProperty -Name LastPoweredOnDate -ObjectType VirtualMachine -Value {(Get-VMLastPoweredOnDate -vm $Args[0]).LastPoweredOnDate} -Force New-VIProperty -Name LastPoweredOnUserName -ObjectType VirtualMachine -Value {(Get-VMLastPoweredOnDate -vm $Args[0]).UserName} -Force Get-VM | Select-Object -property Name,LastPoweredOnDate,LastPoweredOnUserName,LastPoweredOffDate,LastPoweredOffUserName
Regards, Robert
Message was edited by: RvdNieuwendijk Added the -Force parameter to the New-VIProperty commands.
That worked perfectly for the DRS Power event! Thanks Robert!
Jeff
i tried with
-MaxSamples ([int]::MaxValue)
but i could not get LastPoweredOffUserName tho i got LastPoweredOffDate
Please suggest.