I forgot to mention;
I'm using VMware vSphere PowerCLI 4.1 build 264274 (running on Windows 2003 32 bit faster, on Windows 2008 64 bit is much slower).
IE setting 'Check for publisher's certficate revocation' = Unchecked
Hi there,
I am trying to build a PowerCli script that retrieves a set of VM properties by using the "fast way" of data retrieval. This method was described at
http://get-admin.com/blog/?p=704. Could anyone help me with completing this script? The second part contains a blocks that are not completed or making the script run slower. Any help would be appreciated.
.....................................................................................................................................................
My environment: vCenter 2.5 U6 , ESX 3.5 U5
Get-vc
$VMs= get-view -ViewType Virtualmachine -Filter @{"Name"="APPSRV*"}
ForEach ($vm in $VMs) {
$Report = "" | Select-Object VMname,InventoryPath, OverallStatus, GuestID, bootTime, enterBIOSSetup, bootDelay, syncTimeWithHost, toolsUpgradePolicy, guestHeartbeatStatus, guestMemoryUsage, hostMemoryUsage, overallCpuUsage, uuid, NetworkConnected, ConfigStatus, vmCreatedByUser,vmCreatedDate,ESXname,ClusterName,Respool,Datacenter,VmFolder,MemoryGB,vCPUcount,vNICcount,IPaddresses,VMXname,VMDKs,VMDKname,VmdkSizeGB,TotalVmdkSizeGB,DatastoreName,ToolsVersion,ToolsUpdate,NumCpuShares,CpuLimitMHZ,CpuReservationMHZ,NumMemShares,ReservationsMB,LimitMB,SnapshotCount,GuestOS,Mac,NetworkName,VMState,vDVDFile, vFloppyFile
Start part with fast retrieval of VM info ............................
$Report.VMName = $VM.name
$esx=Get-View $vm.Runtime.Host -Property Name
$Report.ESXname = $esx.Name
$respool=Get-View $vm.Resourcepool -Property Name
$Report.ResPool=$respool.Name
$vMFolder=Get-View $vm.parent -Property Name
$Report.VmFolder=$vMFolder.Name
#path
$current=Get-View $vm.parent
$path=$vMFolder.Name
do {
$parent = $current
$path = $parent.Name + "\" + $path
$current = Get-View $current.Parent
} while ($current.Parent -ne $null)
$Report.InventoryPath = $path
$Report.DatastoreName = $VM.Config.DatastoreUrl
$Report.ToolsVersion = $VM.Config.Tools.ToolsVersion
$Report.ToolsUpdate = $VM.Guest.ToolsStatus
$Report.toolsUpgradePolicy = $VM.Config.Tools.toolsUpgradePolicy
$Report.VMState = $VM.summary.runtime.powerState
$Report.OverallStatus=$VM.OverallStatus
$Report.ConfigStatus=$VM.ConfigStatus
$Report.VMXname = $VM.summary.config.VmPathName
$report.uuid=$VM.summary.config.uuid
$Report.GuestID = $VM.Guest.guestId
$Report.GuestOS = $VM.Guest.GuestFullName
$Report.vNICcount = $VM.summary.config.numEthernetCards
$Report.IPaddresses = $VM.Guest.IPAddress
$Report.Mac=$VM.Guest.net[0].MAcAddress
$Report.NetworkName=$VM.Guest.net[0].network
$Report.NetworkConnected=$VM.Guest.net[0].connected
$Report.vCPUcount=$VM.summary.config.numCpu
$report.CpuReservationMHZ=$VM.summary.config.cpuReservation
$Report.CpuLimitMHZ = $VM.config.cpuAllocation.limit
$Report.CpuReservationMHZ = $VM.config.cpuAllocation.Reservation
$Report.MemoryGB=$VM.summary.config.memorySizeMB/1024
$Report.NumMemShares = $VM.resourceConfig.memoryAllocation.shares.shares
$report.ReservationsMB=$VM.summary.config.memoryReservation
$Report.LimitMB = $VM.config.memoryAllocation.limit
$Report.ReservationsMB = $VM.config.memoryAllocation.Reservation
$Report.bootDelay = $VM.config.bootOptions.bootDelay
$Report.enterBIOSSetup = $VM.config.bootOptions.enterBIOSSetup
$Report.guestHeartbeatStatus = $vm.summary.quickStats.guestHeartbeatStatus
$Report.guestMemoryUsage = $vm.summary.quickStats.guestMemoryUsage
$Report.hostMemoryUsage = $vm.summary.quickStats.hostMemoryUsage
$Report.overallCpuUsage = $vm.summary.quickStats.overallCpuUsage
$Report.SnapshotCount = $VM.Layout.Snapshot.Count
End part with fast retrieval of vm info ...................................
Start part that should be completed/rewritten/tuned/optimized
Q1: This one works but it makes the existing script run 400% slower .... how to make same speed as above?"
$VMHardDisks = Get-VM $vm.name| Get-HardDisk
$HardDisksSizesGB = @()
$Temp = $VMHardDisks | ForEach-Object { $HardDisksSizesGB += ::Round($_.CapacityKB/1MB) }
$VmdkSizeGB = ""
$Temp = $HardDisksSizesGB | ForEach-Object { $VmdkSizeGB = "$_" }
$VmdkSizeGB = $VmdkSizeGB.TrimEnd("+")
$TotalHardDisksSizeGB = 0
$Temp = $HardDisksSizesGB | ForEach-Object { $TotalHardDisksSizeGB += $_ }
$VMDKnames = @()
$Temp = $VMHardDisks | ForEach-Object { $VMDKnames += $_.Filename.Split("/")[1] }
$Report.VMDKs=$VMDKnames.count
$Report.VMDKname = $VMDKnames
$Report.VmdkSizeGB = $VmdkSizeGB
$Report.TotalVmdkSizeGB = $TotalHardDisksSizeGB
........................................................
Q2: How to integrate this? Show me connected .ISO file (if any present)"
config.hardware.device[3000].backing.deviceName
config.hardware.device[3000].deviceInfo.summary
config.hardware.device[3000].backing.fileName
config.hardware.device[3000].connectable.connected
config.hardware.device[3000].connectable.startConnected
$Report.vDVDFile =
........................................................
Q3: How to integrate this? Show me connected .FLP file (if any present)"
config.hardware.device[8000].backing.deviceName
config.hardware.device[8000].deviceInfo.summary
config.hardware.device[8000].backing.fileName
config.hardware.device[8000].connectable.connected
config.hardware.device[8000].connectable.startConnected
$Report.vFloppyFile=
........................................................
Q4: How to find cluster name? (with same speed as above)
$esxcls=Get-View $vm.Cluster -Property Name
$Report.ClusterName=$esxcls.Name
$Report.ClusterName=($_.name | Get-Cluster).Name
This one works but it makes the existing script run 400% slower
$Report.ClusterName=(Get-Cluster -VMHost $esx.Name)
........................................................
Q5: How to find Datacenter name? (with same speed as above)
$Report.Datacenter=get-view $vm.Datacenter -Property Name
$Report.Datacenter=($_ | Get-Datacenter).Name
........................................................
Write-Output $Report
}
$Report | Export-Csv "D:\VMreport.txt" -noTypeInformation
Before I reply a quick question, are you using PowerCLI 4.1 or an older version ?
You can check with
Get-PowerCLIVersion
____________
Blog: LucD notes
Twitter: lucd22
Blog: lucd.info Twitter: @LucD22 Co-author PowerCLI Reference
I forgot to mention;
I'm using VMware vSphere PowerCLI 4.1 build 264274 (running on Windows 2003 32 bit faster, on Windows 2008 64 bit is much slower).
IE setting 'Check for publisher's certficate revocation' = Unchecked
Ok, made a few changes and answered the questions.
Should be faster.
I attached the script since it contains some square brackets and the forum SW doesn't like these.
____________
Blog: LucD notes
Twitter: lucd22
Blog: lucd.info Twitter: @LucD22 Co-author PowerCLI Reference
Awesome,
Everything is working super except the part regarding the retrieval of vmdk info (Q1). I guess it's because i'm running this script against the vCenter 2.5U6/ESX 3.5U5 and not against vCenter 4.x/vSphere 4.x. I tried to crawl the path with MOB but i don't see layoutex. I see only layout. Maybe that's the reason.
The error message i'm getting:
Cannot index into a null array.
At E:\My_Datacenter\Software\vPC\BTJOB0001\vminventory3.ps1:86 char:30
+ $tmp = $vm.LayoutEx.File[ <<<< $_]
+ CategoryInfo : InvalidOperation: ( [], RuntimeException
+ FullyQualifiedErrorId : NullArray
If you have any idea how to solve this it would be great otherwise I'll stick to old method until i migrate the environment to vSphere 4.x.
I'll wait for your response or otherwise i'll consider this question as answered (With capital A and thank you for your help)
Well as you stated in : http://communities.vmware.com/message/1550266#1550266. The layoutex is new property in vCenter4.x/vSphere 4.x
My fault, should have seen that you're using API 2.5.
But no problem, there's more than one way to skin a cat
Try the attached version.
Is the speed satisfactory ?
____________
Blog: LucD notes
Twitter: lucd22
Blog: lucd.info Twitter: @LucD22 Co-author PowerCLI Reference
It's working, It retrieves the names of vmdks and count of vmdks
but it can't retrieve the size:
I guess this line doesn't do anything (because $VmdkSize is not calculated and summarized value returns 0).
$VmdkSizeGB += (::round($VmdkSize/1MB))
This is the output part which results in:
....
VMDKs : 2
VMDKname : [ insert to SQL db with SQLbulkCopy option. And post it back.
I know one thing for sure. My other VM inventory scripts based on 'Get-VM' are obsolete. What a huge difference.
Forgot to edit that line.
It should say
$VmdkSizeGB += ([math]::round($_.capacityInKB/1MB))
Sorry about that
____________
Blog: LucD notes
Twitter: lucd22
Blog: lucd.info Twitter: @LucD22 Co-author PowerCLI Reference
Yep,
I tried this before i replied with $_.capacityKB instead of $_.capacityInKB. I didn't pay attention too.
Well, that was a solution. I made a small change (line 33) in order to determine inventory path otherwise i get duplicated path info on every iteration.
It works. Perfect. The final code is posted back.