I am currently working on a script to do a vmfs unmap across a wide number of datastores. I have a script for doing it against a single datastore, and it works well, but in this case I have hundreds to touch, so this is my thought process:
Attached is my script thus far:
$aHosts = @()
$report = @()
$aClusters = Get-Datacenter "MyDC" |
Get-Cluster |
Select Name
foreach($sCluster in $aClusters) {
$sHost = Get-VMHost -Location $sCluster.Name |
Select -First 1 |
Select Name
$aHosts += $sHost
}
foreach ($sHost in $aHosts | Sort Name) {
$sStore = Get-VMHost $sHost.Name |
Get-Datastore |
Select Name
$report += $sStore.Name
}
$report | Out-GridView
First and foremost, as I am still learning with PowerCLI, while this works I wonder if there is not a simpler way to accomplish this through a better pipeline call than splitting it out into two for loops. I attempted to do so but unsuccessfully. Secondly, the output I get has just the datastore name. I have tried a couple different ways of getting the hostname and the datastore name with each pass, but it doesn't come out the way I would expect. My end goal, as I stated, would be to have for each VMHost a list of its datastores, so I can cycle through them. Any suggestions would be welcome.
Try like this, one long pipeline construct.
It uses the PipelineVariable to refer to previous pipeline objects.
Get-Datacenter -Name MyDC |
Get-Cluster -PipelineVariable cluster |
Get-VMHost -PipelineVariable esx |
Get-Datastore |
Select @{N='Cluster';E={$cluster.Name}},
@{N='VMHost';E={$esx.Name}},
Name |
Out-GridView
Blog: lucd.info Twitter: @LucD22 Co-author PowerCLI Reference
Try like this, one long pipeline construct.
It uses the PipelineVariable to refer to previous pipeline objects.
Get-Datacenter -Name MyDC |
Get-Cluster -PipelineVariable cluster |
Get-VMHost -PipelineVariable esx |
Get-Datastore |
Select @{N='Cluster';E={$cluster.Name}},
@{N='VMHost';E={$esx.Name}},
Name |
Out-GridView
Blog: lucd.info Twitter: @LucD22 Co-author PowerCLI Reference
Thanks, this is far and away better than what I have. I can use this to try and cycle through and do the unmaps. One question, if you could help me understand, my code was specifically calling -First 1 so that I would get only the first VMHost in every cluster. Keeps me from having a bunch of redundant data in the output. Yours does not use this explicitly, however I notice it only grabs one host from each. It's great, don't get me wrong - I just don't understand the behavior.
It's not the Get-VMHost that is doing this, it's the Get-Datastore.
The PowerCLI Team implemented the Get-Datastore in such a way that you wouldn't see duplicate entries for shared datastores.
Blog: lucd.info Twitter: @LucD22 Co-author PowerCLI Reference
Thanks again. This is what I ended up with, should anyone do a search for something similar in the future.
$aReport = Get-Datacenter -Name "MyDC" |
Get-Cluster -PipelineVariable cluster |
Get-VMHost -PipelineVariable esx |
Get-Datastore |
Select @{N='Cluster';E={$cluster.Name}}, `
@{N='VMHost';E={$esx.Name}}, `
Name, FreeSpaceGB, CapacityGB
foreach ($sHost in $aReport) {
$_host = $sHost.VMHost
$cluster = $sHost.Cluster
$dStore = $sHost.Name
$esxcli2 = Get-EsxCli -VMHost $_host
$arguments = $esxcli2.storage.vmfs.unmap.CreateArgs()
$arguments.volumelabel = $dStore
$esxcli2.storage.vmfs.unmap.Invoke($arguments)
}