Tuesday, November 17, 2015

Powershell script to change write caching policy (enable or disable) for multiple disks remotely

Following two similar PowerShell scripts allow to change write caching policy (enable or disable) for multiple disk devices remotely and for multiple servers. I have not found ready to go PowerShell cmdlet from Microsoft or MSFT Disk property which allowed to change write-caching policy for disks in easy way without manual human operation clicking with mouse in device/or disk manager. Just assume how it is convenient for multiple servers and disks...

1st PowerShell script will enable (or disable) write caching policy for Disk #1, Disk #2, Disk #3, ... , Disk #13, Disk #14 using Microsoft developed utility dskcache.exe in graceful manner (Windows Server 2008-2016).

Prerequsites


1. Download dskcache.exe utility from https://support.microsoft.com/kb/811392 (Product: Windows 2000, Platform x86)
2. Unpack and install it into the same file directory as PowerShell script ChangeWriteCaching.ps13. Local Administrator rights for local and remote server.
4. Enabled PowerShell remoting. For Windows 2012+ Windows PowerShell remoting is enabled by default.
For earlier Windows versions you might have it disabled check URL: https://technet.microsoft.com/en-us/magazine/ff700227.aspx


Download PowerShell script ChangeWriteCaching.ps1 from: https://gallery.technet.microsoft.com/Change-write-caching-576747ad


Second one PowerShell script below will enable (or disable) write-caching policy for Disk #1, Disk #2, Disk #3, ... , Disk #13, Disk #14 using PowerShell only on remote servers (Windows 2012+).
Note: This particular script will restart target server at the end
$DiskNumbersToModify = (1..14)
$servers="server1","server2","server3","server4","server5","server6"

# CacheIsPowerProtected parameter in most cases would be "0"
$CacheIsPowerProtected=0
# "1" turns on write-caching policy, "0" turns off write-caching policy
$UserWriteCacheSetting=1

foreach ($server in $servers)
    {
    $cimsession=New-CimSession -ComputerName $server
    $PSSession = New-PSSession -ComputerName $server
    foreach ($DiskN in $DiskNumbersToModify)
        {
        $DiskName=(Get-Disk -Number $DiskN -cimsession $cimsession).FriendlyName
        $DiskSN=(Get-Disk -Number $DiskN -cimsession $cimsession).SerialNumber
        $DiskPath=(Get-Disk -Number $DiskN -cimsession $cimsession).Path
        $RegistryPath="HKLM:\SYSTEM\CurrentControlSet\Enum"
        $DiskType=$DiskPath.split([char]0x003F,[char]0x0023)
        $RegistryPath+=($DiskType[1]+"\"+$Disktype[2]+"\"+$Disktype[3]+"\Device Parameters\Disk")
        Invoke-Command -Session $PSSession -ArgumentList $registryPath,$CacheIsPowerProtected,$UserWriteCacheSetting -ScriptBlock  {param($registryPath,$CacheIsPowerProtected,$UserWriteCacheSetting);
        IF(!(Test-Path ($registryPath))) {New-Item -Path $registryPath -Force};          
        New-ItemProperty -Path $registryPath -Name "CacheIsPowerProtected" -Value $CacheIsPowerProtected -PropertyType DWORD -Force -Confirm:$false | Out-Null;
        New-ItemProperty -Path $registryPath -Name "UserWriteCacheSetting" -Value $UserWriteCacheSetting -PropertyType DWORD -Force -Confirm:$false | Out-Null;}
        Write-Host $server "Write-caching policy for disk" ($DiskName+":"+$DiskSN) "DiskNumer:" $DiskN "has been changed" -ForegroundColor Green
        }
    Remove-PSSession -session $PSSession
    Restart-Computer -ComputerName $server -force
    }  

For some storage controllers like RAID changing parameter UserWriteCacheSetting for connected disks may have no effect because of caching policy is being managed by storage controller settings.