I wanted to expand This Script to allow you to specify hosts as well, instead of just vCenter.

This came about because we have 20 new hosts that need storage so we can build our new vCenter server on them, and my old script wouldn’t suffice.

I know you can rescan at the container level (cluster, folder, datacenter), but sometimes the processes would hang on large clusters, other times I’d have to rescan twice. I like this script because it rescans all HBAs one by one, then rescans VMFS after. One could probably add the -runasync, but then it’s the same as the right-click in vCenter.

So, without further ado, here’s the updated script:

#set the input options here as -vc and -cluster
param([string]$vc = "vc", [string]$container = "container", [string[]]$vmhosts = $null)
 
#check to make sure we have both
function usage()
	{
	Write-host -foregroundcolor green `n`t"This script is used to rescan all HBAs and VMFS for all hosts provided."
	Write-host -foregroundcolor green `n`t"You can either specify -vmhosts as an array:"
	write-host -foregroundcolor yellow `n`t`t"Rescan-Storage -vmhosts (`"host1`",`"host2`",`"host3`")"
	Write-host -foregroundcolor green `n`t"or specify -vc and -container, where container is a host name, cluster, folder, datacenter, etc:"
	write-host -foregroundcolor yellow `n`t`t"Rescan-Storage -vc vcenterserver -container cluster1" `n
    	write-host -foregroundcolor green `t"You can use either -vmhosts by itself, or -vc and -container together, not a combination of them." `n
	}
 
function RescanHBA()
{
    foreach ($vmhost in $vmhosts)
	{
	if ($esx -eq 1)
	#do this only if connecting directly to ESX hosts
		{
		connect-viserver $vmhost -credential $vmhost_creds > $NULL 2>&1
		}
	Write-Host `n
	Write-Host -foregroundcolor green "Server: " $vmhost
	write-host "Scan all HBAs on "$vmhost
	get-VMHostStorage -VMHost $vmhost -RescanAllHba
 
    if ($esx -eq 1)
	#disconnect from the current ESX host before going to the next one
        {
        disconnect-viserver -confirm:$false
        }
	}
	write-host `n
}
 
function RescanVMFS()
{
    foreach ($vmhost in $vmhosts)
	{
	if ($esx -eq 1)
	#do this only if connecting directly to ESX hosts
		{
		connect-viserver $vmhost -credential $vmhost_creds > $NULL 2>&1
		}
	Write-Host `n
	Write-Host -foregroundcolor green "Server: " $vmhost
	write-host "Rescan VMFS on "$vmhost
	get-VMHostStorage -VMHost $vmhost -RescanVmfs
 
     	if ($esx -eq 1)
	#disconnect from the current ESX host before going to the next one
        	{
            	disconnect-viserver -confirm:$false
            	}
	}
	write-host `n
 
    	if ($vcenter -eq 1)
        #disconnect from vcenter
        {
        disconnect-viserver -confirm:$false
        }      
}
 
#check to make sure we have all the args we need
if (($vmhosts -eq $null) -and (($vc -eq "vc") -or ($container -eq "container")))
    #if vmhosts, vc, or container is blank
	{
	usage
    	break
	}
 
elseif (($vmhosts -ne $null) -and (($vc -ne "vc") -or ($container -ne "container")))
    #if vmhosts and vc or container is used
	{
	usage
    	break
	}
 
elseif (($vmhosts -ne $null) -and (($vc -eq "vc") -or ($container -eq "container")))
    #if only vmhosts is used, set our esx variable to 1 and get credentials
	{
    	$esx = 1
    	$vmhost_creds = $host.ui.PromptForCredential("ESX/ESXi Credentials Required", "Please enter credentials to log into the ESX/ESXi host.", "", "")
    	RescanHBA
	RescanVMFS
    	}
 
elseif (($vmhosts -eq $null) -and (($vc -ne "vc") -and ($container -ne "container")))
    #if vc and container are used, set our vcenter variable to 1, get credentials, and populate vmhosts
	{
    	$vcenter = 1
    	$vc_creds = $host.ui.PromptForCredential("vCenter Credentials Required", "Please enter credentials to log into vCenter.", "", "")
    	connect-viserver $vc -credential $vc_creds > $NULL 2>&1
    	$vmhosts = get-vmhost -location $container | sort name
	RescanHBA
	RescanVMFS
	}
 
#garbage collection
$vmhost_creds = $null
$vc_creds = $null
$vmhosts = $null
$vc = $null
$container = $null
$esx = $null
$vcenter = $null