Site icon Grzegorz Kulikowski

When was vm created, how vm was created and who has created this vm ?

who and when created the vm

who and when created the vm

I wanted to know where it is possible, who has created virtual machine. When the virtual machine was created and how it was created.
The idea is very simple. As an input i will take a virtual machine, and the output should be an object with few properties. VM can be created in several ways, right ? So i need to search for different events. When vm is being created/deployed it will create an event for this fact. Those events are as follows:

VmBeingCreatedEvent – Vm is created manually. Right-click New-VM. When we do VM in this way, a second event joins VmRegisteredEvent. So To check for vms there were manually created, we have to browse for events and check if 2 types of events have occured.
VmBeingDeployedEvent – When vm was deployed from template it will make this type of event
VmRegisteredEvent – When vm was registered, for example, open datastore browser, right click on vmx – register.
VmClonedEvent – When vm was cloned.

Since i have already written a function few days ago that queries for events i will use it here. I use Get-VMEvents, to query for specific events types regarding virtual machine object. So first let’s load this function to our powercli environment. Copy/paste this source code into your powershell/powercli/powergui/ise session.

Ok, once we have this loaded we can start actually querying with this function:

Ok, so now we have 2 functions that we can use.
Get-VMEvents that will query for events regarding a VM, and Get-VMCreationdate that uses the first function. There are couple of ways to use it.
The most basic approach i guess will be:

It also gives you a warning when you are querying a vm that does not exist in your infrastructure.

When you will query for a VM that no longer has event information about being created, it will result in sending an object with a vm name and other properties with NoEvent value. It’s up to you then what do in that case. Maybe you want to query Active Directory and check registration there when NoEvent is returned. Maybe you do not have AD in your environment, and you are fine with marking creation date as a date of the oldest event for a virtualmachine. Like i said, its up to you what to do in this case.
All sorts of selecting vms are possible to feed Get-VMCreationdate
get-vm -Location X | …
get-cluster ‘some_cluster’ | …
get-datacenter ‘X’ | …

And of course you can filter information about creation dates for your virtual machines. Let’s say that you have already a report

$vms=get-vm -Location ‘My_folder1’
$report=Get-VMCreationdate -VMnames $vmnames

$report |Where-Object {$_.CreatedMonth -eq “July”} | Select VMname
Would for example output only vm names for vms that where created in July.

$report |Where-Object {$_.Creator -eq “Grzegorz”} | Select VMname
Would for example output only vm names for vms that where created by Grzegorz.

$report |Where-Object {$_.CreationMethod -eq “RegisteredFromVMX”} | Select VMname
Would for example output only vm names for vms that were created using method: Registered from vmx.

$report |Where-Object {$_.CreationMethod -eq “Cloned”} | Select VMname
Would for example output only vm names for vms that were cloned.

If you want to store your report as an CSV there is no problem with that:
$report | Export-csv c:\myreport.csv

You will probably see a lot of vms without any data , i mean they will have NoEvent value. How to fight with that ? If you want to track the creationdate, and have this information always available for virtualmachine, you can for example create an annotation with name : CreatedDate , and you can check your vms once a day to see if a vm does not have this annotation completed. If there is no information in the annotation you can simply use Get-VMCreationdate, to get this information and store i within vm annotation field. If after some months you VC will lose information about creation events, created dated will be still in the annotation. If you have any other ideas about this, write a comment !

What can be done more ? You will notice that command like :
get-vm|get-vmcreationdate
Will take some time. It should take 1.5 second to obtain information for 1 vm. If you have a large infrastructure like 1000,5000, and more vms it will take some time to complete this report. There is a way though to obtain report for ALL vms in your infrastructure in around ~20-30 seconds i believe. Unfortunately i don’t have that much free time to write it. But if you want to try it, please share your work with us in comments or thoughts about this idea.
You can use get-vmevents with -all switch and -types that will indicatate creation of virtual machine.
$creationevents=get-vmevents -all -types ‘VmBeingDeployedEvent’,’VmRegisteredEvent’,’VmClonedEvent’,’VmBeingCreatedEvent’
In order to complete this it will need around 2-3 seconds.
This way of doing this is very quick BUT, it will include information of virtual machines that no longer exists in your infrastructure, so we have to filter these out.
$creationevents array will include events objects that have vm moref property. So you have to store it somewhere.
$morefs=$creationevents|%{$_.vm.vm}
Like this for example
Then you have to compare those morefs with morefs for vms that you actually have in your vc , for example using compare-object.
Once this is done You can now feed get-vmcreationdate with those events that have proper moref property.
When i will have more time i will try this idea out 😉 For now, no time ;(
Big thanks goes to Bartosz Bielawski for helping me out with some parts of the script!