I am attempting to gather a comprehensive inventory of virtual machines and hosts in my environment. For the virtual machines, I am trying to gather the information seen below but having issue looping through instances of hard disks and network adapters. For example, on the hard disks, I receive the following output:
VMNIC1 : Network adapter 1
NICMAC1 : 00:50:56:87:01:e6
NICNetwork1 : dvPortGroup6666
NICState1 : Connected, GuestControl, StartConnected
HDName1 : Hard disk 2
StorageFormat1 : Thin
HDCapacityGB1 : 100
Datastore1 : [RXCXN00020] host108a/host108a_1.vmdk
As you can see, only the last instance of the disk is saved to my output. In other words, HDNamex is never incremented but the value (here "Hard disk 2") always represents the last disk i.e., this virtual machine has two disks. I have some virtuals with five disk and, in that case, it has HDName 1 with a value of Hard disk 5. How do I properly loop through each instance of my hard disks?
A key part of my information on Virtual Machines is the Cluster it resides upon. This value, however, is only available through the host object's parent attribute. As such, I created a hash table to try and perform this lookup but it appears that the hash table is lost outside of Get-HostInfo function. Note, the function Get-VMInfo attempts to access the values in this hash table with the following output:
Cannot index into a null array.
At D:\scripts\VMInventory.ps1:36 char:82
+ $VMStuff | Add-Member -type noteproperty -name HostCluster -value $HostHashTa
ble[ <<<< $VMStuff.Host]
+ CategoryInfo : InvalidOperation: (host012.domain.com:VMHostIm
pl) [], RuntimeException
+ FullyQualifiedErrorId : NullArray
It looks like I need this hash table to be 'global' and not restricted to its function. Any help with either of these two issues would be greatly appreciated. Below is my code:
Function Get-HostInfo {
Begin {}
Process {
$HostStuff=new-object psobject
$HostHashTable=@{}
$HostStuff | Add-Member -type noteproperty -name HostName -value $_
$HostStuff | Add-Member -type noteproperty -name PowerState -value $_.Powerstate
$HostStuff | Add-Member -type noteproperty -name CPUQty -value $_.NumCpu
$HostStuff | Add-Member -type noteproperty -name Build -value $_.Build
$HostStuff | Add-Member -type noteproperty -name Version -value $_.Version
$HostStuff | Add-Member -type noteproperty -name Manufacturer -value $_.Manufacturer
$HostStuff | Add-Member -type noteproperty -name MemoryTotalGB -value $_.MemoryTotalGB
$HostStuff | Add-Member -type noteproperty -name Model -value $_.Model
$HostStuff | Add-Member -type noteproperty -name NetworkInfo -value $_.NetworkInfo
$HostStuff | Add-Member -type noteproperty -name Cluster -value $_.Parent
$HostStuff | Add-Member -type noteproperty -name Storage -value $_.StorageInfo
$HostHashTable[$HostStuff.HostName]=$HostStuff.Parent
write-output $HostStuff
}
End {}
}
Function Get-VMInfo {
Begin {}
Process {
$VMStuff=new-object psobject
$VMHashTable=@{}
$VMStuff | Add-Member -type noteproperty -name VMName -value $_
$VMStuff | Add-Member -type noteproperty -name Mnmemonic -value $_.Folder
$VMStuff | Add-Member -type noteproperty -name Host -value $_.Host
#Link the VM to its cluster location
$VMStuff | Add-Member -type noteproperty -name HostCluster -value $HostHashTable[$VMStuff.Host]
$VMStuff | Add-Member -type noteproperty -name PowerState -value $_.PowerState
$VMStuff | Add-Member -type noteproperty -name ProvisionedSpaceGB -value $_.ProvisionedSpaceGB
$VMStuff | Add-Member -type noteproperty -name UsedSpace -value $_.UsedSpaceGB
$VMStuff | Add-Member -type noteproperty -name Version -value $_.Version
#Get Network Adapter Information on each instance
$AdapterInfo=Get-NetworkAdapter $_
foreach ($Adapter in $AdapterInfo) {
$j=1
$VMStuff | Add-Member -type noteproperty -name VMNIC$j -value $Adapter.Name
$VMStuff | Add-Member -type noteproperty -name NICMAC$j -value $Adapter.MACAddress
$VMStuff | Add-Member -type noteproperty -name NICNetwork$j -value $Adapter.NetworkName
$VMStuff | Add-Member -type noteproperty -name NICState$j -value $Adapter.ConnectionState
$j++
} #end foreach adapter loop
#Get hard disk information for each instance
$HardDisks=Get-Harddisk $_
foreach ($HD in $Harddisks) {
$i=1
$VMStuff | Add-Member -type noteproperty -name HDName$i -value $HD.Name -force
$VMStuff | Add-Member -type noteproperty -name StorageFormat$i -value $HD.StorageFormat -force
$VMStuff | Add-Member -type noteproperty -name HDCapacityGB$i -value $HD.CapacityGB -force
$VMStuff | Add-Member -type noteproperty -name Datastore$i -value $HD.Filename -force
$i++
} #end foreach HD loop
#Select only the windows machines for the obtaining information from WMI
if ($_ -like "w*"){
$OSinfo=Get-WmiObject -Class Win32_OperatingSystem -computer $_
$VMStuff | Add-Member -type noteproperty -name OSSerialNumber -value $OSinfo.SerialNumber
$VMStuff | Add-Member -type noteproperty -name OSVersion -value $OSinfo.Version
$VMStuff | Add-Member -type noteproperty -name OSVServicePack -value $OSinfo.ServicePackMajorVersion
$VMStuff | Add-Member -type noteproperty -name OSCaption -value $OSinfo.Caption
$VMStuff | Add-Member -type noteproperty -name OSInstallDate -value $OSinfo.InstallDate
$VMStuff.OSInstallDate=([WMI]'').ConvertToDateTime(($OSInfo).InstallDate).ToString("yyyy-MM-dd HH:mm:ss")
$VMStuff | Add-Member -type noteproperty -name OSLastBoot -value $OSinfo.LastBootupTime
$VMStuff.OSLastBoot=([WMI]'').ConvertToDateTime(($OSInfo).LastBootUpTime).ToString("yyyy-MM-dd HH:mm:ss")
$ComputerInfo=Get-WmiObject -Class Win32_ComputerSystem -computer $_
$VMStuff | Add-Member -type noteproperty -name OSSystemType -value $ComputerInfo.SystemType
#Get IP information from each adapter
$OSNICArray=@()
$OSNICrecord=get-wmiobject Win32_NetworkAdapterConfiguration -filter IPEnabled=TRUE -computer $_|select Caption,IPAddress,IPSubnet,DefaultIPGateway,DNSServerSearchOrder,DNSDomainSUffixSearchOrder
$OSNICArray+=$OSNICrecord
foreach ($LAN in $OSNICArray) {
$VMStuff | Add-Member -type noteproperty -name OSAdapterName -value $LAN.Caption
$VMStuff | Add-Member -type noteproperty -name OSIPAddress -value $LAN.IPAddress
$VMStuff | Add-Member -type noteproperty -name OSIPSubnet -value $LAN.IPSubnet
$VMStuff | Add-Member -type noteproperty -name OSGateway -value $LAN.DefaultIPGateway
$VMStuff | Add-Member -type noteproperty -name OSDNSSearchOrder -value $LAN.DNSServerSearchOrder
$VMStuff | Add-Member -type noteproperty -name OSDNSSuffix -value $LAN.dnsdomainsuffixsearchorder
} #end foreach LAN loop
} #end if
$VMHashTable[$VMStuff.VMName]=$VMStuff.Host
write-output $VMStuff
}
End {}
}
#Specify location to search
$Location="My-Place"
Connect-VIServer "VIServer1"
#Gather the host information
$HostatSite=get-vmhost -Location $Location
$HostatSite|Get-Hostinfo
#$HostatSite|Get-Hostinfo|export-csv 'd:\scripts\server-report\'$Location'-HostReport.csv'
#Gather the VM information
$VMatSite=get-vm -Location $Location
#$VMatSite|Get-VMInfo|export-csv d:\scripts\server-report\$Location-VMReport.csv -NoTypeInformation
#$VMatSite|Get-VMInfo|ConvertTo-Html|Set-Content d:\scripts\server-report\$Location-VMReport.htm
$VMatSite|Get-VMInfo