VMware Cloud Community
denovojeff
Contributor
Contributor
Jump to solution

VM Power Off Date

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

1 Solution

Accepted Solutions
RvdNieuwendijk
Leadership
Leadership
Jump to solution

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. Smiley Wink

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". Smiley Wink

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.

Blog: https://rvdnieuwendijk.com/ | Twitter: @rvdnieuwendijk | Author of: https://www.packtpub.com/virtualization-and-cloud/learning-powercli-second-edition

View solution in original post

3 Replies
RvdNieuwendijk
Leadership
Leadership
Jump to solution

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. Smiley Wink

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". Smiley Wink

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.

Blog: https://rvdnieuwendijk.com/ | Twitter: @rvdnieuwendijk | Author of: https://www.packtpub.com/virtualization-and-cloud/learning-powercli-second-edition
denovojeff
Contributor
Contributor
Jump to solution

That worked perfectly for the DRS Power event!  Thanks Robert!

Jeff

Reply
0 Kudos
esxi1979
Expert
Expert
Jump to solution

i tried with

-MaxSamples ([int]::MaxValue)

but i could not get  LastPoweredOffUserName tho i got LastPoweredOffDate

Please suggest.

Reply
0 Kudos