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

by Grzegorz Kulikowski
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!

You may also like

24 comments

vanzerhous February 21, 2013 - 9:16 pm

Brilliant! Thank you!

Reply
p3opl3sh3ro March 19, 2013 - 5:21 pm

I am having a difficult time trying to figure out how to use this information. I want to be able to run a report for all creation methods and have it go to a file so that I can sort. It looks like I am after the 2nd function you have shown. I have loaded it, but am having trouble going from there. How do I actually run the report needed and save the output?

Reply
psvmware March 27, 2013 - 2:34 pm

Hi, can you let me know what is wrong ? It’s not clear for me what is not working. Post includes information how to invoke report and save it to file.

Reply
p3opl3sh3ro March 27, 2013 - 8:44 pm

I actually created some SQL queries instead and have them available to my team via SSRS. Thank you.

Reply
Anonymous August 22, 2013 - 3:17 pm

Awesome !! Thx a lot

Reply
Rob October 16, 2013 - 4:31 pm

Love your script! Question though, when I run it, it shows me the original name of the VM, not the current name.

EG,

Machine42_NEW 10/1/2013 18:27 October Cloned Durdle

I used

$report=get-vm|get-vmcreationdate
$report | export-csv x:\report.csv

Reply
Rob October 16, 2013 - 4:32 pm

to Clarify, the ‘real’ name of that machine would be WebServer42, as that I renamed it months ago.

Reply
psvmware October 21, 2013 - 5:37 pm

Hi Rob, thanks for comments. To be honest i was not thinking about this possibility. Like you wrote, this will be his default behaviour in returning the names due to the fact that vm name is being collected from event from the past.
If you would like to get name not from the event but the current vm, please look at line 113 in this script.
$ReportedVM.VMname=$CollectedEvent.vm.Name
Please change this line to
$ReportedVM.VMname=$vm.name

i think that will help.

Reply
Scotty November 26, 2013 - 6:26 pm

Hi good job. Exactly what i was looking for.

But don’t work in my case 🙁
vSphere is running version 4.1

>get-vm Vm-test |get-vmcreationdate
VMname : Vm-test
CreatedTime : NoEvent
CreatedMonth : NoEvent
CreationMethod : NoEvent
Creator : NoEvent

Any Idea ?

Reply
Anonymous February 19, 2014 - 6:09 pm

Doubting you’re still looking for info on the NoEvent after all this time, but from what I can tell, that comes up if the VM is really old.

Reply
psvmware February 19, 2014 - 7:53 pm

That is correct. If we would like to keep events/tasks for longer period of time we would have to change te virtual center database retention policy as described in documentation https://pubs.vmware.com/vsphere-51/index.jsp?topic=%2Fcom.vmware.vsphere.vcenterhost.doc%2FGUID-DD999601-2F41-498D-A577-DDC7C06648EE.html

Reply
wojcieh February 20, 2014 - 5:10 pm

Hi Greg,

Excellent work. I was able to find when VM was created. I checked script against VMware ESX 4.1 U3 and VMware ESXi 5.1 & 5.5

Best Regards
Wojciech

Reply
Find when Virtual Machine was created using SQL query | w o j c i e h . n e t February 20, 2014 - 11:05 pm

[…] if it is possible to find when virtual machine was created and by who. I found great post on Grzegorz blog. I tested it and it works from ESX 4.1 U3 up to ESXi […]

Reply
JB April 22, 2014 - 12:31 am

Greg, I have this error when load the function Get-VMEvents. Appreciate if someone can guide me through it.

The ‘<' operator is reserved for future use.
At line:60 char:36
+ $EventFilterSpec = New-Object < <<<VMware.Vim.EventFilterSpec
+ CategoryInfo : ParserError: ( if ($VM){
>> $EventFilterSpec.Entity = New-Object VMware.Vim.EventFilterSpecByEntity
>> switch ($VM) {
>> {$_ -is [VMware.Vim.VirtualMachine]} {$VMmoref=$vm.moref}
>> {$_ -is [VMware.VimAutomation.ViCore.Impl.V1.Inventory.VirtualMachineImpl
]}{$VMmoref=$vm.Extensiondata.moref}
>> default {$vmmoref=(get-view -ViewType virtualmachine -Filter @{‘name’=$VM}).moref }
>> }
>> $EventFilterSpec.Entity.Entity = $vmmoref
>> $em.QueryEvents($EventFilterSpec)
>> }
>> if ($All) {
>> $em.QueryEvents($EventFilterSpec)
>> }
>> }
>>
The ‘<' operator is reserved for future use.
At line:2 char:43
+ $EventFilterSpec.Entity = New-Object < <<<VMware.Vim.EventFilterSpecByEntity
+ CategoryInfo : ParserError: (<:OperatorToken) [], ParentContainsErrorRecordException
+ FullyQualifiedErrorId : RedirectionNotSupported

Reply
psvmware April 22, 2014 - 7:32 am

could you please paste what you are trying to load in powershell ? I think either you have added something somewhere, or you are pasting it with some special characters maybe. When i copy/paste what is in the post i got no errors. Would be best if you would just paste on some pastebin, the code you are trying to execute.

Reply
JB April 22, 2014 - 8:35 pm

Thank you for reply. I copy and paste the whole function, got error then I took out the comment & examples part and got the same error. I used 3 different machines to load the same function and got the same error. Here is the shorter version of the function
===============================================
PS C:\MyPS> function Get-VMEvents {
>> param(
>> [Parameter(ValueFromPipeline=$true)]
>> [ValidatenotNullOrEmpty()]
>> $VM,
>> [String[]]$types,
>> [string]$category,
>> [switch]$All
>> )
>> $si=get-view ServiceInstance
>> $em= get-view $si.Content.EventManager
>> $EventFilterSpec = New-Object VMware.Vim.EventFilterSpec
>> $EventFilterSpec.Type = $types
>> if($category){
>> $EventFilterSpec.Category = $category
>> }
>>
The ‘<' operator is reserved for future use.
At line:12 char:36
+ $EventFilterSpec = New-Object < <<<VMware.Vim.EventFilterSpec
+ CategoryInfo : ParserError: ( if ($VM){
>> $EventFilterSpec.Entity = New-Object VMware.Vim.EventFilterSpecByEntity
>> switch ($VM) {
>> {$_ -is [VMware.Vim.VirtualMachine]} {$VMmoref=$vm.moref}
>> {$_ -is [VMware.VimAutomation.ViCore.Impl.V1.Inventory.VirtualMachineImpl
]}{$VMmoref=$vm.Extensiondata.moref}
>> default {$vmmoref=(get-view -ViewType virtualmachine -Filter @{‘name’=$VM}).moref }
>> }
>> $EventFilterSpec.Entity.Entity = $vmmoref
>> $em.QueryEvents($EventFilterSpec)
>> }
>> if ($All) {
>> $em.QueryEvents($EventFilterSpec)
>> }
>> }
>>
The ‘<' operator is reserved for future use.
At line:2 char:43
+ $EventFilterSpec.Entity = New-Object < <<<VMware.Vim.EventFilterSpecByEntity
+ CategoryInfo : ParserError: (<:OperatorToken) [], ParentContainsErrorRecordException
+ FullyQualifiedErrorId : RedirectionNotSupported

Reply
psvmware April 23, 2014 - 6:56 am

JB. you are not pasting the function you are trying to load. You are pasting some fragment of function + error output. Can you please just paste the entire script you are trying to load on some pastebin ?

Reply
JB April 23, 2014 - 4:57 pm

Sorry, I misunderstood.
==========================================================
function Get-VMEvents {
param(
[Parameter(ValueFromPipeline=$true)]
[ValidatenotNullOrEmpty()]
$VM,
[String[]]$types,
[string]$category,
[switch]$All
)
$si=get-view ServiceInstance
$em= get-view $si.Content.EventManager
$EventFilterSpec = New-Object VMware.Vim.EventFilterSpec
$EventFilterSpec.Type = $types
if($category){
$EventFilterSpec.Category = $category
}

if ($VM){
$EventFilterSpec.Entity = New-Object VMware.Vim.EventFilterSpecByEntity
switch ($VM) {
{$_ -is [VMware.Vim.VirtualMachine]} {$VMmoref=$vm.moref}
{$_ -is [VMware.VimAutomation.ViCore.Impl.V1.Inventory.VirtualMachineImpl]}{$VMmoref=$vm.Extensiondata.moref}
default {$vmmoref=(get-view -ViewType virtualmachine -Filter @{‘name’=$VM}).moref }
}
$EventFilterSpec.Entity.Entity = $vmmoref
$em.QueryEvents($EventFilterSpec)
}
if ($All) {
$em.QueryEvents($EventFilterSpec)
}
}

Reply
JB April 23, 2014 - 8:39 pm

I found the issue. I just need to remove all and from both functions. Appreciate your responses and many thanks to creator.

Reply
BravoDelta June 2, 2014 - 10:35 pm

This is superballs! Did exactly what I needed it to do, thanks so much!

Reply
psvmware June 3, 2014 - 8:29 am

you are welcome 😉

Reply
Nicholas Ferguson December 4, 2014 - 12:14 am

Great scripts! Thank you so very much.

Reply
Jody January 17, 2018 - 11:35 pm

Why in the hell should we have to do all of this heavy scripting to get a creation date for a VM? How in the hell is it that VMWare doesn’t simply have this in a VM’s summary? Typical half-ass engineering from half-ass VMWare. Ludicrous…

Reply

Leave a Reply

Chinese (Simplified)EnglishFrenchGermanHindiPolishSpanish