Home > Virtualization, Windows > Set Guest OS I/O Timeout Settings via PowerShell

Set Guest OS I/O Timeout Settings via PowerShell

Back in October 2009, I wrote a post on how to remotely set the TimeoutValue for the Disk service in Windows per NetApp’s best practices.  It is kind of a pain to grab a list of VM’s, make a bunch of batch files, call them, and so on.

I was playing around with the PSRemoteRegistry PowerShell module, and figured out a better way of doing it… Using PowerShell.

To make this work
A few things are needed:

  • PowerShell 2.0
  • vSphere PowerCLI
  • PSRemoteRegistry
  • vCenter Server and appropriate access by the account running the script
  • Connectivity to the Guest as the changes are made via a remote registry call
  • Credentials in the VM to make changes using the same account running the script
  • Run this script from the vSphere PowerCLI

The Workflow
The script will basically need to enumerate all VM’s, perform a registry query to see if the TimeoutValue exists, and depending on what the result is, either update the setting or create it if it does not exist.  Because this only relates to Windows OSes, I chose to only look at VM’s running Windows.  Also, no point in attempting the update on a VM that isn’t powered on, given that I’m making a remote registry call.

The PowerShell functions that help with the process are Test-RegValue and Set-DWord, both of which are part of the Remote Registry PowerShell Module.  I’m not going to go into the syntax of these functions, but more information can be found on them using Get-Help Test-RegValue and Get-Help Set-DWord once the PSRemoteRegistry module is loaded.

Two variables I’m using are $tovdec and $tovhex which are TimeOut Value in Decimal and TimeOut Value in Hexadecimal.  These can easily be changed to a value that is appropriate with whatever storage is being used, based on the recommendations of the storage vendor (NetApp, EMC, etc).

The Script
Here is the script I came up with:

##########################################################
# correctvmtimeout.ps1
# Jase McCarty 4/29/2010
# Posh Script to set/correct TimeoutValue
# in Windows Virtual Machines
##########################################################

#Import the PSRemoteRegistry
Import-Module PSRemoteRegistry

#Connect to vCenter Server
Connect-VIServer MYvCenterServer

# Specify the Hive, RegKey, and DWORD Value
$Hive = "LocalMachine"
$DiskKey = "SYSTEM\CurrentControlSet\Services\Disk"
$tovdec = "190"
$tovhex = "0xBE"

# Get only Windows VM's that are Powered On and are Windows Guests
Get-VM | Sort-Object Name | Where { $_.PowerState -eq "PoweredOn" } | %{get-view $_.ID} | Foreach {If ($_.guest.GuestFamily -eq "windowsGuest") {

     # Check to see if the value is present, and if it is, what is the value
     $Key = Test-RegValue -CN $_.Name -Hive $Hive -Key $DiskKey -Value TimeoutValue -PassThru

     If ($Key -eq $false) {
          Write-Host $_.Name,incorrect,missing,correcting
          Set-RegDWord -CN $strComputer -Hive $Hive -Key $DiskKey -Value TimeoutValue -Data $tovhex -Force
          }
else {
          If ($Key.Data -eq $tovdec) {
              Write-Host $Key.ComputerName, correct,$Key.Data
          }
          else    {
             Write-Host $Key.ComputerName,incorrect,$Key.Data,correcting
             Set-RegDWord -CN $Key.ComputerName -Hive $Hive -Key $DiskKey -Value TimeoutValue -Data $tovhex -Force
          }
       }
    }
}

I hope this helps anyone looking to perform a mass update of the TimeoutValue registry setting.  Additionally, this could be integrated into a config/check script that is run from time to time to ensure that all VM’s are held in compliance to the appropriate values a storage vendor recommends.

I have a couple different types of storage, so maybe I will add some additional logic to determine the storage provider, and adjust accordingly… Now to find the time to do it.

And many thanks to Shay Levy for the work on the PSRemoteRegistry module!

  1. May 1st, 2010 at 19:36 | #1

    Hi,

    Nice script! One note if someone is copying/pasting the example, the $Hive = “LocalMachine” is commented out accidently it appears.

    -Rod

  2. August 23rd, 2010 at 13:26 | #4

    Nicely done! I posted a very similar script (it does the same thing) back on January 09 on the Netapp Community forums.

    http://communities.netapp.com/docs/DOC-2025

    I don’t really consider myself a master script writer (more of a copy and paster) so I always love seeing how other people come up with the same solution. Keep up the great work!

    • August 23rd, 2010 at 21:05 | #5

      I took a look at your script.

      Nice… A little more work than mine.

      I just wanted something quick and easy, but you did nicely.

  3. March 29th, 2012 at 00:47 | #6

    I just tried running this script across a single VM and i get the below error

    Set-RegDWord : Key ‘SYSTEMCurrentControlSetServicesDisk’ doesn’t exist.
    At E:\Scripts\diskiotest.ps1:21 char:23
    + Set-RegDWord <<<< -CN $strComputer -Hive $Hive -Key $DiskKey -Valu
    e TimeoutValue -Data $tovhex -Force
    + CategoryInfo : NotSpecified: (:) [Write-Error], WriteErrorExcep
    tion
    + FullyQualifiedErrorId : Microsoft.PowerShell.Commands.WriteErrorExceptio
    n,Set-RegDWord

    Any suggestion?

    • jase
      March 29th, 2012 at 06:47 | #7

      Actually, I was missing the slashes (\) in the $DiskKey variable.

      I have corrected the script.

      Thanks for the heads up!
      Jase

  1. April 30th, 2010 at 09:13 | #1
  2. April 30th, 2010 at 21:27 | #2
  3. May 1st, 2010 at 19:56 | #3
  4. May 14th, 2010 at 22:28 | #4
  5. November 30th, 2010 at 16:44 | #5
  6. May 1st, 2011 at 23:40 | #6
  7. February 23rd, 2012 at 20:22 | #7