Hi guys. I'm trying to get this modified script to disable "delayed ack" on every esxi host in a cluster. With the original script, it only targets specific esxi hosts instead and it runs just fine. When it runs this way (i.e. specifying the cluster so it iterates through the hosts one at a time), it fails on the first host it attempts to process. The error message has been provided below. Could someone tell me why it's not working and / or help fix it?
=================Error Message============
Exception calling "UpdateInternetScsiAdvancedOptions" with "3" argument(s): "The object or item referred to could not be found."
At line:52 char:1
+ $HostStorageSystem.UpdateInternetScsiAdvancedOptions($HostiSCSISoftwa ...
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : NotSpecified: (:) [], MethodInvocationException
+ FullyQualifiedErrorId : VimException
=================Script====================
param (
[parameter(Mandatory=$true
,HelpMessage="VC Name")]
[string] $VC
,[parameter(Mandatory=$true
,HelpMessage="Cluster Name")]
[string] $cluster
)
$svr=$null;
$svr = Connect-VIServer -Server $VC;
if ($svr -eq $null)
{
$sMsg = "Unable to connect to VC " + $VC;
exit 1;
}
$sMsg = "Getting cluster " + $cluster +" on VC " + $VC;
Write-Host $sMsg;
$oClstr=$null;
$oClstr = Get-Cluster -Server:$svr -Name $cluster;
if ($oClstr -eq $null)
{
$sMsg="Unable to find cluster " +$cluster + " on VC " + $VC;
$iret1 = Disconnect-VIServer -Server:$svr -Confirm:$false -ErrorAction:SilentlyContinue;
exit 1;
}
$sMsg ="Getting hosts on cluster " + $cluster + " on VC " + $VC;
write-host $sMsg;
$hosts = Get-VMHost -Location $oClstr -Server:$svr;
foreach($item in $hosts)
{
$sMsg = "Processing host " + $item.Name + " in cluster " +$cluster + " on VC " +$VC;
write-host $sMsg;
}
$HostView = Get-VMHost $hosts | Get-View
$HostStorageSystemID = $HostView.configmanager.StorageSystem
$HostiSCSISoftwareAdapterHBAID = ($HostView.config.storagedevice.HostBusAdapter | where {$_.Model -match "iSCSI Software"}).device
$options = New-Object VMWare.Vim.HostInternetScsiHbaParamValue[] (1)
$options[0] = New-Object VMware.Vim.HostInternetScsiHbaParamValue
$options[0].key = "DelayedAck"
$options[0].value = $false
$HostStorageSystem = Get-View -ID $HostStorageSystemID
$HostStorageSystem.UpdateInternetScsiAdvancedOptions($HostiSCSISoftwareAdapterHBAID, $null, $options)
Your foreach loop does not include the method call.
You should use $item (a single ESXi node) and not $hosts (all ESXi nodes in the cluster) inside the foreach loop.
Try like this
[parameter(Mandatory = $true
, HelpMessage = "VC Name")]
[string] $VC
, [parameter(Mandatory = $true
, HelpMessage = "Cluster Name")]
[string] $cluster
)
$svr = $null;
$svr = Connect-VIServer -Server $VC;
if ($svr -eq $null) {
$sMsg = "Unable to connect to VC " + $VC;
exit 1;
}
$sMsg = "Getting cluster " + $cluster + " on VC " + $VC;
Write-Host $sMsg;
$oClstr = $null;
$oClstr = Get-Cluster -Server:$svr -Name $cluster;
if ($oClstr -eq $null) {
$sMsg = "Unable to find cluster " + $cluster + " on VC " + $VC;
$iret1 = Disconnect-VIServer -Server:$svr -Confirm:$false -ErrorAction:SilentlyContinue;
exit 1;
}
$sMsg = "Getting hosts on cluster " + $cluster + " on VC " + $VC;
write-host $sMsg;
$options = New-Object VMWare.Vim.HostInternetScsiHbaParamValue[] (1)
$options[0] = New-Object VMware.Vim.HostInternetScsiHbaParamValue
$options[0].key = "DelayedAck"
$options[0].value = $false
$hosts = Get-VMHost -Location $oClstr -Server:$svr;
foreach ($item in $hosts) {
$sMsg = "Processing host " + $item.Name + " in cluster " + $cluster + " on VC " + $VC;
write-host $sMsg;
$HostStorageSystemID = $item.EXtensionData.configmanager.StorageSystem
$HostiSCSISoftwareAdapterHBAID = ($item.EXtensionData.config.storagedevice.HostBusAdapter |
where { $_.Model -match "iSCSI Software" }).device
$HostStorageSystem = Get-View -ID $HostStorageSystemID
$HostStorageSystem.UpdateInternetScsiAdvancedOptions($HostiSCSISoftwareAdapterHBAID, $null, $options)
}
Blog: lucd.info Twitter: @LucD22 Co-author PowerCLI Reference
Your foreach loop does not include the method call.
You should use $item (a single ESXi node) and not $hosts (all ESXi nodes in the cluster) inside the foreach loop.
Try like this
[parameter(Mandatory = $true
, HelpMessage = "VC Name")]
[string] $VC
, [parameter(Mandatory = $true
, HelpMessage = "Cluster Name")]
[string] $cluster
)
$svr = $null;
$svr = Connect-VIServer -Server $VC;
if ($svr -eq $null) {
$sMsg = "Unable to connect to VC " + $VC;
exit 1;
}
$sMsg = "Getting cluster " + $cluster + " on VC " + $VC;
Write-Host $sMsg;
$oClstr = $null;
$oClstr = Get-Cluster -Server:$svr -Name $cluster;
if ($oClstr -eq $null) {
$sMsg = "Unable to find cluster " + $cluster + " on VC " + $VC;
$iret1 = Disconnect-VIServer -Server:$svr -Confirm:$false -ErrorAction:SilentlyContinue;
exit 1;
}
$sMsg = "Getting hosts on cluster " + $cluster + " on VC " + $VC;
write-host $sMsg;
$options = New-Object VMWare.Vim.HostInternetScsiHbaParamValue[] (1)
$options[0] = New-Object VMware.Vim.HostInternetScsiHbaParamValue
$options[0].key = "DelayedAck"
$options[0].value = $false
$hosts = Get-VMHost -Location $oClstr -Server:$svr;
foreach ($item in $hosts) {
$sMsg = "Processing host " + $item.Name + " in cluster " + $cluster + " on VC " + $VC;
write-host $sMsg;
$HostStorageSystemID = $item.EXtensionData.configmanager.StorageSystem
$HostiSCSISoftwareAdapterHBAID = ($item.EXtensionData.config.storagedevice.HostBusAdapter |
where { $_.Model -match "iSCSI Software" }).device
$HostStorageSystem = Get-View -ID $HostStorageSystemID
$HostStorageSystem.UpdateInternetScsiAdvancedOptions($HostiSCSISoftwareAdapterHBAID, $null, $options)
}
Blog: lucd.info Twitter: @LucD22 Co-author PowerCLI Reference
LucD. As always, works like a charm! Thank you so much!
Hi LucD. I have a quick follow up question if you can. Is there a way to update the host profile using PowerCLI after delayed ack has been disabled on the hosts?
And would it make sense to combine both scripts or have them separate?
You should be able to update the HostProfile with the Set-VMHostProfile cmdlet, and reference an ESXi node for which you just changed the delayed ack.
Note that all other properties in the HostProfile will also be overwritten by the current settings of that ESXi node.
Blog: lucd.info Twitter: @LucD22 Co-author PowerCLI Reference
Yep. Good point. Thanks again.
Sorry one last question. I was able to achieve updating the profile from reference host OK using this:
**************************************************************************
$Profile = Get-VMHostProfile
$Spec = New-Object VMware.Vim.HostProfileHostBasedConfigSpec
$Spec.Host = New-Object VMware.Vim.ManagedObjectReference
$Spec.Host = $Profile.ReferenceHost.ExtensionData.MoRef
$Spec.useHostProfileEngine = $true
$Profile.ExtensionData.UpdateHostProfile($Spec)
**************************************************************************
But is there a way to have only the changed setting to be overwritten?
Not with a cmdlet I'm afraid.
You could fall back to using the API method UpdateHostProfile, but the problem might be that the layout of the object you need to update is not documented.
It will require some reverse engineering.
Similar to what I did in Change The Root Password In Hosts And Host Profiles
Blog: lucd.info Twitter: @LucD22 Co-author PowerCLI Reference
OK. Again, appreciate all your help. Thank you.