PowerCLI: Automating traffic shaping on portgroups

I was contacted by someone who needed to automate some changes to their virtual infrastructure, I can never resist a challenge so of course I agreed to help.

He worked for a Virtual Hosting platform who offer hosting at a low cost of entry.  Each customer where he works is provided with a dedicated  virtual machine, a public IP space in a logical VLAN.   As such his platform is currently 9 hosts, 190 VM’s and 60 Portgroups/VLAN’s. The platform is based on HP c700 Chassis with Cisco 3020 gig switches, with each “half” of the chassis trunked back to our core with a 2Gbps etherchannel. Each Blade’s “production” interface is connected to each “half” of the chassis at 1Gbps with originating VM id based load balancing.

He explained that all was working fine until they hit upon an issue, what prompted the change in policy was a compromised VM (not everything has perimeter firewalling as per standard purchase, this is down to the customers choice) pushing upwards of 900MBps out our primary International gateway causing heavy packet loss for the rest of the DC.

Whilst the traffic shaping options for VI3 are only outbound it will at least prevent this occurrence again.

At an estimate he said it would have taken a minimum of nine hours to do this manually using the VIC, not to mention mind numbing and prone to error.

Following a simple bit of script work it only took 2hrs for the script to run so I thought I would add it to my blog just in case anyone else gets into a similar position and would like to save themselves some work !

As a side note, all customer PortGroups in this case were on vSwitch1, although the script can be easily adjusted to make the change for all vSwitches.

Foreach ($VMHost in Get-VMHost) {
    Write "$VMHost"
    Foreach ($PG in ($VMHost | Get-VirtualSwitch -Name "vSwitch1" | Get-VirtualPortGroup)){
        $vswitchName = "vSwitch1"
        $pgName = $PG.Name

        Write "...$pgName"
        $HS = $VMHost | Get-View
        $nwSys = $HS.ConfigManager.NetworkSystem
        $mor = Get-View $nwSys

        $portgrp = New-Object VMware.Vim.HostPortGroupSpec
        $portgrp.Name = $pgName
        $portgrp.VswitchName = $vswitchName
        $portgrp.policy = New-Object VMware.Vim.HostNetworkPolicy
        $portgrp.policy.shapingPolicy = New-Object VMware.Vim.HostNetworkTrafficShapingPolicy
        $portgrp.policy.shapingPolicy.enabled = $true
        $portgrp.policy.shapingPolicy.averageBandwidth = 104857600000
        $portgrp.policy.shapingPolicy.peakBandwidth = 104857600000
        $portgrp.policy.shapingPolicy.burstSize = 107374182400

        $mor.UpdatePortGroup($pgName, $portgrp)
    }
}

The result of all this would be the same settings applied to each portgroup as below:

image

This script can easily be added to the VESI/PowerGUI Powerpack where you can manually select the portgroups and mass apply the changes with a simple action.

image

5 thoughts on “PowerCLI: Automating traffic shaping on portgroups

  1. Jon Atkinson

    hi. This has been working fine for years now but I recently upgraded to powercli 6.5.0.234 and I now get the following –

    Cannot convert argument “portgrp”, with value: “VMware.Vim.HostPortGroupSpec”, for “UpdatePortGroup” to type
    “VMware.Vim.HostPortGroupSpec”: “Cannot convert the “VMware.Vim.HostPortGroupSpec” value of type
    “VMware.Vim.HostPortGroupSpec” to type “VMware.Vim.HostPortGroupSpec”.”
    At line:1 char:9
    + $mor.UpdatePortGroup($pgName, $portgrp)
    + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    + CategoryInfo : NotSpecified: (:) [], MethodException
    + FullyQualifiedErrorId : MethodArgumentConversionInvalidCastArgument

  2. Ofir Zvik

    here is the script with correction for the vlanId issue + limits the traffic for 100mbit/sec + auto connect to the VC with it’s local

    $VC = Get-VC -Server localhost

    Foreach ($VMHost in Get-VMHost) {
    Write “$VMHost”
    Foreach ($PG in ($VMHost | Get-VirtualSwitch -Name “vSwitch0” | Get-VirtualPortGroup)){
    $vswitchName = “vSwitch0”
    $pgName = $PG.Name
    $vlanID = $PG.VLanId

    Write “…$pgName”
    $HS = $VMHost | Get-View
    $nwSys = $HS.ConfigManager.NetworkSystem
    $mor = Get-View $nwSys

    $portgrp = New-Object VMware.Vim.HostPortGroupSpec
    $portgrp.Name = $pgName
    $portgrp.VswitchName = $vswitchName
    $portgrp.policy = New-Object VMware.Vim.HostNetworkPolicy
    $portgrp.policy.shapingPolicy = New-Object VMware.Vim.HostNetworkTrafficShapingPolicy
    $portgrp.policy.shapingPolicy.enabled = $true
    $portgrp.policy.shapingPolicy.averageBandwidth = 100000000
    $portgrp.policy.shapingPolicy.peakBandwidth = 100000000
    $portgrp.policy.shapingPolicy.burstSize = 10240000
    $portgrp.VLanId = $vlanID

    $mor.UpdatePortGroup($pgName, $portgrp)
    }
    }

  3. Nigel Hardy

    I think that, as written, the script will lose any VLAN setting you have for the portgroups being changed as there’s no VlanId property set in the new HostPortGroupSpec. That could be a bad thing.

  4. Darren

    Darn it, ignore my previous comment.

    Script works absolutley fine IF you remember to change BOTH occurances of vSwitch1 to vSwitch0.

    (thwack) – loud noise of beating myself over the head with a printed copy of the PowerCLI commands.

    Cheers,
    Darren.

  5. Darren

    Hi Alan.

    When I copy / paste the code into PowerGui Script Editor the execute I receive this message.

    “Exception calling “UpdatePortGroup” with “2” argument(s): “A specified parameter was not correct.
    Vim.Host.PortGroup::Specification::vswitchId”
    At :line:22 char:28
    + $mor.UpdatePortGroup <<<< ($pgName, $portgrp)"

    Are you able to clarify why this message appears? Or, is this script part of a larger piece of code hence I'm missing something?

    Cheers,
    Darren.
    (@dawoo)

Leave a Reply

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.