Archive

Posts Tagged ‘disks’

Disk timeout settings in registry for VMs using PowerCLI

September 1st, 2010 3 comments

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!