Automating vSphere Replication Bandwidth Limits with PowerCLI

If you’re running vSphere Replication on vSphere 5.5 and also have access to the vSphere Distributed Switch (VDS) – this one’s for you. One of my pet peeves with vSphere Replication (VR) is that there is no inherent way to control or limit the replication bandwidth. There are often times where you might find it advantageous to throttle bandwidth – such as during a backup window or critical business hour.

The two major ways to exercise limits on replication outside of VR are:

  1. Use Network IO Control (NIOC) on a VDS, specifically the vSphere Replication network resource pool
  2. Enable L4 Quality of Service on your network for ports 31031 (initial replication) and 44046 (on-going replication) – (source)

When someone has the VDS, I usually lean towards option 1. It’s simple to do and requires little fuss on the network. It’s also controlling traffic right at the source, since NIOC only affects outbound traffic. But what about controlling the limits programmatically? It stands to reason that you’d probably want to automate the controls to turn them on when needed and off when not, right? Maybe even have a VR limit based on some external trigger?

I wrote a little PowerCLI code that you can use as-is or plug into something else you’re working on. It’s available on GitHub here and I’ve also embedded the code below. Huge kudos to scripting MVP Luc Dekens for his contribution on the commented section when I pinged him on Twitter.

[sourcecode language=”powershell”]
cls
<#
vSphere Replication Limits
Scriptable way to toggle your VR bandwidth cap for day, night, weekend, or whatever
Args usage = PSfile "vcenter name" "VDS name to configure" "Mbps limit value"
#>

# Variables
$vcenter = $args[0]
$dvsName = $args[1]
$rpName = "vSphere Replication"
# Set to -1 to go back to unlimited
$newLimit = $args[2]

# Connect to vCenter
If (-not $global:DefaultVIServer) {Connect-VIServer -Server $vcenter}

# Check args
if (-not $args[2])
{
throw "Incorrect format. Provide the vCenter name, VDS name, and limit in Mbps. Example: `"script `"vCenterFQDN`" `"VDS1`" 500`" would set VR bandwidth on VDS1 to 500 Mbps"
exit
}

# Get the VDS details
$dvs = Get-VDSwitch -Name $dvsName

# Set the VR network pool to the value provided in args
# The section below was written by Luc Dekens (@LucD22), all credit to him
$rp = $dvs.ExtensionData.NetworkResourcePool | Where {$_.Name -match $rpName}
if($rp){
$spec = New-Object VMware.Vim.DVSNetworkResourcePoolConfigSpec
$spec.AllocationInfo = $rp.AllocationInfo
$spec.AllocationInfo.Limit = [long]$newLimit
$spec.ConfigVersion = $rp.ConfigVersion
$spec.Key = $rp.Key
$dvs.ExtensionData.UpdateNetworkResourcePool(@($spec))
}

# Verify
$rp = $dvs.ExtensionData.NetworkResourcePool | Where {$_.Name -match $rpName}
Write-Host "A limit of" $rp.AllocationInfo.Limit "Mbps has been set on $dvs"[/sourcecode]