UPDATE - 23 JAN 2017: I ran into an issue with the script managing uninitialized SnapMirror relationships; so I have updated the script to include logic for addressing this issue.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
################################################################################ | |
# Author: MikeTheTechGeek # | |
# Version: 1.2 # | |
# # | |
# Scenario: Auto throttling on CDOT SnapMirrors, where throttling is reset to # | |
# unlimited by third-party application (like SnapProtect). # | |
# Created scheduled task on a server with NetApp Powershell Toolkit installed # | |
# to run every 15-60 seconds # | |
################################################################################ | |
#Module import | |
Import-Module DataONTAP | |
#CDOT cluster connection info | |
$cluster = "cluster.domain.local" | |
$user = "********" | |
$pass = "********" | ConvertTo-SecureString -AsPlainText -Force | |
$creds = New-Object System.Management.Automation.PsCredential($user, $pass) | |
$connect = Connect-NcController $cluster -Credential $creds | |
#Max allowed throttle in kilobytes / second (100 megabits/sec = 12500 kilobytes/sec) | |
[Int]$throttle = 62500 * 1024 | |
#Collects all SnapMirrors on cluster | |
$SnapMirrors = Get-NcSnapmirror | |
#Determines SnapMirrors that are running | |
$RunningSnapMirrors = $SnapMirrors | Where-Object {($_.Status -eq "transferring")} | |
#Determines SnapMirrors that are running without a throttle set 0 = unlimited | |
$RunningWOThrottle = $RunningSnapMirrors | Where-Object {$_.MaxTransferRate -eq 0} | |
#Determines total number of running SnapMirrors | |
$count = $RunningSnapMirrors.count | |
#If statement to check for running SnapMirrors | |
If ($count -gt 0) { | |
#Calculate currently running SnapMirrors total MaxTransferRate | |
$CurrentRate = $RunningSnapMirrors | Measure-Object -sum MaxTransferRate | |
#Calculate theortical additonal transfer rate added for any SnapMirrors running currently without throttling | |
$AddRate = $RunningWOThrottle.count * 10240000 | |
#Calculate total theortical transfer rate both current and additional | |
$SumRate = $CurrentRate.Sum + $AddRate | |
#Switch Statement to determine throttle conditions based of SumRate | |
switch ($SumRate) | |
{ | |
#If SumRate is less than allowed throttle and has SnapMirrors running without throttling | |
{(($_ -lt ($throttle + 1)) -and ($RunningWOThrottle.count -gt 0))} | |
{ | |
#Set throttling on SnapMirrors running without throttle; default max transfer rate | |
[Void]($RunningWOThrottle | Set-NcSnapmirror -MaxTransferRate 10240000) | |
#Abort SnapMirrors running without throttle | |
[Void]($RunningWOThrottle | Invoke-NcSnapmirrorAbort) | |
#Pause for 5 seconds | |
Start-Sleep -Seconds 5 | |
#Start previously aborted SnapMirrors now with throttling | |
foreach ($mirror in $RunningWOThrottle) | |
{ | |
if ($mirror.MirrorState -eq "Snapmirrored") | |
{ [Void]($mirror | Invoke-NcSnapmirrorUpdate -MaxTransferRate 10240000) } | |
ElseIf ($mirror.MirrorState -eq "Uninitialized") | |
{ [Void]($mirror | Invoke-NcSnapmirrorInitialize -MaxTransferRate 10240000) } | |
} | |
} | |
#If SumRate is greater than allowed throttle and has SnapMirrors running without throttling, or if SumRate is greater than allowed throttle and all SnapMirrors are throttled | |
{(($_ -gt $throttle) -and ($RunningWOThrottle.count -gt 0)) -or (($_ -gt $throttle) -and ($RunningWOThrottle.count -eq 0))} | |
{ | |
#Calculate max transfer rate for each running SnapMirror based of max allowed transfer and number of running SnapMirrors | |
$avgThrottle = [Int64]($throttle / $count) | |
#Set throttling on all running SnapMirrors based on above calculation | |
[Void]($RunningSnapMirrors | Set-NcSnapmirror -MaxTransferRate $avgThrottle) | |
#Abort all running SnapMirrors | |
[Void]($RunningSnapMirrors | Invoke-NcSnapmirrorAbort) | |
#Pause for 5 seconds | |
Start-Sleep -Seconds 5 | |
#Start previously aborted SnapMirrors now with throttling | |
foreach ($mirror in $RunningSnapMirrors) | |
{ | |
if ($mirror.MirrorState -eq "Snapmirrored") | |
{ [Void]($mirror | Invoke-NcSnapmirrorUpdate -MaxTransferRate $avgThrottle) } | |
ElseIf ($mirror.MirrorState -eq "Uninitialized") | |
{ [Void]($mirror | Invoke-NcSnapmirrorInitialize -MaxTransferRate $avgThrottle) } | |
} | |
} | |
#If SumRate is less than half allowed throttle and has no SnapMirrors running without throttling | |
{(($_ -lt (($throttle*.75)+1)) -and ($RunningWOThrottle.count -eq 0))} | |
{ | |
#Calculate max transfer rate for each running SnapMirror based of max allowed transfer and number of running SnapMirrors | |
$avgThrottle = [Int64]($throttle / $count) | |
#Set throttling on all running SnapMirrors based on above calculation | |
[Void]($RunningSnapMirrors | Set-NcSnapmirror -MaxTransferRate $avgThrottle) | |
#Abort all running SnapMirrors | |
[Void]($RunningSnapMirrors | Invoke-NcSnapmirrorAbort) | |
#Pause for 5 seconds | |
Start-Sleep -Seconds 5 | |
#Start previously aborted SnapMirrors now with throttling | |
foreach ($mirror in $RunningSnapMirrors) | |
{ | |
if ($mirror.MirrorState -eq "Snapmirrored") | |
{ [Void]($mirror | Invoke-NcSnapmirrorUpdate -MaxTransferRate $avgThrottle) } | |
ElseIf ($mirror.MirrorState -eq "Uninitialized") | |
{ [Void]($mirror | Invoke-NcSnapmirrorInitialize -MaxTransferRate $avgThrottle) } | |
} | |
} | |
#Default switch | |
default {break} | |
} | |
} |