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.

  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: