Get VMware VM creation date (kind of)

VMware vSphere doesn’t seem to keep the VM creation date in its database anywhere, but if your VMs are all/mostly running Windows (and you have permission to do a WMI query against them) you can get the OS install date, which probably aligns fairly closely to the VM creation date. It won’t be perfect, but it might be good enough, and better than nothing.

This PowerShell/PowerCLI script attempts to pull information out of your VMs, and allows you to fairly easily graph (via Excel) how your VMware environment has grown over time. Note that in its current form the script assumes that the VM name is the same as the Windows computer name.

The script gives you the following columns in its CSV file output:

  • VM name
  • Windows OS install date (or a reason why it wasn’t able to get it)
  • Number of vCPUs for the current VM
  • vRAM allocated to the current VM

My suggestion for graphing is as follows: sort the output by the InstallDate column, ditch the rows where the date couldn’t be retrieved. Shift the CPU and RAM columns three columns to the right to give a three column gap. In the column immediately next to the date, have a “Count” column – a simple incrementing number to keep count of how many VMs you had on that date, starting at one and going up by one per row (i.e. 1, 2, 3, 4, …). Then in the other two columns use simple formulas to keep a running total of the amount of vRAM and vCPUs that you have. To get the graph, select the column heading for the InstallDate column, then Ctrl-click on the column headings for the Count, TotalvRAM and TotalvCPU columns one at a time. You can then insert a line graph, and it’ll look halfway decent (albeit needing some tidying up and adjustment of the labelling of the axes):

VMwareGrowth

Clearly if you have converted any physical machines to VMs then the install date will be that of the physical server, not the VM creation, so you might want to ignore anything before whatever date you went 100% VM, but it’s still better than nothing!

function LoadVMwareSnapins{
    $snapinList = @( "VMware.VimAutomation.Core", "VMware.VimAutomation.License", "VMware.DeployAutomation", "VMware.ImageBuilder", "VMware.VimAutomation.Cloud")

    $loaded = Get-PSSnapin -Name $snapinList -ErrorAction SilentlyContinue | % {$_.Name}
    $registered = Get-PSSnapin -Name $snapinList -Registered -ErrorAction SilentlyContinue  | % {$_.Name}
    $notLoaded = $registered | ? {$loaded -notcontains $_}

    foreach ($snapin in $registered) {
        if ($loaded -notcontains $snapin) {
            Add-PSSnapin $snapin
        }
    }
}

function GetInstallDate([string]$Computer){
    Write-Host "Processing $Computer"
    if(Test-Connection -ComputerName $Computer -Count 1 -ErrorAction SilentlyContinue){
        $OS = Get-WmiObject -Class Win32_OperatingSystem -ComputerName $Computer -ErrorAction SilentlyContinue
        if($OS -ne $null){
            $InstallDate = $OS.ConvertToDateTime($OS.Installdate)
            Add-Member -InputObject $ResultObject -MemberType NoteProperty -Name InstallDate -Value $InstallDate
        } else {
            Add-Member -InputObject $ResultObject -MemberType NoteProperty -Name InstallDate -Value "WMI fail"
        }
    } else {
        Add-Member -InputObject $ResultObject -MemberType NoteProperty -Name InstallDate -Value "Ping fail"
    }
}

$CSVFile = "$env:UserProfile\Desktop\VMAudit2.csv"
$TotalVMs = 0
$TotalvRAM = 0
$TotalCPUs = 0

LoadVMwareSnapins
Connect-VIServer -Server vsphere
$VMs = Get-VM

foreach($VM in $VMs){
    $ResultObject = New-Object -TypeName PSObject
    Add-Member -InputObject $ResultObject -MemberType NoteProperty -Name Computer -Value $VM.Name
    if($vm.PowerState -eq "PoweredOn"){
        GetInstallDate $VM.Name
    } else {
        Add-Member -InputObject $ResultObject -MemberType NoteProperty -Name InstallDate -Value "Powered off"
    }
    $TotalVMs = $TotalVMs + 1
    $TotalvRAM = $TotalvRAM + $VM.MemoryGB
    $TotalCPUs = $TotalCPUs + $VM.NumCpu
    Add-Member -InputObject $ResultObject -MemberType NoteProperty -Name vCPUs -Value $VM.NumCpu
    Add-Member -InputObject $ResultObject -MemberType NoteProperty -Name vRAM -Value $VM.MemoryGB
    Export-Csv -InputObject $ResultObject -Path $CSVFile -Append -NoTypeInformation
    $ResultObject | Format-Table -AutoSize
}
Write-Host "Total VMs: $TotalVMs, Total vRAM: $TotalvRAM, Total vCPUs: $TotalCPUs"
Disconnect-VIServer -Server vsphere
This entry was posted in PowerShell, vSphere, Windows and tagged , , , , , , , , , . Bookmark the permalink.

10 Responses to Get VMware VM creation date (kind of)

  1. Wayne says:

    It doesn’t work?
    I got that you had to change the vsphere to your Virtual Center’s name
    Also I did go onto the DC and ran winrm quickconfig to open the firewall and wmi port
    But on the output it says?

    “Computer InstallDate vCPUs vRAM
    DC01 Ping fail 2 4
    VC01 Ping fail 2 12

    So everything works but the installDate which actually the only thing I need.

  2. Wayne says:

    Hi Guys
    This does work, you need to be on a server on the same domain as the virtual center (Not laptop on other domain)
    Also I had to upgrade to powershell version 3
    Works now, thanks

  3. Hadjie M Buquis says:

    Step by Step please…

  4. UBERX says:

    how can we execute the above script? are we going to save it on a file or just copy and paste it to the power shell?

    • rcmtech says:

      Copy & paste the script into the PowerShell ISE, change the vCenter server name at line 36, save it, then run it.
      Note that the account you run the script as needs to have administrator rights to all the VMs, so you need to run it as a server/domain admin.

      • UBERX says:

        is it safe to run during production hours? does it have impact to vm performance?

      • rcmtech says:

        As you can see from the script, it’s not doing anything to the VMs other than a simple WMI query, which shouldn’t add any noticeable extra load on the servers. The other info is coming from vCenter.

  5. UBERX says:

    thanks.. by the way, we’ve run the script and the result was not what we expect as you have indicated above like the graph. here are some red font results.

    Export-Csv : A parameter cannot be found that matches parameter name ‘Append’.
    At line:14 char:65
    + Export-Csv -InputObject $ResultObject -Path $CSVFile -Append <<<< -NoTypeInformation
    + CategoryInfo : InvalidArgument: (:) [Export-Csv], ParameterBindingException
    + FullyQualifiedErrorId : NamedParameterNotFound,Microsoft.PowerShell.Commands.ExportCsvCommand

    We have already installed the latest VMWARE vSphere PowerCLI 5.5 as our tool to run the script, by the way, do we need some plugins or features also to install in our workstation to have it works smoothly?

    Please advice. Thanks again for your help

    • rcmtech says:

      You’re running an old version of PowerShell. I recommend at least version 3, but preferably the latest available – currently 4.0.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s