Home > event, PowerCLI, PowerShell, vSphere > Events – Part 4 : Who started that VM ?

Events – Part 4 : Who started that VM ?

December 20th, 2009 Leave a comment Go to comments

In a comment on my Events – Part 3 : Auditing VM device changes post, Ian asked if it was possible to report who started a VM.

To take away the suspense, yes that can be done by using the information from two of my earlier post.

Poweredon-report

Since I considered it a bit too long to give the solution in a comment, this post.

Logic

First you will have to find which event(s) to use for a power on of a guest. For that use the CSV file of all events that I blogged about in Events, Dear Boy, Events – Part 2.

It’s obvious that you will need the VmPoweredOnEvent.

VMpoweredonEvent
The first script in Events: a great source of information – Part 1 shows how to get at the user information in the event object via the userName property.

The scripts

First the script with only PowerCLI cmdlets.
Turns out we can do this with a one-liner !

Get-VIEvent -Start (Get-Date).adddays(-10) | `
	where {$_.gettype().Name -eq "VmPoweredOnEvent" -and $_.CreatedTime -lt (Get-Date).adddays(-30)} | `
	select @{N="VMname"; E={$_.Vm.Name}},
		@{N="CreatedTime"; E={$_.CreatedTime}},
		@{N="Host"; E={$_.Host.Name}},
		@{N="User"; E={$_.UserName}} | `
	Export-Csv "C:\VM-powerod-audit.csv" -NoTypeInformation -UseCulture

Annotation

Line 1: The Where-Object (alias ‘where’) cmdlet only passes the events we’re interested in

The second version of the script uses the event collector methods as described in Events: a great source of information – Part 1 (second script in that post).

$days = 7
$eventnumber = 1000

$report = @()

$serviceInstance = get-view ServiceInstance
$eventMgr = Get-View eventManager

if($eventMgr.Client.Version -eq "Vim4" -and $eventnumber -gt 1000){
	Write-Host "Sorry, API 4.0 only allows a maximum event window of 1000 entries!" -foregroundcolor red
	Write-Host "Please set the variable `$eventnumber to 1000 or less" -foregroundcolor red
	exit
}

$efilter = New-Object VMware.Vim.EventFilterSpec
$efilter.time = New-Object VMware.Vim.EventFilterSpecByTime
$efilter.time.beginTime = (Get-Date).Adddays(- $days)
$efilter.time.endtime = (Get-Date)

$ecollectionImpl = Get-View ($eventMgr.CreateCollectorForEvents($efilter))
$ecollection = $ecollectionImpl.ReadNextEvents($eventnumber)
while($ecollection -ne $null){
	foreach($event in $ecollection){
		switch($event.GetType()){
			"VMware.Vim.VmPoweredOnEvent" {
				$report += New-Object PSObject -Property @{
					VMname = $event.Vm.Name
					CreatedTime = $event.CreatedTimE
					Host = $event.Host.Name
					User = $event.UserName
				}
			}
		}
	}
	$ecollection = $ecollectionImpl.ReadNextEvents($eventnumber)
}
$ecollectionImpl.DestroyCollector()

$report | Export-Csv "C:\VM-poweredon-audit-fast.csv" -NoTypeInformation -UseCulture

Annotation

Line 9-13: VIM 4.0 has a limitation in the number of events.
Line 26-31: this way of building an object is new to PowerShell v2
Line 37: you can have a maximum of 32 event collectors in your session. So clean up !

Result

Both scripts produce a CSV file that gives all the information we’re after. See the first screenshot in this post.
The difference is in the execution time, the 2nd script ran nearly 35 times faster than the first script in my test environment. Quite important if you have to go back far in time or if you are auditing a big environment !

You can use any of the above scripts as skeletons to hunt for other audit information. Just plug in the event(s) you’re after ;-)

A personal reflection, it would be useful that in a future PowerCLI build, the Get-VIEvent cmdlet would have a ‘filter‘ parameter. That would get rid of the Where-Object cmdlet through which we now have to pipe all the events.

  1. Skywalker
    May 24th, 2010 at 05:00 | #1

    @LucD
    Thanks much, Luc!

  2. Skywalker
    May 21st, 2010 at 09:19 | #2

    Hi Luc,
    Is it possible to monitor manual migration event and have username (who), starttime, state, vm name, from, to displayed? I saw a script from you, which tracks DRS. Thanks again!

    • May 21st, 2010 at 14:37 | #3

      That shouldn’t be too difficult.
      If you replace the code inside the switch statement (lines 25-32) by the following code, you should get a report on the vMotions.

      "VMware.Vim.VmRelocatedEvent"{
      $report += New-Object PSObject -Property @{
      VMname = $event.Vm.Name
      CreatedTime = $event.CreatedTimE
      From = $event.SourceHost.Name
      To = $event.Host.Name
      User = $event.UserName
      State = $event.FullFormattedMessage
      }
      }

      I suspect that you can test on the presence of the User property to determine if it was a manual vMotion or one triggered by the system (DRS).
      Luc.

  3. December 20th, 2009 at 14:50 | #4

    Good stuff! I did a similar post a bit back: http://professionalvmware.com/2009/10/a-quick-powercli-lesson-digging-for-info-who-powered-off-that-vm/ Love the performance improvements tho… 35x is HUGE!

    • December 20th, 2009 at 16:02 | #5

      That is indeed a great post you did Cody.
      Wouldn’t have done this one, if it wasn’t for the performance difference between the two methods.

  1. December 20th, 2009 at 13:45 | #1