Exporting all that useful VM information with PowerCLI
There are many occasions when you may need to produce a report showing some aspect of your VM environment.
Many companies have various types of inventory databases which grab information from various sources to provide tracking and reporting of the various IT assets.
An example of a database could be one which pulls information from the software inventory system, patch management system, anti-virus console showing latest file update, AD etc. which could show a dashboard view of the workstations and highlight where they are not in compliance to company standards.
As a virtual workstation environment grows there is plently of information from vCenter that would be very useful to gather.
Grouping VMs by VDI groups in vCenter folders so you know how many VMs x department has would be useful to have. For the dashboard view it may be usedful having the VM Tools status. It’s could also be useful knowing which VMs are in which cluster and datastore, what virtual CPU and RAM they have and how big their disks are which can be used for capacity planning, performance analysis and reporting on what is deployed where.
A daily PowerCLI report can then be run which pulls this all from vCenter and dumps a .CSV file which the workstation database sucks in and mashes together with the other feeds providing a single place to view everything related to workstations.
The script builds an always useful hash table which is very easy to add to and then exports the resulting report to CSV.
The Get-Member powershell command is the best way to find out what information is available for a particular object. There are two simple lines you can run which will output most of the objects you can report on, for this example it is Get-VM but you could use Get-Cluster etc.
Get-VM "AnyVM" | Get-Member Get-VM "AnyVM"| Get-View | Get-Member
I’ve also used the great Get-FolderPath function from Maish which is excellent.
@" =============================================================================== Title: Export-VMInfo.ps1 Description: Exports VM Information from vCenter into a .CSV file for importing into anything Usage: .\Export-VMInfo.ps1 Date: 04/03/2010 =============================================================================== "@ filter Get-FolderPath { $_ | Get-View | % { $row = "" | select Name, Path $row.Name = $_.Name $current = Get-View $_.Parent # $path = $_.Name # Uncomment out this line if you do want the VM Name to appear at the end of the path $path = "" do { $parent = $current if($parent.Name -ne "vm"){$path = $parent.Name + "\" + $path} $current = Get-View $current.Parent } while ($current.Parent -ne $null) $row.Path = $path $row } } $VCServerName = "vCenter.local" $VC = Connect-VIServer $VCServerName $VMFolder = "Workstations" $ExportFilePath = "\\fileshare\dump\Export-VMInfo.csv" $Report = @() $VMs = Get-Folder $VMFolder | Get-VM $Datastores = Get-Datastore | select Name, Id $VMHosts = Get-VMHost | select Name, Parent ForEach ($VM in $VMs) { $VMView = $VM | Get-View $VMInfo = {} | Select VMName,Powerstate,OS,Folder,IPAddress,ToolsStatus,Host,Cluster,Datastore,NumCPU,MemMb,DiskGb, DiskFree, DiskUsed $VMInfo.VMName = $vm.name $VMInfo.Powerstate = $vm.Powerstate $VMInfo.OS = $vm.Guest.OSFullName $VMInfo.Folder = ($vm | Get-Folderpath).Path $VMInfo.IPAddress = $vm.Guest.IPAddress[0] $VMInfo.ToolsStatus = $VMView.Guest.ToolsStatus $VMInfo.Host = $vm.host.name $VMInfo.Cluster = $vm.host.Parent.Name $VMInfo.Datastore = ($Datastores | where {$_.ID -match (($vmview.Datastore | Select -First 1) | Select Value).Value} | Select Name).Name $VMInfo.NumCPU = $vm.NumCPU $VMInfo.MemMb = [Math]::Round(($vm.MemoryMB),2) $VMInfo.DiskGb = [Math]::Round((($vm.HardDisks | Measure-Object -Property CapacityKB -Sum).Sum * 1KB / 1GB),2) $VMInfo.DiskFree = [Math]::Round((($vm.Guest.Disks | Measure-Object -Property FreeSpace -Sum).Sum / 1GB),2) $VMInfo.DiskUsed = $VMInfo.DiskGb - $VMInfo.DiskFree $Report += $VMInfo } $Report = $Report | Sort-Object VMName IF ($Report -ne "") { $report | Export-Csv $ExportFilePath -NoTypeInformation } $VC = Disconnect-VIServer -Confirm:$False
Thanks for the mention Julian
But the get-folderpath credit should actually go to Luc Dekens – I can’t exactly remember where the source is on the community – but I am 100% he was the source for the script.
I’m sure a lot of scripting credit when passed up the chain lands at the foot of the master…Luc.
Well, thanks Luc for devising it and Maish for implementing it!
Updated with some more operational efficiencies and added calculated disk space info
Thank you. Nice report
Can you add a line to get the notes in VMs?
Regards
I have an issue with one part that I cannot figure out.
I have PowerCLI 5.0 and vcenter 4.1 U2.
I get an error
Get-View : Cannot validate argument on parameter ‘VIObject’. The argument is null or empty. Supply an argument that is not null or empty and the
n try the command again.
exportvms.ps1:12 char:32 which is $current = Get-View $current.Parent
Any help would be appreciated
hello everyone, this scripts get the first hdd and datastore configured in vsphere. is there any way that we can get all the hdd and datastore through this script?
waiting for reply.
here is another one liner that you can use…
Get-VM | Select Name, NumCPU, MemoryMB, ProvisionedSpaceGB, UsedSpaceGB, @{N=”ESX Host”;E={Get-VMHost -VM $_}}, @{N=”Datastore”;E={Get-Datastore -VM $_}}, @{N=”Guest OS”;E={Get-VMGuest -VM $_}}
Hello everyone, I’m using PowerCLI 5.1 and I’m getting a HardDisk deprecation error with this script. Is it possible to update the script using the new cmdlet?
This will let you use the Custom Attributes of a VM, replace “Description” with your own custom attribute name:
$VMInfo.Description = (Get-VM -Name $VM | Get-Annotation -CustomAttribute “Description”) -replace “Description:”
Hi,
I would like to know, how do I get the Folder details of VM and RDM disk in below oneliner
Get-VM | Select Name, NumCPU, MemoryMB, ProvisionedSpaceGB, UsedSpaceGB, @{N=”ESX Host”;E={Get-VMHost -VM $_}}, @{N=”Datastore”;E={Get-Datastore -VM $_}}, @{N=”Guest OS”;E={Get-VMGuest -VM $_}}
Hi All,
I would like to know how do i get details of all the VM in a cluster.
The VMs have multiple NICs attached so would like VM information to show IP address on both the NICs
kindly assist.
Thanks
How do i change the script for Hyper-V (non-cluster) . Please guide me .
I have changed this line in the script because it does not display the full and correct OS level. For instance, VMware will only display 2012 guest OS and not 2012 R2. When run it by itself it seems to work great on remote systems, but when its run in the script against a vcenter the issue I’m running into is it appears to list things in that line as an array and if it can’t locate that VM’s info it doesn’t place a NULL in its place.
# $VMInfo.OS = $vm.Guest.OSFullName
$VMInfo.OS = (Get-CimInstance -ComputerName $VMs Win32_OperatingSystem | Select Caption)
I was hoping you could have some guidance on how to successfully merge this into your script to get that much more detail.
@Suresh
Try just Network:
$vminfo.NetworkName= $vm.Network
Before running in a script, try this:
Get-VM SOME-VM-HERE | Get-View
you will see a line for Network and see what the variable data is.