Home > NetApp, PowerCLI, Powershell > Disk timeout settings in registry for VMs using PowerCLI

Disk timeout settings in registry for VMs using PowerCLI

September 1st, 2010

One of NetApp’s best practices is to increase the disk timeout settings for VMs to 190 seconds so VMs don’t blue screen if they temporary lose connectivity to their disks say during a cluster failover.

This is done by amending the Disk Timeout registry value:
HKLM\SYSTEM\CurrentControlSet\Services\Disk\TimeoutValue to DWord 190.

I’m sure you’d love to go through all your VMs and load regedit manually so why not grab a list of VMs using PowerCLI and set the registry value.

The VMs will obviously need to be powered on and you will need permissions to be able to write to the registry.

The procedure is a 2 step process:

The first is to get all the VMs you want to change.
You can use any Get-VM statement you want:

All VMs in a particular Resource Pool

$VMs = Get-VM -Location (Get-ResourcePool "Resource_Pool_Prod") | Where { $_.PowerState -eq "PoweredOn" }

or

$VMs = Get-ResourcePool "Resource_Pool_Prod" | Get-VM | Where { $_.PowerState -eq "PoweredOn" }

All VMs in a particular Cluster

$VMs = Get-Cluster "LON_PROD1" | Get-VM | Where { $_.PowerState -eq "PoweredOn" }

All VM names starting with WEBSERVER

$VMs = Get-VM "WEBSERVER*" | Where { $_.PowerState -eq "PoweredOn" }

The second stage is to work some registry magic for the VMs you have.

You can then read the current registry value:

ForEach ($VM in $VMs) {
	$reg = [Microsoft.Win32.RegistryKey]::OpenRemoteBaseKey('LocalMachine', $VM.Guest.Hostname)
	Write-Host "Registry Value for: "$VM.Guest.Hostname ": " $reg.OpenSubKey("SYSTEM\CurrentControlSet\Services\Disk\").GetValue("TimeoutValue")
}

To write the registry value:

ForEach ($VM in $VMs) {
	Write-Host "Setting Registry Value for: "$VM.Guest.Hostname
	$reg = [Microsoft.Win32.RegistryKey]::OpenRemoteBaseKey('LocalMachine', $VM.Guest.Hostname)
	$regKey= $reg.OpenSubKey("SYSTEM\CurrentControlSet\Services\Disk",$true)
	$regkey.SetValue('TimeoutValue',200,'DWord')
}

Or you can combine a read, set and verify.

ForEach ($VM in $VMs) {
	$reg = [Microsoft.Win32.RegistryKey]::OpenRemoteBaseKey('LocalMachine', $VM.Guest.Hostname)
	Write-Host "Registry Value Before: "$VM.Guest.HostName "-" $reg.OpenSubKey("SYSTEM\CurrentControlSet\Services\Disk\").GetValue("TimeoutValue")

	$regKey= $reg.OpenSubKey("SYSTEM\CurrentControlSet\Services\Disk",$true)
	$regkey.SetValue('TimeoutValue',190,'DWord')

	Write-Host "Registry Value After:  "$VM.Guest.HostName "-" $reg.OpenSubKey("SYSTEM\CurrentControlSet\Services\Disk\").GetValue("TimeoutValue")
}

or be bold and set it in a one liner:

Get-VM "WEBSERVER*" | Where { $_.PowerState -eq "PoweredOn" } | %{[Microsoft.Win32.RegistryKey]::OpenRemoteBaseKey('LocalMachine', $_.Guest.Hostname).OpenSubKey("SYSTEM\CurrentControlSet\Services\Disk",$true).SetValue('TimeoutValue',190,'DWord')}

Powershell…you gotta love it!

  1. HP
    January 18th, 2011 at 04:34 | #1

    Thank you!! This is a very helpful script!

  2. Newbie
    August 26th, 2011 at 12:58 | #2

    Hi, for some reason this is not working for me, using vsphere powercli (powershell v1) on a win XP PC and getting following error:

    Exception calling “OpenRemoteBaseKey” with “2” argument(s): “The network path was not found.

    At line:1 char:56
    + $reg = [Microsoft.Win32.RegistryKey]::OpenRemoteBaseKey( <<<< 'LocalMachine', $vm.Guest.Hostname)

    Thanks for any help

  3. Mark
    December 8th, 2011 at 18:12 | #3

    Thanks for this script! It helped a lot!

  1. No trackbacks yet.
Comments are closed.