write-host ("Forcing hosts to rescan storage.")
$ScanResults = @()
$h = Measure-Command {
$Hosts = Get-VMHost | `
Where-Object {($_.ConnectionState -notlike '*dis*') -and ($_.ConnectionState -notlike '*not*')} |`
Sort-Object -Property Name
}
Write-Host " Getting host list: Get-VMHost took $($h.TotalSeconds) seconds to complete."
$ts = Measure-Command {
$Hosts | ForEach-Object {
Write-Host " Rescan $($_.Name)"
$m = Measure-command {$ScanResults += Get-VMHostStorage -VMHost $_.Name -RescanAllHba -RescanVmfs}
Write-Host " Get-VMHostStorage for $($_.Name) took $($m.TotalSeconds) seconds to complete."
}
}
Write-Host " Get-VMHostStorage for all $($Hosts.count) hosts took $($ts.TotalSeconds) seconds to complete."
}
Thanks in advance!
-Chris
The RescanHBA and RescanVmfs are slow and the system will execute them sequentially.
There is not a lot that can be improved speed-wise.
And this is not a PowerCLI thing, as the 2nd snippet should show.
The fact the methods (see 2nd snippet), don't have a _Task suffix (run in the background) is telling.
The 1st method to potentially win some execution time, is to run the scans in parallel.
But there you will notice that they are still executed in sequence.
$job = {
param($session,$esx)
Connect-VIServer -Server $session.Name -Session $session.Sessionid
Write-Host " Rescan $($esx.Name)"
$m = Measure-command {$ScanResults += Get-VMHostStorage -VMHost $esx.Name -RescanAllHba -RescanVmfs}
Write-Host " Get-VMHostStorage for $($esx.Name) took $($m.TotalSeconds) seconds to complete."
}
if ($ReScan) {
write-host ("Forcing hosts to rescan storage.")
$ScanResults = @()
$h = Measure-Command {
$Hosts = Get-VMHost |
Where-Object {($_.ConnectionState -notlike '*dis*') -and ($_.ConnectionState -notlike '*not*')} |
Sort-Object -Property Name
}
Write-Host " Getting host list: Get-VMHost took $($h.TotalSeconds) seconds to complete."
$ts = Measure-Command {
$jobs = @()
$Hosts | ForEach-Object {
$jobs += Start-Job -ScriptBlock $job -ArgumentList $global:defaultviserver,$_ -Name scan
}
Wait-Job -Job $jobs
Receive-Job -Job $jobs
}
Write-Host " Get-VMHostStorage for all $($Hosts.count) hosts took $($ts.TotalSeconds) seconds to complete."
}
Another way to improve the execution time is to call the vSphere methods directly.
But this is still slow, and you only see a very small improvement (any potential PowerCLI overhead).
write-host ("Forcing hosts to rescan storage.")
$ScanResults = @()
$h = Measure-Command {
$Hosts = Get-VMHost |
Where-Object {($_.ConnectionState -notlike '*dis*') -and ($_.ConnectionState -notlike '*not*')} |
Sort-Object -Property Name
}
Write-Host " Getting host list: Get-VMHost took $($h.TotalSeconds) seconds to complete."
$ts = Measure-Command {
$Hosts | ForEach-Object {
Write-Host " Rescan $($_.Name)"
$m = Measure-command {
$storSys = Get-View -Id $_.ExtensionData.ConfigManager.StorageSystem
$storSys.RescanAllHba()
$storSys.RescanVmfs()
}
Write-Host " Get-VMHostStorage for $($_.Name) took $($m.TotalSeconds) seconds to complete."
}
}
Write-Host " Get-VMHostStorage for all $($Hosts.count) hosts took $($ts.TotalSeconds) seconds to complete."
}
In conclusion, no big time gains possible.
Blog: lucd.info Twitter: @LucD22 Co-author PowerCLI Reference
The RescanHBA and RescanVmfs are slow and the system will execute them sequentially.
There is not a lot that can be improved speed-wise.
And this is not a PowerCLI thing, as the 2nd snippet should show.
The fact the methods (see 2nd snippet), don't have a _Task suffix (run in the background) is telling.
The 1st method to potentially win some execution time, is to run the scans in parallel.
But there you will notice that they are still executed in sequence.
$job = {
param($session,$esx)
Connect-VIServer -Server $session.Name -Session $session.Sessionid
Write-Host " Rescan $($esx.Name)"
$m = Measure-command {$ScanResults += Get-VMHostStorage -VMHost $esx.Name -RescanAllHba -RescanVmfs}
Write-Host " Get-VMHostStorage for $($esx.Name) took $($m.TotalSeconds) seconds to complete."
}
if ($ReScan) {
write-host ("Forcing hosts to rescan storage.")
$ScanResults = @()
$h = Measure-Command {
$Hosts = Get-VMHost |
Where-Object {($_.ConnectionState -notlike '*dis*') -and ($_.ConnectionState -notlike '*not*')} |
Sort-Object -Property Name
}
Write-Host " Getting host list: Get-VMHost took $($h.TotalSeconds) seconds to complete."
$ts = Measure-Command {
$jobs = @()
$Hosts | ForEach-Object {
$jobs += Start-Job -ScriptBlock $job -ArgumentList $global:defaultviserver,$_ -Name scan
}
Wait-Job -Job $jobs
Receive-Job -Job $jobs
}
Write-Host " Get-VMHostStorage for all $($Hosts.count) hosts took $($ts.TotalSeconds) seconds to complete."
}
Another way to improve the execution time is to call the vSphere methods directly.
But this is still slow, and you only see a very small improvement (any potential PowerCLI overhead).
write-host ("Forcing hosts to rescan storage.")
$ScanResults = @()
$h = Measure-Command {
$Hosts = Get-VMHost |
Where-Object {($_.ConnectionState -notlike '*dis*') -and ($_.ConnectionState -notlike '*not*')} |
Sort-Object -Property Name
}
Write-Host " Getting host list: Get-VMHost took $($h.TotalSeconds) seconds to complete."
$ts = Measure-Command {
$Hosts | ForEach-Object {
Write-Host " Rescan $($_.Name)"
$m = Measure-command {
$storSys = Get-View -Id $_.ExtensionData.ConfigManager.StorageSystem
$storSys.RescanAllHba()
$storSys.RescanVmfs()
}
Write-Host " Get-VMHostStorage for $($_.Name) took $($m.TotalSeconds) seconds to complete."
}
}
Write-Host " Get-VMHostStorage for all $($Hosts.count) hosts took $($ts.TotalSeconds) seconds to complete."
}
In conclusion, no big time gains possible.
Blog: lucd.info Twitter: @LucD22 Co-author PowerCLI Reference
Thanks Luc!
I now understand the issue better and from your reply I see that there is little to be done to improve the script's performance.
Best,
-Chris
Hi Luc,
I tried the parallel version, but the jobs all failed with errors like this one:
10/8/18 5:31:02 PM Get-VMHostStorage Could not find VMHost with name 'ESXi99.local'.
+ CategoryInfo : ObjectNotFound: (ESXi99.local:String) [Get-VMHostStorage], VimException
+ FullyQualifiedErrorId : Core_ObnSelector_SelectObjectByNameCore_ObjectNotFound,VMware.VimAutomation.ViCore.Cmdlets.Commands.Host.GetVMHostStorage
+ PSComputerName : localhost
10/8/18 5:31:02 PM Get-VMHostStorage Value cannot be found for the mandatory parameter VMHost
+ CategoryInfo : NotSpecified: (:) [Get-VMHostStorage], VimException
+ FullyQualifiedErrorId : Core_BaseCmdlet_UnknownError,VMware.VimAutomation.ViCore.Cmdlets.Commands.Host.GetVMHostStorage
+ PSComputerName : localhost
I'm not sure what I did wrong ...
Any advice is appreciated.
-Chris
In the Start-Job code block it connects to the vCenter that is passed via the Start-Job cmdlet.
Perhaps the ESXi node for which you are trying to scan the storage is not located in the vCenter you passed to the Start-Job?
Are you perhaps connected to multiple vCenters at the same time?
I would need to know your environment and see the code you used to further analyse.
Blog: lucd.info Twitter: @LucD22 Co-author PowerCLI Reference