Who created that VM ?

I was asked whilst on a customer site to work out who had created a VM, this is a common question in most environments where admin rights are the normal and creating a VM is as easy as creating a new word document.

After trawling through the logs for a couple of minutes I found the creator and told the customer, easy enough I guess but how could we make this easier ?

The answer to that question will be no surprise to most readers of this blog….. PowerCLI !

With a quick script and resolving the user account in AD, I was able to add a custom field to each VM letting me know who created the VM and when it was created, all displayed in the annotations of each VM as seen below:

image

Connect-VIServer MYVISERVER
# Uncomment the next line to test this script and tell you what it would do !
# $WhatIfPreference = $true
if (-not (Get-PSSnapin VMware.VimAutomation.Core -ErrorAction SilentlyContinue)) {
	Add-PSSnapin VMware.VimAutomation.Core
}
if (-not (Get-PSSnapin Quest.ActiveRoles.ADManagement -ErrorAction SilentlyContinue)) {
	Add-PSSnapin Quest.ActiveRoles.ADManagement
}

$VMs = Get-VM | Sort Name
$VM = $VMs | Select -First 1
If (-not $vm.CustomFields.ContainsKey("CreatedBy")) {
	Write-Host "Creating CreatedBy Custom field for all VM's"
	New-CustomAttribute -TargetType VirtualMachine -Name CreatedBy | Out-Null
}
If (-not $vm.CustomFields.ContainsKey("CreatedOn")) {
	Write-Host "Creating CreatedOn Custom field for all VM's"
	New-CustomAttribute -TargetType VirtualMachine -Name CreatedOn | Out-Null
}
Foreach ($VM in $VMs){
	If ($vm.CustomFields["CreatedBy"] -eq $null -or $vm.CustomFields["CreatedBy"] -eq ""){
		Write-Host "Finding creator for $vm"
		$Event = $VM | Get-VIEvent -Types Info | Where { $_.Gettype().Name -eq "VmBeingDeployedEvent" -or $_.Gettype().Name -eq "VmCreatedEvent" -or $_.Gettype().Name -eq "VmRegisteredEvent" -or $_.Gettype().Name -eq "VmClonedEvent"}
		If (($Event | Measure-Object).Count -eq 0){
			$User = "Unknown"
			$Created = "Unknown"
		} Else {
			If ($Event.Username -eq "" -or $Event.Username -eq $null) {
				$User = "Unknown"
			} Else {
				$User = (Get-QADUser -Identity $Event.Username).DisplayName
				if ($User -eq $null -or $User -eq ""){
					$User = $Event.Username
				}
				$Created = $Event.CreatedTime
			}
		}
		Write "Adding info to $($VM.Name)"
		Write-Host -ForegroundColor Yellow "CreatedBy $User"
		$VM | Set-CustomField -Name "CreatedBy" -Value $User | Out-Null
		Write-Host -ForegroundColor Yellow "CreatedOn $Created"
		$VM | Set-CustomField -Name "CreatedOn" -Value $Created | Out-Null
	}
}

The script is fairly straight forward, a few caveats are worth mentioning though:

  • This script uses the Quest AD cmdlets to resolve the username in AD, if you don’t have these installed then you can either install them or use the Microsoft AD cmdelts or I have a small function which will do the same thing, I previously used this here.
  • This may take a long time if the VM was created a long time ago as unfortunately the Get-VIEvent cmdlet does not have a way to start from the beginning of the events so I need to retrieve all events for that VM and then filter on them.
  • If the VM’s were removed from the virtual center and then re-added it will have the name of the person who re-imported or added the VM, not the original creator.

Once we have the information added to the VM’s we can of course do some cool reporting, like who created the VM’s:

Get-VM | Select Name -ExpandProperty CustomFields | Where {$_.key -eq "CreatedBy"} | Out-GridView

image

Or even who created the most VMs:

Get-VM | Select Name -ExpandProperty CustomFields | Where {$_.key -eq "CreatedBy"} | Group-Object | Select Count, Name | Sort Count -Descending |Out-GridView 

image

