Customisation: Lesson 4 – PortGroups

Lessons so far in this blog post series:

So, we now have our host added to virtual center, we have it syncing the time with our central time server, we have the firewall adjusted to meet our needs and we have some virtual switches created, our vmotion vswitch and portgroup created and associated with some nics.  Now what ?

PortGroups !

As this will obviously be different for each configuration I will show you a couple of ways of doing this.  If your not starting to guess the format of the cmndlets by now then there is no hope, turn back and start again from lesson 1, if you can already guess the cmdlets we will be using then please continue to Go and collect £200.

Firstly lets think about why we may use the VI toolkit to do this, we know that consistency is the key in VMware, PortGroups need to be named exactly the same on each host and you need to make sure that each one is replicated to the new hosts if you have an existing cluster with existing hosts and PortGroups, Just imagine if you put a space in a portgroup name or misspelled ‘Production Network’ – BANG ! Vmotion doesnt work !

There are a nice couple of cmdlets to help us here called Get-VirtualPortGroup and New-VirtualPortGroup.

We could just use the New-VirtualPortgroup cmdlet to add all our new portgroups,  this would look something like the following:

$VMHost | Get-VirtualSwitch -Name vSwitch2 | New-VirtualPortGroup -Name Network 192.168.10.x-VLanId ‘16810

$VMHost | Get-VirtualSwitch -Name vSwitch2 | New-VirtualPortGroup -Name Network 192.168.12.x-VLanId 16812

etc etc for each PortGroup we needed, but what if we were adding a new host into a cluster that already existed ?!?  I have a neat trick for this !

We know we can read the Virtual Switches from a host using Get-VirtualSwitch and we know we can create virtual switches using New-VirtualSwitch equally we know we can read PortGroups using Get-VirtualPortGroup and we know we can create virtual PortGroups using New-VirtualPortgroup so wouldn’t it make more sense to base our configuration on a host that already exists and pull both the Virtual Switches and the PortGroups from this host……

As if by magic…..

$BASEHost = Get-VMHost -Name

$BASEHost | Get-VirtualSwitch | Foreach {
If (($VMHost | Get-VirtualSwitch -Name $_.Name -ErrorAction SilentlyContinue) -eq $null){
Write-Host Creating Virtual Switch $($_.Name)
$NewSwitch = $VMHost | New-VirtualSwitch -Name $_.Name -NumPorts $_.NumPorts -Mtu $_.Mtu
$vSwitch = $_
$_ | Get-VirtualPortGroup | Foreach {
If (($VMHost | Get-VirtualPortGroup -Name $_.Name -ErrorAction SilentlyContinue) -eq $null){
Write-Host Creating Portgroup $($_.Name)
$NewPortGroup = $VMHost | Get-VirtualSwitch -Name $vSwitch | New-VirtualPortGroup -Name $_.Name -VLanId $_.VLanID

This short code block will read the existing vSwitch from a base host and check to see if it exists on the host we are configuring, if it doesn’t exist it will create it, once it has done this it will go through each PortGroup and check if these exist, creating them if they do not.

This obviously helps us with our consistency as our PortGroups will 100% be named the same and will definitely exist.  Why didnt I think of this from the start ?  We could read all of our info from an existing host and apply it to our new host !  I may have to put some more work into this and come up with a PowerShell version of Host Profiles 🙂

Our Script now becomes:

Connect-VIServer myviserver

$VMHost =

Remove-VMHostNtpServer -VMHost $VMHost -NtpServer

Add-VMHostNtpServer -VMHost $VMHost -NtpServer

Get-VmHostService -VMHost $VMHost |Where-Object {$_.key-eq ntpd} |Start-VMHostService

Get-VmhostFirewallException -VMHost $VMHost -Name NTP Client |Set-VMHostFirewallException -enabled:$true
Get-VmhostFirewallException -VMHost $VMHost -Name SNMP Server |Set-VMHostFirewallException -enabled:$true

New-VirtualSwitch -VMHost $VMHost -Name vSwitch1 -Nic nic1
$VMotionIP =
$VMotionSubnet =
New-VMHostNetworkAdapter -PortGroup VMotion -VirtualSwitch vSwitch1 -IP $VMotionIP -SubnetMask $VMotionSubnet -VMotionEnabled:$true

$BASEHost = Get-VMHost -Name

$BASEHost | Get-VirtualSwitch | Foreach {
If (($VMHost | Get-VirtualSwitch -Name $_.Name -ErrorAction SilentlyContinue) -eq $null){
Write-Host Creating Virtual Switch $($_.Name)
$NewSwitch = $VMHost |New-VirtualSwitch -Name $_.Name-NumPorts $_.NumPorts-Mtu $_.Mtu
$vSwitch = $_
$_ |Get-VirtualPortGroup |Foreach {
If (($VMHost |Get-VirtualPortGroup -Name $_.Name-ErrorAction SilentlyContinue)-eq $null){
Write-Host Creating Portgroup $($_.Name)
$NewPortGroup = $VMHost |Get-VirtualSwitch -Name $vSwitch |New-VirtualPortGroup -Name $_.Name-VLanId $_.VLanID

7 thoughts on “Customisation: Lesson 4 – PortGroups

  1. Sany

    Can we have a PowerCLI script to edit Host profile to add a new port group and add a LUN as datastore

  2. Daniel

    Wrote a little PS based on this article and thought I would share. In a hosting environment like our I am always adding VLAN’s/Portgroups which you can imagine becomes tedious even on only 6 hosts. Enjoy

    $VCUser = Read-Host “User ID: ”
    $VCPassword = Read-Host “Password: ”
    $portgroupname = Read-Host “Enter the name of the PortGroup:”
    $vlanid = Read-Host “Enter the VLAN ID”

    Connect-VIServer -Server -User $VCUser -Password $VCPassword
    $ESXHost = Get-VMHost | Sort-Object -Property Name

    ForEach($objHost in $ESXHost){
    $VSwitch = Get-Virtualswitch -VMHost (Get-VMHost $objHost) | where-object { $_.Name -match “Vswitch1” }
    Write-Host “Adding Virtual Port Group” $portgroupname “with VLAN Tag” $vlanid “to” $objHost
    New-VirtualPortGroup -Name $portgroupname -VirtualSwitch $VSwitch -VLanId $vlanid -WhatIf

  3. Daniel

    Just a quick note, a VLAN id’s of “16810” and “16812” are not really valid:)

    Otherwise fantastic article!

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.