VMware Cloud Community
chrischrischris
Enthusiast
Enthusiast
Jump to solution

Need help improving performance of "Get-VMHostStorage -RescanAllHba -RescanVmfs" in script.

Hi all,
Any suggestions on how to improve the performance of this script would be greatly appreciated.
The script forces all hosts to rescan their storage (because of changes on the storage side (add LUNs, etc.)).
Currently it takes 33 minutes for 57 hosts.  I would like to bring this down to 5 minutes, if possible.
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 {

     $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

0 Kudos
1 Solution

Accepted Solutions
LucD
Leadership
Leadership
Jump to solution

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).

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 {

   $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

View solution in original post

0 Kudos
4 Replies
LucD
Leadership
Leadership
Jump to solution

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).

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 {

   $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

0 Kudos
chrischrischris
Enthusiast
Enthusiast
Jump to solution

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

0 Kudos
chrischrischris
Enthusiast
Enthusiast
Jump to solution

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

0 Kudos
LucD
Leadership
Leadership
Jump to solution

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

0 Kudos