# encoding: ascii # api: powershell # title: VMware guest information # description: I needed to write a script to generate a VMware guest inventory so I needed to know what was available within the PowerCLI interface and where to find it. So I wrote this script to dump everything it could find about a single VMware guest. It has proved very useful to me. I hope others will also find it useful. # version: 4.1 # type: script # author: Bruce Shreffler # license: CC0 # x-poshcode-id: 3129 # x-archived: 2016-03-04T19:40:20 # x-published: 2012-12-27T10:18:00 # # # vminfo.ps1 # # Give this a VMware guest and it will attempt to dump all the information available. # # Example: .\vminfo.ps1 "guestname" # # This scripts assumes that you have already connected to a VirtualCenter server. # # This was developed and tested using VMware vSphere PowerCLI version 4.1.1.2816 # on an ESXi 4.1 build 381591 cluster Param($guest) #################################################################### # ProcessObject - This recursive function does the bulk of the work. # #Input Parameters # # $xobj - Object to dump info on # $pref - Prefix to use on print lines # # When an object is encountered then we recursively call ourselves to # process that object after first updating the prefix. # # Snapshot objects can point to both a parent and a child. Dumping both # Parent and Child objects results in an endless loop. Therefore dump only # Child objects. function ProcessObject ($xobj, $pref){ $plen = $pref.length $pad = $width - $plen If ($pad -lt 0){$pad = 0} # Get information on all of the members of this object because what is done with a member is # dependent on whether the member is an object or is a data item and if it is a data item # what kind of data item is it $xom = $xobj | get-member -membertype property foreach ($ent in $xom){ $xnam = $ent.name #write-host ">>>>>>>Processing entry" $ent.name $xnlen = $xnam.length $strs = $ent.Definition.split(" ") # process 1st level simple things like strings and numbers including simple arrays # There are some fields in a VMware guest "Get-View" description we will ignore # because they are obsolete and have either had their descriptive names changed # or a new cmdlet is now available and it is the preferred method for finding # out about the object. # # The following "objects" may be encountered but will be ignored. These are legacy objects # from ESX 3.5 but were promoted to having their own cmdlets in ESX 4. Therefore we will # ignore them when found as members of some other object prefering to examine them using the # new cmdlets. # # legacy guest objects # # CDDrives == Get-CDDrives # FloppyDrives == Get-FloppyDrive # HardDisk == Get-HardDisk # NetworkAdapters == Get-NetworkAdapter # UsbDevices == Get-UsbDevice # # legacy host objects # # ConsoleNic == Get-VMHostNetworkAdapter # PhysicalNic == Get-VMHostNetworkAdapter # VirtualNic == Get-VMHostNetworkAdapter # VirtualSwitch == Get-VirtualSwitch # ScsiLun == Get-ScsiLun # # if ($xnam -match "^(CDDrives|FloppyDrives|HardDisks|NetworkAdapters|UsbDevices)$" ){ "{0,-$plen}{1,-1}{2,-$pad}{3,-2}{4,-30}" -f $pref, ".", $xnam, ":", "== skipping legacy device object ==" #| Out-File -FilePath $reportfile -Append } elseif ($xnam -match "^(ConsoleNic|PhysicalNic|ScsiLun|VirtualNic|VirtualSwitch)$" ){ #Write-Host "****** skipping legacy Network Adapter object- $xnam" "{0,-$plen}{1,-1}{2,-$pad}{3,-2}{4,-30}" -f $pref, ".", $xnam, ":", "== skipping legacy Network Adapter object ==" #| Out-File -FilePath $reportfile -Append } # The following are obsolete identifiers in ESX 3.5 that have new names as of ESX version 4.x # We will ignore all old identifiers and only display the new identifiers. # # Description - replaced by Notes # Host is replaced by VMHost # HostId is replaced by VMHostId # State == ConnectionState # VirtualMachineId == VMId elseif ($xnam -match "^(Description|Host|HostId|State|VirtualMachineId)$" ){ "{0,-$plen}{1,-1}{2,-$pad}{3,-2}{4,-30}" -f $pref, ".", $xnam, ":", "== skipping obsolete identifier ==" #| Out-File -FilePath $reportfile -Append } # Examining the following will result in recursive loops threrfore we will skip them. # # Parent # VM # VMHost elseif ($xnam -match "^(VMHost)$" ){ "{0,-$plen}{1,-1}{2,-$pad}{3,-2}{4,-30}" -f $pref, ".", $xnam, ":", "== skipping object to avoid infinite loop ==" #| Out-File -FilePath $reportfile -Append } elseif ($strs[0] -match "^System.String\[\]" ){ if (!$xobj.$xnam.count) { $res = $xobj.$xnam #Write-Host "=== single entry array name =" $xnam "result" $res "{0,-$plen}{1,-1}{2,-$pad}{3,-2}{4,-30}" -f $pref, ".", $xnam, ":", $xobj.$xnam #| Out-File -FilePath $reportfile -Append } else { $count = $xobj.$xnam.count for ($i=0; $i -lt $count; $i++){ $namlen = $xnam.length $ipad = $pad - 2 - $namlen If ($i -gt 9){$ipad--} If ($ipad -lt 1){$ipad = 1} "{0,-$plen}{1,-1}{2,-$namlen}{3,1}{4,1}{5,-$ipad}{6,-2}{7,-30}" -f $pref, ".", $xnam, "[", $i, "]", ":", $xobj.$xnam[$i] #| Out-File -FilePath $reportfile -Append } } } elseif ($strs[0] -match "^System.(String|Int|Nullable|Boolean|DateTime|Double)" ){ # If this is a "value__" then show the number and the symbolic name if ($xnam -eq "value__"){ $vpad = $pad + 3 "{0,-$plen}{1,$vpad}{2,-2}{3,-2}{4,-30}" -f $pref, ": ", $xobj.$xnam, "-", $xobj #| Out-File -FilePath $reportfile -Append } else { "{0,-$plen}{1,-1}{2,-$pad}{3,-2}{4,-30}" -f $pref, ".", $xnam, ":", $xobj.$xnam #| Out-File -FilePath $reportfile -Append } } elseif ($strs[0] -match "^VMware.Vim(.|Automation.Types|Automation.ViCore)"){ # Hack to avoid closed loop when crawling snapshot structures # Each child points back to its parent and each parent points to its children # hence and endless loop. Therefore do not process parents if ($xnam -match "^(Parent|ParentSnapshot|VM)$"){ $pad = $width-$plen If ($pad -lt 0){$pad = 0} "{0,-$plen}{1,-1}{2,-$pad}{3,-2}" -f $pref, ".", $xnam, ": == skipping $xnam to avoid infinite loop ==" #| Out-File -FilePath $reportfile -Append } else { $pad = $width-$plen If ($pad -lt 0){$pad = 0} $yobj = $xobj.$xnam $newp = $pref + "." + $xnam if (!$yobj){ "{0,-$plen}{1,-1}{2,-$pad}{3,-2}" -f $pref, ".", $xnam, ": =undefined=" #| Out-File -FilePath $reportfile -Append } else{ if (!$yobj.count){ ProcessObject $yobj $newp } else { $lc = $yobj.count for ($z = 0; $z -lt $lc; $z++){ $zobj = $yobj[$z] $zperf = $newp + "[" + $z + "]" ProcessObject $zobj $zperf } } } } } elseif ($strs[0] -match "^System.(Collections)" ){ Foreach ($entry in $xobj.$xnam){ $newpref = $pref + "." + $xnam $cpad = $pad - $xnam.length - 1 If ($cpad -lt 0){$cpad = 0} "{0,-$plen}{1,-1}{2,-$Cpad}{3,-2}{4,-30}" -f $newpref, ".", $entry.Key, ":", $entry.value #$strs[0] #| Out-File -FilePath $reportfile -Append } } else { "{0,-$plen}{1,-1}{2,-$pad}{3,-2}{4,-30}" -f $pref, ".", $xnam, ":", $ent.Definition #$strs[0] #| Out-File -FilePath $reportfile -Append } } } function POLauncher ($xobj, $pref){ if (!$xobj.count){ ProcessObject $xobj $pref } else { $lc = $xobj.count for ($z = 0; $z -lt $lc; $z++){ $zobj = $xobj[$z] $zperf = $pref + "[" + $z + "]" ProcessObject $zobj $zperf } } } # end function ProcessObject $reportfile = "vminfo-rpt.txt" $first = 20 $width = 70 $xvm = get-vm -name $guest $prefix = $xvm.name + " Get-VM" POLauncher $xvm $prefix # Display information about virtual devices attached to the guest # Process devices CDDrives|Harddisk|FloppyDrives|NetworkAdapters|UsbDevices $dvm = get-HardDisk -vm $xvm $prefix = $xvm.name + " Get-HardDisk" POLauncher $dvm $prefix $cdvm = get-CDDrive -vm $xvm $prefix = $xvm.name + " Get-CDDrive" POLauncher $cdvm $prefix $flpvm = get-FloppyDrive -vm $xvm $prefix = $xvm.name + " Get-FloppyDrive" POLauncher $flpvm $prefix $netvm = get-NetworkAdapter -vm $xvm $prefix = $xvm.name + " Get-NetworkAdapter" POLauncher $netvm $prefix $usbvm = get-UsbDevice -vm $xvm $prefix = $xvm.name + " Get-UsbDevice" POLauncher usbvm $prefix #Get-View return more information than Get-Vm $xview = $xvm | get-view $prefix = $xvm.name + " Get-View" POLauncher $xview $prefix # Return information about any snapshots. $snap = get-snapshot $xvm if ($snap){ $prefix = $xvm.name + " Get-Snapshot" POLauncher $snap $prefix } #Tell ua about the host we are running on $vmhost = $xvm.VMHost $prefix = $vmhost.name + " Get-VMHost" POLauncher $vmhost $prefix # probably don't want to do this one unless you want to be buried in data #$vmhostv = Get-View $vmhost #$prefix = $vmhostv.name + " Get-View" #POLauncher $vmhostv $prefix #Dump information about the Host's devices $nics = Get-VMHostNetworkAdapter $vmhost foreach ($nic in $nics){ $prefix = $vmhost.name + " " + $nic.Name POLauncher $nic $prefix } $vmguest = get-vmguest $xvm $prefix = $xvm.name + " Get-VMGuest" #POLauncher $vmguest $prefix $vmdatastore = get-datastore -vm $xvm $prefix = $xvm.name + " Get-Datastore" POLauncher $vmdatastore $prefix $dc = Get-Datacenter -vm $xvm $prefix = $xvm.name + " Get-Datacenter" #POLauncher $dc $prefix