VMware Cloud Community
trent1980
Enthusiast
Enthusiast

get-vmhoststorage rescan all hba on hosts at same time

Does anyone know how to rescan the HBAs on all hosts at the same time instead of waiting for each one to finish? In our recovery script, we currently have:

Get-Cluster -Name $Cluster | Get-VMHost | Get-VMHostStorage -RescanAllHba -RescanVmfs | out-null

but this scans 1 VMHost at a time and then goes to the next (which is very time consuming)

I've tried to use the Start-Job cmdlet in ps v2.0 but I'm having a difficult time understanding the best concept. It seems like I can start the job but then I need to "Receive-Job" before it actually sends the rescanallhba job to the VMHost. Then I have to write a loop to "Receive-Job" on all the jobs I dynamically created ... and then I'm back to square one ... one at at time instead of all at once.

thanks

0 Kudos
17 Replies
LucD
Leadership
Leadership

Welcome to the club, I'm breaking my head over something similar since a couple of days Smiley Wink

In theory the PS v2 background jobs should be the solution for this.

But I'm experiencing a hang with this (and judging from several posts on other forums I'm not the only one)

My idea was:

*) get all the VMHosts where you want to perform a rescan

*) start a separate background job for each rescan

*) wait till all jobs are finished by using the Wait-Job cmdlet

My initial script looked like this

$jobs = @()
Get-View -ViewType HostSystem | %{
		$jobs += Start-Job `
			-InitializationScript {
				Add-PSSnapin -Name "VMware.VimAutomation.Core"
			} `
			-ScriptBlock {
# 			[void][http://Reflection.Assembly|http://Reflection.Assembly]::LoadWithPartialName("VMware.Vim")
 			Connect-VIServer -Session $Args[1]
 			(Get-View $Args[0].configManager.storageSystem).RescanAllHba()
		} -ArgumentList $_,$defaultVIserver.SessionId
}
Wait-Job $jobs
Receive-Job $jobs

Each background job hangs on the Add-PSSnapin cmdlet. And this is required since the background jobs start with the -NoProfile option as far as I can see.

I place the Add-PSSnapin in the -InitializationScript script block and in the -ScriptBlock script bloc, but the effect is always the same, the background job hangs.

I'm not sure if the LoadWithPartialName statement is required.

The hang of the Add-PSSnapin cmdlet in background jobs seems to be a known problem. See for example Adding a snapin (add-pssnapin) from within a job (start-job) causes job to hang indefinitely, a post by Hal.

____________

Blog: LucD notes

Twitter: lucd22


Blog: lucd.info  Twitter: @LucD22  Co-author PowerCLI Reference

0 Kudos
halr9000
Commander
Commander

I'm glad you linked back to that bug report Luc, as I had not seen the comments. Note that the last comment is from a guy on the PowerShell team.

Posted by LukaszA on 1/25/2010 at 4:46 PM

The hang is related to this: http://support.microsoft.com/kb/2009703

After reading the article, I don't pretend to know much more about the issue except that it appears to be only seen on XP and 2003. Is that consistent with what everyone here is seeing? I'll have to try to repro now on W7...nope, can't repro. It appears to be fixed there.




[vExpert|http://www.vmware.com/communities/vexpert/], PowerShell MVP, VI Toolkit forum moderator

Author of the book: Managing VMware Infrastructure with PowerShell

Co-Host, PowerScripting Podcast (http://powerscripting.net)

Need general, non-VMware-related PowerShell Help? Try the forums at PowerShellCommunity.org

My signature used to be pretty, but then the forum software broked it. vExpert. Microsoft MVP (Windows PowerShell). Author, Podcaster, Speaker. I'm @halr9000
0 Kudos
trent1980
Enthusiast
Enthusiast

Yeah I came across that post by Hal this morning ... I actually wrote him earlier and requested a blog writeup on the background processes in v2.0 - ha

I tried creating a second powershell script that I could pass an argument to but I can't figure out how to pass a variable in the scriptblock

For instance, If I could create a generic scan.ps1 and just pass it the vmhost ... then I could just loop through that and create start-jobs off that

I tried this:

Start-Job -Name $VMNAME -FilePath G:\USERS\Trent\PowerShell\Scripts\scan-hba.ps1 -ArgumentList $VMNAME --- (and different variations)

&

Start-Job -name $VMNAME -sciptblock {Powershell "& g:\users\trent\powershell\scripts\scan-hba.ps1 $VMNAME"}

(which starts the job with the vmhost's name but then just passes "$VMNAME" to the script instead "esx01.local" ... which fails)

That second one I just tried to regurgitate from banging my head on the desk about 4 hours ago ... not sure if it's exactly how I had it before.

I even ran onyx and then did a rescan on the cluster ... but it just spun out multiple lines of the same thing that go sequentially if i run them from PowerGUI

0 Kudos
LucD
Leadership
Leadership

Passing arguments via the -ArgumentList parameter works. I tried that.

I use it to pass the SessionId.

Note that the background job is a complete new PS session, so you will have to perform the Connect-ViServer again.

That's why I pass the SessionId

Hal, I read that last remark on the post this evening (CET) and will try again on some other platforms.

____________

Blog: LucD notes

Twitter: lucd22


Blog: lucd.info  Twitter: @LucD22  Co-author PowerCLI Reference

0 Kudos
LucD
Leadership
Leadership

Tested the Start-Job script on a Windows 2008 R2 64-bit server and Windows 7 Ultimate 64-bit, same problem.

____________

Blog: LucD notes

Twitter: lucd22


Blog: lucd.info  Twitter: @LucD22  Co-author PowerCLI Reference

0 Kudos
trent1980
Enthusiast
Enthusiast

I know it's junk ... but here's my workaround for now (I only have XP machines to work with)

Call a new powershell script and pass it a variable from within my loop function. Then I wait for all the job states to not equal "running" ...

#############################

function RefreshDataStores {

Write-Host "Rescanning for new devices and Datastores..."

$VMHOSTS = Get-Cluster -Name $Cluster | Get-VMHost

$VMHOSTS | ForEach-Object {

$VMNAME = $_.Name

$PSLine = "Start-Job -Name $VMNAME -ScriptBlock {powershell C:\scan-hba.ps1 $VMNAME}"

Invoke-Expression $PSLine

}

$getjobs = Get-Job

do {

sleep 5

$getjobs = Get-Job | where {$_.state -eq "Running"}

} while ($getjobs -ne $null)

}

##################################

scan-hba.ps1

param($pattern = $(throw "Please pass me some content"))

$VIserver = "myserver"

Add-PSsnapin VMware.VimAutomation.Core -ErrorAction SilentlyContinue

connect-viserver $VIserver

Get-VMHost $pattern | Get-VMHostStorage -RescanVmfs -RescanAllHba | out-null

0 Kudos
yboychev
Hot Shot
Hot Shot

If we (VMW) introduce a -RunAsync parameter to the Get-VmHostStorage cmdle would that help? Then the piece of script would look like this:

Get-VMHost | Get-VMHostStorage -RescanAllHba -RescanVmfs -RunAsync | out-null

\Yavor

0 Kudos
LucD
Leadership
Leadership

Yavor, that sounds like a great idea.

One question though, how would we discover that a scan ended with a fault ?

Will the cmdlet capture, and pass on, these potential faults ?

____________

Blog: LucD notes

Twitter: lucd22


Blog: lucd.info  Twitter: @LucD22  Co-author PowerCLI Reference

0 Kudos
yboychev
Hot Shot
Hot Shot

Yeah, good note Luc. Have to figure what will be the best approach. 10x, will put that in our wish list Smiley Happy

\Yavor

PowerCLI team

0 Kudos
admin
Immortal
Immortal

Has there been a solution for this where we can perform "Get-VMHostStorage -RescanAllHba" against multiple hosts asynchronously?

0 Kudos
LucD
Leadership
Leadership

I'm afraid not, there is no -RunAsync parameter on the Get-VMHostStorage cmdlet yet.


Blog: lucd.info  Twitter: @LucD22  Co-author PowerCLI Reference

0 Kudos
admin
Immortal
Immortal

Is there a workaround available? Are there any OS / configurations that are not affected?

What about using a mix of PowerShell (to get the host listing) and CMD (to call a PowerShell stub via CMD background) to get the job done?

0 Kudos
admin
Immortal
Immortal

Trent wrote:

I know it's junk ... but here's my workaround for now  (I only have XP machines to work with)

Trent's workaround worked for me. While I don't consider his workaround to be "junk," I think we all agree there should be a better way via a direct -async option or a more elegant Start-Job option.

0 Kudos
LucD
Leadership
Leadership

I don't think this is a PowerCLI problem, if you look at the underlying SDK methods, RescanHBA and RescanAllHBA and RescanVMFS, you will see that these methods do not return a task object. The call to the method will wait till the scan is finished.

I agree, Trent's solution is the better alternative for now.


Blog: lucd.info  Twitter: @LucD22  Co-author PowerCLI Reference

0 Kudos
Jas0nBourne
Contributor
Contributor

Is this still really the best way to do this?  (even after all these years)

0 Kudos
LucD
Leadership
Leadership

I'm afraid so.


Blog: lucd.info  Twitter: @LucD22  Co-author PowerCLI Reference

0 Kudos
GA_KIFILL
Contributor
Contributor

I was hoping to find some new nuggets for datastore decommission script been working on... made use of the get-datastore/unmount-datastore function from William Lee... but was hoping  get-vmhoststorage would've matured by now...

0 Kudos