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

Alan

Alan Renouf has a role of Automation Frameworks Product Manager at VMware responsible for providing the architects and operators of the cloud infrastructure with the toolkits/frameworks and command-line interfaces they require to build a fully automated software-defined datacenter. Alan is a frequent blogger at http://blogs.vmware.com/vipowershell and has a personal blog at http://virtu-al.net. You can follow Alan on twitter as @alanrenouf.

You may also like...

43 Responses

  1. JT says:

    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…

  2. Roger says:

    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)”
    }
    }
    }

  3. Steve Furniss says:

    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

  4. Mike says:

    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.

  5. Luis says:

    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.

  6. Itay Mesholam says:

    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?

  7. mkbell says:

    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.

  8. Gareth Wilson says:

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

  9. Hemant Patel says:

    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

  10. Michael says:

    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 ?

  11. Sybux says:

    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”}

  12. Warren says:

    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

    • Alan says:

      Sure, just change the line that currently reads:

      $VMs = Get-VM | Sort Name

      to the following:

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

  13. Doug Crist says:

    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

  14. Robert van den Nieuwendijk says:

    I have changed your “Who created that VM?” script to try to get the creation date from the Active Directory if it can’t be found in the events.

    The script is in the VMware Communities:
    http://communities.vmware.com/message/1728450#1728450

  15. DazP says:

    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 ?

  16. 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.

  17. Brian says:

    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?

  18. SylStyle says:

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

    Thanks for your work :=)

  19. SylStyle says:

    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

  20. Very nice script. For an alternative that doesn’t set custom fields on the VMs, check this out:
    http://www.vmdev.info/?p=311

  21. Tinsmyth says:

    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!

  22. Virtu-Al says:

    @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 ?

  23. Virtu-Al says:

    @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.

  24. Tinsmyth says:

    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!

  25. Tinsmyth says:

    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!

  26. Virtu-Al says:

    Troy,

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

  27. Troy Clavell says:

    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.

  28. Virtu-Al says:

    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 ?

  29. Brian says:

    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?

  30. Andy Grant says:

    Nice post, very useful and good use of active directory!

    PS.. Great use of Childrens TV with Peppa and George Pig, Oink Oink!

  1. February 23, 2010

    Social comments and analytics for this post…

    This post was mentioned on Twitter by alanrenouf: New Post: Who created that VM ? http://is.gd/90jRe #PowerCLI #VMware…

  2. February 24, 2010

    […] virtu-al.net появился скрипт PowerCLI / PowerShell (как пользоваться – здесь), позволяющий […]

  3. February 26, 2010

    […] Who created that VM ? « Virtu-Al – "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." […]

  4. April 9, 2010

    […] For an alternative script that saves the creation time and user as custom fields on each VM (so it should be faster for repeated runs), see Alan Renouf’s script here: http://www.virtu-al.net/2010/02/23/who-created-that-vm/ […]

  5. November 21, 2010

    […] but I have several different accounts that could have created them. I have seen articles on VMWare: http://www.virtu-al.net/2010/02/23/who-created-that-vm/ but nothing on Hyper-V. Any help would be appreciated. Question by This question originated […]

  6. February 5, 2011

    […] but I have several different accounts that could have created them.I have seen articles on VMWare: http://www.virtu-al.net/2010/02/23/who-created-that-vm/ but nothing on Hyper-V. Any help would be appreciated. […]

  7. May 16, 2011

    […] I will start off by saying that this was not my idea to create this awesome script. The real hero behind this is Alan Renouf who first published the original script here.  […]

  8. July 5, 2012

    […] then found an excellent script compiled by Alan Renouf (@alanrenouf) at http://www.virtu-al.net/2010/02/23/who-created-that-vm. The script has a dependently on vSphere PowerCLI (obviously!) and ActiveRoles Management Shell […]

  9. April 10, 2013

    […] informacji na temat kto stworzył daną maszynę, lecz do tego posłużyłem się skryptem z wpisu VIRTU-AL.NET who created that […]

Leave a Reply

%d bloggers like this: