Search Tools Links Login

Managing Portgroups with PowerCLI

If your VMware implementation contains more than a few hosts, managing portgroups (or any multi-host settings) can be a real pain. In order to take advantage of cool things like vMotion, your portgroups need to match across all hosts in the cluster. If one of them is mispelled, or has a bad VLAN tag, it's a no-go.

By using a script, you can apply a add/change to all hosts in a cluster, vastly reducing the chances of that hard to find typo that will bork you. As an added bonus, you'll get your portgroups updated in vastly reduced time.

Recently, I began on a journey to standardize names of port groups across all the VMware clusters that I manage. Mainly for standardization of processes and procedures. Also, I am trying to prepare the virtual landscape for movement to a private cloud model. This standardization of network names across the 9 or so clusters is a good start.

My largest single cluster, the labs, contains 16 hosts. Each host contains 8 VLANS, for seperation of various lab environments, some fenced, most not. I drafted up this handy little table that shows current state and where I want to be:

VLAN IDOld PG NameNew PG Name
10prod-10net0010 Production
12QALabs120012 LAB QA 1
29CVLAN290029 Client
26CVLAN260026 Client
214SIT2140214 LAB UAT
314SIT3140314 LAB SIT
414infra4140414 LAB Infrastructure
514PerfTest5140514 LAB Performance Testing

So, I know the what the current VLAN and name information is for each portgroup, and what I want it to be called when I am done. Good - step 1 complete. Now, we have a few more steps to complete:

Why not just rename the existing portgroups? Much easier, right? Glad you asked!

Each guest VM holds its configuration in a VMX file. This file describes the virtual hardware configuration of the guest VM. Things like vCPU count, Memory size, VMDK location, and what network to use. By simply changing the name of the portgroup, the guest configurations are not updated. You would have to change all the VMs to point to the new network!

You could automate that with some of the knowledge I'm going to lay on you below, but I think it is a bit less intrusive to the users if you first create a new set of portgroups, then update the VMs with the new info.

For this exercise, I am going to be using PowerCLI. VMware vSphere PowerCLI is a powerful command line tool that lets you automate all aspects of vSphere management, including network, storage, VM, guest OS and more, all in a PowerShell snapin. If you haven't gotten your hands on it, go get it now!

Once you get PowerCLI installed, connect to your vCenter server:

Connect-VIServer -Server -Protocol https -User admin -Password mypass

Of course, you'll need to put your account information in the proper places. Once you get connected, you now have a PowerShell interface to all the hosts and clusters that your account has access to, with a ton of great cmdlets at your disposal.

The cmdlet we are interested for adding new portgroups is new-VirtualPortGroup. A single host example of adding a portgroup to a vswitch looks something like this:

get-vmhost -name | Get-VirtualSwitch -name vSwitch0 | new-VirtualPortGroup -name "4010 LAB MyLabSpace" -vlanid 4010

Typing this command at your PowerCLI prompt will add a new portgroup called 4010 LAB MyLabSpace to vSwitch0, with a VLAN tag of 4010. Ok, that's pretty neat. This definitely cuts the amount of time needed to add a portgroups to hosts. You could type this up into notepad, with all the necessary host information, ending with 16 lines of code you could then paste into the PowerCLI window.

But there is a better way. How about poking the information into all the hosts in a particular cluster, with one line of PowerShell goodness? This bit of code will add a portgroup with VLAN id, to a named vSwitch on all hosts in a named cluster:

foreach ($esx in get-VMhost -Location "TargetClusterName" | sort Name) { $esx | Get-VirtualSwitch -Name "vSwitchName" | New-VirtualPortGroup -Name "New PortGroup Name" -VlanId 123 }

If you've worked with PowerShell, you should recognize what is going on here. But for those who may not be familar, I'll explain a bit. First, if you are copy/pasting this code, you'll need to modify a few values before you run it.

Once you have all the information in there, run it. The code retrieves all the host names in the cluster, sorted by name, then proceeds to add the portgroup to each host. Repeat this for each new portgroup you want to add. You could encapsulate this further by having PowerShell read a list of portgroups to add from a file, and fully automate the process. Pretty slick, and step two complete.

Before we move on to moving the clients, you might want to know how to break this command out. This would be handy if you want to include this workflow in a larger script. Basically, we are going to use variables to define our switch values, thus:

$Cluster = "Target Cluster Name"
$vSwitch = "Target vSwitch Name"
$NPG = "Name of new Portgroup"
Get-Cluster -Name $Cluster | Get-VMHost | foreach { New-VirtualPortGroup -VirtualSwitch ( Get-VirtualSwitch -Name $vSwitch -VMHost $_ ) -Name $NPG -VLanId $vlan }

Using this, you could potentially have the script ask for the needed values from the user running the script, or this would be first step in reading the values from a CSV file. Go forth and do good!

Provided you didn't make any typos, you now have at least one new, empty portgroup on all the hosts in your cluster. Now, on to step 3, moving the guest VMs to the new portgroup.

Once again, you can change individual machines, but that would take a bit long, I think. But, if you want to test with one machine (which you should), you'd use the Set-NetworkAdapter cmdlet, like this:

Get-VM VMName | Get-NetworkAdapter | Set-NetworkAdapter -NetworkName "PortGroup Name"

Easy enough. Set focus to the VM, then the network adapter, then set the name. Pretty easy to do, for one or two guest virtual machines.

As mentioned previously, the cluster I am working with contains sixteen hosts, and currently carries around 500 guest virtual machines. I am not going to use the above method to change 500 VMs. PowerShell to the rescue! Here is the code to change all guests using a named network to the new network:

$Cluster = "My Cluster Name"
$OldNetwork = "Old Network Name"
$NewNetwork = "New Network Name"
Get-Cluster $Cluster |Get-VM |Get-NetworkAdapter |Where {$_.NetworkName -eq $OldNetwork } |Set-NetworkAdapter -NetworkName $NewNetwork -Confirm:$false

As you can see, the above code is ready for inclusion into a larger script. For the "one-line" method, simply place your values directly in the last line of the code. Be sure and change the values where applicable, though. Otherwise, you'll see a bunch of red errors because PowerShell is not happy with your input! If all is well, your new portgroups will be full of guest VMs, and your old portgroups will be emptied in a matter of minutes rather than days.

By now, you should see pattern to these scripts. They are pretty basic, but very powerful. With these bits of code, you have the potential to easily administer your entire environment, or shoot yourself in the foot.

This next piece of code is especially dangerous, especially if you stick it in a loop. You could accidentally blow away the wrong thing, so be careful!

Get-VirtualPortGroup -VMHost "Host" -name "PortGroupName" | Remove-VirtualPortGroup -confirm:$false

This chunk of code will remove the named portgroup from the specified host, without confirmation. BE CAREFUL! I can't reiterate that enough. Test in a safe area before you start working in a production environment. If you mistype something and delete the wrong thing, it's your own fault.

So, that's it. I hope this little bit of knowledge will help you in automating your VMware environment. At the very least, the points and method brought up in this article should get you started down that path.

Happy coding, and may your packets keep flowing!

About this post

Posted: 2012-06-02
By: dwirch
Viewed: 16,310 times



VMWare Products




No attachments for this post

Loading Comments ...


No comments have been added for this post.

You must be logged in to make a comment.