I'm trying to find the fastest way to do the following:
I have this working code, but it takes ages to run:
Get-VM -Location (Get-ResourcePool -Name TestPool) | Select Name, @{N="Host";E={Get-VMHost -VM $_}}, @{N="Location";E={Get-VMHost -VM $_ | Get-Annotation -CustomAttribute Location}}
The code above will return something like this:
Name | Host | Location |
---|---|---|
VM1 | Host1 | Site-A |
VM2 | Host1 | Site-A |
VM3 | Host2 | Site-B |
Is there a faster way to get this info, perhaps with Views?
Try like this
$rpName = 'MyResourcePool'
$si = Get-View ServiceInstance
$caMgr = Get-View -Id $si.Content.customFieldsManager
$key = $caMgr.Field | where{$_.ManagedObjectType -eq 'HostSystem' -and $_.Name -eq 'Location'} |
Select -ExpandProperty Key
$rp = Get-View -ViewType ResourcePool -Filter @{'Name'="^$($rpName)$"}
$rp | %{Get-View -Id $_.VM} |
Select Name,
@{N='Host';E={$script:esx=Get-View -Id $_.Runtime.Host -Property Name,CustomValue; $script:esx | select -ExpandProperty Name}},
@{N='Location';E={$script:esx.CustomValue | where{$_.Key -eq $key} | select -ExpandProperty Value}},
@{N='Datastore';E={
($_.Storage.PerDatastoreUsage | %{
"$(Get-View -Id $_.Datastore -Property Name | Select -ExpandProperty Name)($([math]::Round(($_.Committed/1GB),0))GB)"
}) -join ','
}}
Blog: lucd.info Twitter: @LucD22 Co-author PowerCLI Reference
Try like this
$rpName = 'MyResourcePool'
$si = Get-View ServiceInstance
$caMgr = Get-View -Id $si.Content.customFieldsManager
$key = $caMgr.Field | where{$_.ManagedObjectType -eq 'HostSystem' -and $_.Name -eq 'Location'} |
Select -ExpandProperty Key
$rp = Get-View -ViewType ResourcePool -Filter @{'Name'=$rpName}
Get-View -Id $rp.VM |
Select Name,
@{N='Host';E={$script:esx=Get-View -Id $_.Runtime.Host -Property Name,CustomValue; $script:esx | select -ExpandProperty Name}},
@{N='Location';E={$script:esx.CustomValue | where{$_.Key -eq $key} | select -ExpandProperty Value}}
Blog: lucd.info Twitter: @LucD22 Co-author PowerCLI Reference
Thanks Luc, that worked a treat, and soo much faster!
Well, it worked after I realised "-Filter @{'Name'=$rpName}" was returning several Resource Pools, so I had to use the unique identifier to only return one Resource Pool.
How do you format the code showing colour?
Note that the filter is a regular expression, if you want an exact match, you could use the following notation $rpname = '^rpname$'.
The caret and the dollar sign are positional markers (at the start and at the end of the string)
Blog: lucd.info Twitter: @LucD22 Co-author PowerCLI Reference
It now works perfectly when using ^ and $, thanks Luc.
How can I select the VM's Datastore and Datastore Cluster too, ideally handling multiple datastores if disks are spread across more than one?
Also, what's the best resource out there to find out all the properties and methods available when using views?
Something like a tree-view would be great if available?
The resource for all the vSphere API methods and properties is the API Reference
There are a number of tools available to list/display the content of a complex object.
One of the better ones, imho, is Show-Object from Lee Holmes
Blog: lucd.info Twitter: @LucD22 Co-author PowerCLI Reference
This is one way of getting the datastores on which the VM has VMDK.
If there is more than one datastore, then they are separated by '|'
$rpName = 'MyResourcePool'
$si = Get-View ServiceInstance
$caMgr = Get-View -Id $si.Content.customFieldsManager
$key = $caMgr.Field | where{$_.ManagedObjectType -eq 'HostSystem' -and $_.Name -eq 'Location'} |
Select -ExpandProperty Key
$rp = Get-View -ViewType ResourcePool -Filter @{'Name'="^$($rpName)$"}
Get-View -Id $rp.VM |
Select Name,
@{N='Host';E={$script:esx=Get-View -Id $_.Runtime.Host -Property Name,CustomValue; $script:esx | select -ExpandProperty Name}},
@{N='Location';E={$script:esx.CustomValue | where{$_.Key -eq $key} | select -ExpandProperty Value}},
@{N='Datastore';E={
$ds = $_.Config.Hardware.Device | where{$_ -is [VMware.Vim.VirtualDisk} | %{
$_.Backing.Datastore
}
[string]::Join((Get-View -Id $ds -Property Name | select -ExpandProperty Name),'|')
}}
Blog: lucd.info Twitter: @LucD22 Co-author PowerCLI Reference
Thanks Luc.
It didn't work using:
[string]::Join((Get-View -Id $ds -Property Name | select -ExpandProperty Name),'|')
but this gets the desired result:
Get-View -Id $ds -Property Name | select -ExpandProperty Name
How easy is it to allow the script to handle multiple Resource Pools (if we don't use ^ and $ in the initial search), then display the resource pool as a column in the results?
Strange that the Join didn't work for you.
For running this over multiple resourcepools, you would need to loop through all the resourcepools, and add a calculated property to display the resourcepoolname.
Blog: lucd.info Twitter: @LucD22 Co-author PowerCLI Reference
I've been playing around with various other scripts and I've fallen at the first hurdle.
My lack of knowledge is obviously getting in the way!
I'm trying to loop through all Resource Pools, but I'm getting this error:
Get-View : Cannot validate argument on parameter 'Id'. The argument is null or empty. Supply an argument that is not null or empty and then try the command again.
At F:\AdamRush\ps\test-get-rp-vms-hosts-locations.ps1:25 char:19
+ $rp | Get-View -Id <<<< $_.VM |
+ CategoryInfo : InvalidData: (:) [Get-View], ParameterBindingValidationException
+ FullyQualifiedErrorId : ParameterArgumentValidationError,VMware.VimAutomation.ViCore.Cmdlets.Commands.DotNetInterop.GetVIView
Here's the current script:
==============
# ResourcePool
$rpName = 'ResourcePoolName'
# Connect to stretched vCenter
Connect-VIServer VCENTERNAME
Write-Host "Finding VMs in Org VDC(s) matching this string: $($rpName) ..."
# Get Key for Custom Annotation called "Location"
$si = Get-View ServiceInstance
$caMgr = Get-View -Id $si.Content.customFieldsManager
$key = $caMgr.Field | where{$_.ManagedObjectType -eq 'HostSystem' -and $_.Name -eq 'Location'} |
Select -ExpandProperty Key
$rp = Get-View -ViewType ResourcePool -Filter @{'Name'="$rpName"} # this sometimes returns multiple Resource Pools so I need to handle that
# Loop through all VMs in each Resource Pool and display ResourcePool, VM Name, Location, VM Host, Datastores (with used GB amount in brackets)
$rp | Get-View -Id $_.VM |
Select Name,
@{N='ResourcePool';E={Get-View -Id $_.ResourcePool -Property Name | select -ExpandProperty Name}}, # NOT SURE AS HAVEN'T GOT THIS FAR
@{N='Location';E={$script:esx=Get-View -Id $_.Runtime.Host -Property Name,CustomValue; $script:esx.CustomValue | where{$_.Key -eq $key} | select -ExpandProperty Value}},
@{N='Host';E={$script:esx | select -ExpandProperty Name}},
@{N='Datastores';E={
$ds = $_.Config.Hardware.Device | where{$_ -is [VMware.Vim.VirtualDisk]} | %{
$_.Backing.Datastore
}
Get-View -Id $ds -Property Name | select -ExpandProperty Name
}} | sort Location, Datastores | Out-GridView -Title "VMs in the $($rp.Name) Org VDC"
# this stops GridView disappearing
Read-Host "Press Enter to continue ..."
============
What's wrong with "$rp | Get-View -Id $_.VM |"?
$rp has a collection of Resource Pools, so I thought $_.VM should return all VMs for each Resource Pool?
I'm also trying to add the "used disk space per datastore" in brackets next to Datastore name, but I can't get that working even though I have this to work from: How to display VM specific disk size
Any help would be greatly appreciated!
Anyone got any ideas?
If you change that line to
$rp | %{Get-View -Id $_.VM}
it will work.
By using the ForEach you make sure that the Get-View uses the resourcepool in the $_ variable.
The Id parameter on Get-View doesn't accept input through the pipeline.
Blog: lucd.info Twitter: @LucD22 Co-author PowerCLI Reference
Thanks Luc, that worked great and I can now produce something like this:
Name Location Host Datastores ResourcePool
VM1 SiteA Host01 Datastore01,Datastore02 ResourcePoolA
VM2 SiteB Host01 Datastore01,Datastore04 ResourcePoolA
VM1 SiteA Host02 Datastore01 ResourcePoolB
How can I add the disk usage per Datastore (actual space used)?
For example:
Name Location Host Datastores ResourcePool
VM1 SiteA Host01 Datastore01(20GB),Datastore02(10GB) ResourcePoolA
VM2 SiteB Host01 Datastore01(10GB),Datastore04(5GB) ResourcePoolA
VM1 SiteA Host02 Datastore01(40GB) ResourcePoolB
Does anybody know how to add up the actual space used per Datastore?
Try like this
$rpName = 'MyResourcePool'
$si = Get-View ServiceInstance
$caMgr = Get-View -Id $si.Content.customFieldsManager
$key = $caMgr.Field | where{$_.ManagedObjectType -eq 'HostSystem' -and $_.Name -eq 'Location'} |
Select -ExpandProperty Key
$rp = Get-View -ViewType ResourcePool -Filter @{'Name'="^$($rpName)$"}
$rp | %{Get-View -Id $_.VM} |
Select Name,
@{N='Host';E={$script:esx=Get-View -Id $_.Runtime.Host -Property Name,CustomValue; $script:esx | select -ExpandProperty Name}},
@{N='Location';E={$script:esx.CustomValue | where{$_.Key -eq $key} | select -ExpandProperty Value}},
@{N='Datastore';E={
($_.Storage.PerDatastoreUsage | %{
"$(Get-View -Id $_.Datastore -Property Name | Select -ExpandProperty Name)($([math]::Round(($_.Committed/1GB),0))GB)"
}) -join ','
}}
Blog: lucd.info Twitter: @LucD22 Co-author PowerCLI Reference
Works great, thanks for all your help Luc!
Your book is also really helping me with ideas and scripts:
VMware vSphere PowerCLI Reference: Automating vSphere Administration: VMware vSphere PowerCLI Reference: Automating vSphere Administration eBook: Luc Dekens, Jonathan Med...