Virtually everything is poshable
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:
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
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
| Print article | This entry was posted by Virtu-Al on February 23, 2010 at 13:59, and is filed under PowerCLI, powershell, vmware. Follow any responses to this post through RSS 2.0. You can leave a response or trackback from your own site. |







(3)
(13)
(0)
about 6 months ago
Nice post, very useful and good use of active directory!
PS.. Great use of Childrens TV with Peppa and George Pig, Oink Oink!
about 6 months ago
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?
about 6 months ago
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 ?
about 6 months ago
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.
about 6 months ago
Troy,
That is strange, its working fine here, i just tried adding another New VM and running the script and it updated fine.. Hmmm
about 6 months ago
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!
about 6 months ago
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!
about 6 months ago
@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.
about 6 months ago
@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 ?
about 5 months ago
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!
about 4 months ago
Very nice script. For an alternative that doesn’t set custom fields on the VMs, check this out:
http://www.vmdev.info/?p=311
about 2 months ago
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
about 2 months ago
It’s okay I figured it out, I just re commented the “WhatIfPreference line”
Thanks for your work :=)
about 1 month ago
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?
about 1 month ago
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.
about 3 weeks ago
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 ?
about 3 weeks ago
I would try copying the code again, are you using the same code against dev and live ?