47 thoughts on “Who created that VM ?

  1. Zymos

    Not sure if my PowerCLI is broken, running v6.3 but Set-CustomField seems unavailable. A workaround is to change to use Set-Annotation instead.

    Write-Host -ForegroundColor Yellow “CreatedBy $User”
    $VM | Set-Annotation -CustomAttribute “CreatedBy” -Value $User | Out-Null
    }
    else {
    Write-Host -ForegroundColor Yellow “CreatedBy $User”
    $VM | Set-Annotation -CustomAttribute “CreatedBy” -Value $User | Out-Null

    /Z

  2. Jody (@JodyJodystewart)

    You have to use a script to find out who built a VM?? Why was VMWare too lazy to develop an option of putting that in the logs. This is something that should be in the Event Logs. This should not require using a Powershell script. What type of crap is this?? Unprofessional garbage…

  3. Pingback: Who created all these VMs? | VirtualDataCave

  4. Clifton Gerald

    This script rocks my only issue seems to be its only pulling data that is extremely recent, meaning today. so if a machine is created today it finds its and populates correctly but if the machine was created yesterday or later it doesn’t find it.

    am i doing something wrong or not editing a field i don’t see?

  5. JT

    Is there a newer version of this that uses tags instead of custom attributes? It looks like it may be simple to change it over if you are good with programming – which I’m not…

  6. Roger

    Custom Fields are not the recommended way to do things these days.
    Here is a version of the script using Tags.
    It’s a cleanup of another script I have in production and this script is not tested in any way.
    The script stores only who created the VM not when. I didn’t need it at the time of writing and it’s trivial to add. 🙂
    I only needed the login name without the domain component so no check against AD.
    If you need the full name of the user you can easily do it with the Active Directory Module.
    Example: $user=(Get-ADUser ).Name

    Connect-VIServer MYVISERVER

    # Uncomment the next line to test this script and tell you what it would do !
    # $WhatIfPreference = $true
    if (-not (Get-PSSnapin VMware.VimAutomation.Core -ErrorAction SilentlyContinue)) {
    Add-PSSnapin VMware.VimAutomation.Core
    }

    try
    {
    $category=Get-TagCategory -Name “Created by” -ea stop
    }
    catch
    {
    Write-Host “Creating Tag Category: Created by”
    New-TagCategory -Name “Created by” -Description “Tags with those who created the objects” -Cardinality “Single” -EntityType “VirtualMachine”
    }

    $VMs = Get-VM | Sort Name
    $VM = $VMs | Select -First 1

    Foreach ($VM in $VMs){
    $Event = $VM | Get-VIEvent -Types Info | Where { $_.Gettype().Name -eq “VmBeingDeployedEvent” -or $_.Gettype().Name -eq “VmCreatedEvent” -or $_.Gettype().Name -eq “VmClonedEvent” -or $_.Gettype().Name -eq “VmRegisteredEvent”}
    if(($Event | Measure-Object).Count -eq 0)
    {
    $user=”Unknown”
    $desc=”No information about user found”
    }
    else
    {
    if($Event.Username -eq “” -or $Event.Username -eq $null)
    {
    $user=”Unknown”
    $desc=”No information about user found”
    }
    else
    {
    $user=($Event.Username -split “\\”)[1]
    $desc=”Who created the object”
    }
    }

    $tag=$null
    try
    {
    $tag=Get-Tag -Name $user -Category “Created by” -ea stop
    }
    catch
    {
    Write-Host “Creating Tag $($user)”
    $tag=New-Tag -Name $user -Category “Created by” -Description $desc
    }

    $tags=$vm | get-TagAssignment

    $hastag=$false
    if($tags -ne $null)
    {
    foreach($t in $tags.Tag)
    {
    if($t.Category.Name -eq “Created by”)
    {
    $hastag=$true
    }
    }

    }

    if(-not $hastag)
    {
    try
    {
    Write-Host “Assigning $($tag.Name)”
    $tmp=New-TagAssignMent -Tag $tag -Entity $vm
    }
    catch
    {
    Write-Error “Failed to assign Tag $($tag.Name) to VM $($vm.Name)”
    }
    }
    }

  7. Steve Furniss

    Alan,

    Does this work for vSphere 5.5 with a W2003 Domain?

    When I run it in my 5.5 environment I get “Unknown” for both user and creation date.

    Any ideas?

    Regards

    Steve

  8. Mike

    Is there an updated script for 5.1 coding? I can’t get this to change the annotations on the VM’s in vSphere 5.1.

  9. Luis

    This data is coming from vCenter right? We just recently migrated from one vCenter server to another and I’m noticing that most of the VM’s don’t have a creation event type. They have a discovered event and that’s from when the new vCenter server first started to manage the VM’s. I’m going to end up retrieving the OS Install date from WMI and use that date as an alternative for Windows based VM’s that don’t have a creation type of event. That should give me a fairly close time to when the VM was first created.

  10. Pingback: Informacje z vSphere – Who Created VM, PortGroup of VM, IP addresse-DamianGarbus | e-DamianGarbus

  11. Itay Mesholam

    Hi,

    i just got this error while runing the script :

    parameter cannot be found that accepts argument ‘class=goog_qs-tidbit goog_qs-tidbit-0>Core

    can i get your help please?

  12. mkbell

    Help! I need to pull out all this list of virtual machines, to include their OS type, names, Ipaddress, cpu, memory. Just like all the information we see on a virtual machine summary.

  13. Gareth Wilson

    If you deploy machines from templates then it just seems to return unknown, uknown for the creation user and date ?

  14. Pingback: First steps to tackle VM sprawl (…with a little, well a lot of help!) « Deans Blog

  15. Hemant Patel

    Hi,

    Really good script and it running perfectly. But when we run the script it cache the previous username who created VM and add this name in all VM’s rather than adding correct name.

    Is there any way to come out from this?

    Hemant

  16. Michael

    Very nice one.. Is it possible to restrict the script so only a particular VM is being queried ? For instance, we are trying to find out when one single VM is being created but we need to avoid that the annotation of 100s of VMs is being modified … Would

    $VMs = Get-VM -name vm1

    do the trick ?

  17. Sybux

    Hi,
    1st, thanx for your script it help me a lot.
    I’ve run it on my vCenter and it returns a little number of result. I’ve combined yours with another one I’ve found on Internet and now it looks in all event.

    I’ve added this lines at the begining :
    # Go very far in past to get all events and enough
    $start = (Get-Date).AddDays(-1999)
    $eventNr = 999999

    And I’ve changed the $Event blabla to use this parameters.
    $Event = $VM | Get-VIEvent -Start $start -MaxSamples $eventNr | Where-Object { $_.Gettype().Name -eq “VmBeingDeployedEvent” -or $_.Gettype().Name -eq “VmCreatedEvent” -or $_.Gettype().Name -eq “VmRegisteredEvent” -or $_.Gettype().Name -eq “VmClonedEvent”}

  18. Alan Post author

    Sure, just change the line that currently reads:

    $VMs = Get-VM | Sort Name

    to the following:

    $VMs = Get-Cluster MyCluster | Get-VM | Sort Name

  19. Warren

    Could this script be altered to only show VM’s in a particular cluster? Very interested to know who did what in our server cluster, but not interested in VDI cluster for exmample. Thanks

  20. Doug Crist

    I’m fairly new to PowerCLI and have a question about the $WhatIfPreference line. I did a find and only found it in line 3. Shouldn’t I see it being checked somewhere farther down in the script? Otherwise, how could it prevent something being written or created?

    Thanks,
    Doug

  21. Pingback: Audit VMware VM’s for Creator and write to vCenter VM notes with PowerShell and PowerCLI 4.1.1 | Learn Powershell | Achieve More

  22. Pingback: How can I tell who created a Hyper-V guest after the fact? - Question Lounge

  23. Pingback: Who created that Hyper-V Server? | DeveloperQuestion.com

  24. Virtu-Al

    I would try copying the code again, are you using the same code against dev and live ?

  25. DazP

    Many thanks for the script ! 🙂
    Works perfectly in my test/dev environment, with c. 20 VMs. In my production environment, against either of 2 vCentres, (c. 190 VMs each) it gives the following error…

    Encountered end of line while processing a string token.
    At line:1 char:3
    + . ” <<<< d:\scripts\Who_Created_VMs.ps1

    Any ideas, please ?

  26. Keshav Attrey

    vCenter events do expire. Based on looking at Alan’s script, the “Unknown”s are there either because some VMs are too old, so vCenter no longer has events for those VMs of type “VmBeingDeployedEvent”, “VmCreatedEvent”, “VmRegisteredEvent”, “VmClonedEvent”, or else because those events for some reason have a blank or null Username field. You can add in some write statements to see which is the cause. If you have to associate *some” user with each VM, but that user doesn’t necessarily need to be the one that deployed/created/registered/cloned it (i.e. someone that powered it on is OK), then you could consider removing the where clause that filters for those event types, and add a sort by createdTime, and just pull of the first user you find. An example without any AD lookup is at http://www.vmdev.info/?p=311.

  27. Brian

    Why would I see a lot of Unknowns? Is every single event for a vm stored forever? Or is it possible that they are only kept for 3-6 months and then deleted? Also, would it return unknown if the user is no longer in AD? Say they left the company or something?

  28. SylStyle

    It’s okay I figured it out, I just re commented the “WhatIfPreference line”

    Thanks for your work :=)

  29. SylStyle

    Hi,

    The script seems to work (because there are no errors except sometimes “domain either not exist”) but the custom fields are not displayed in the annotations box… Have I to create the 2 fields manually?

    Thanks,

    Syl

  30. Pingback: Determining VM creation times from vCenter events « vmdev.info

  31. Tinsmyth

    Hi Al,

    Thanks for the info on the resource change info will try soon.

    My timeout issue occured for several of the first servers it ran against then I stopped the run after 5 or 6 servers. The VC is 2.4 U4. I know some stuff may be an issue before we get to vSphere but am hoping to get some stuff.

    Thanks!

  32. Virtu-Al

    @Tinsymth

    As for your timeout issue I havent seen this before, does it complete any of the VMs or do you get this on the first one ? How old is your VC ?

  33. Virtu-Al

    @Tinsmyth

    Unfortunaatly I dont thing the details are stored in the events so you may find this hard to fine, it looks like it just logs it as a resource change, you can however get a list of resource changes by using something similar to the following:

    Get-VM TestVM | Get-VIEvent | Where { $_.Gettype().Name -eq “VmResourceReallocatedEvent”} | Select CreatedTime, UserName, FullFormattedMessage

    Hope this helps.

  34. Tinsmyth

    Hi Al,

    Well I ran the script and uncommented the line so I could see what it would do and I am getting the following timeout: Get-VIEvent : The operation has timed out
    At C:\Program Files\VMware\Infrastructure\vSphere PowerCLI\WhoCreatedThatVM.ps1
    :23 char:29
    + $Event = $VM | Get-VIEvent <<<< -Types Info | Where { $_.Gettype().N
    ame -eq "VmBeingDeployedEvent" -or $_.Gettype().Name -eq "VmCreatedEvent" -or $

    etc., I did install the Quest AD cmdlets but not sure if its related or not. Thanks!

  35. Tinsmyth

    Hi Al,

    I haven’t run the script yet but it certainly looks like one I can use. I am just getting started with the PowerShell/PowerCLI environment, but I can see learning it will be a good move. I need to be able to get in to my virtual machine settings and find out who has been changing the memory limits in the resource tab. They have caused us big performance problems and I sure would like to know who and why its being done.

    Thanks to you and LucD for helping us newbies out with these scripts!

  36. Virtu-Al

    Troy,

    That is strange, its working fine here, i just tried adding another New VM and running the script and it updated fine.. Hmmm

  37. Troy Clavell

    Hey Al,

    I ran this script against my test environment. Worked great the first time through. However if I add new VM’s and run it again, it erases any previous Annotations and doesn’t add the new. The PCLI interface says it has added it, but the vSphere Client doesn’t show anything. More information can be provided if needed.

  38. Pingback: kb.hurricane-ridge.com / Bookmarks for February 22, 2010 through February 23, 2010

  39. Virtu-Al

    Brian,

    How are you copying the code, are you using the source viewer icon when you hover over the script ?

    Also, do you have the Quest AD cmdlets installed ?

  40. Pingback: VMware vSphere - виртуализация ЦОД » Как узнать, кто создал виртуальную машину на

  41. Brian

    Hey love your scripts… I copied this and I get an error “Unexpected Token ‘if’ in expression or statement. At line:9 char:6

    I am not a scripter so not sure what this means however it looks ok….
    ideas?

  42. Pingback: uberVU - social comments

Leave a Reply

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.