This Script will clone an existing vDS and its port groups.  **with new UUIDs**
This is great if you get a corrupted vDS and need to migrate away from it.
Or, if you want to recreate a new vDS in the image of an old one without using the export/import method.

** quick notes:
– This creates a new distributed switch and port groups with new IDs.  This isn’t good to use as an Export/Import when migrating hosts and VMs to a new vCenter.
– This script does not keep special Security Policies but its very easy to add it to the script. I left all of the vars complete so you can pull and assign the extension data for additional needs.
– This code pulls an old vDS and its port groups, then recreates a new one using a “-2” at the end of the names.  At the very end of the script, it then removes the “-2” from the names.   Keep this in mind if you have “-2” in the name of your vDS or port groups.  If you do use this “-2” string in your existing names, change it in the script to something like “QQQQ” so you can remove the trailing text at the end without impacting your existing names.

## Set your old vDS name and paste the rest.

Add-PSSnapin VMware.*
$oldVDSName = “dvs-MyvDS”

#Grab the old vDS info
$oldvDS = get-VDSwitch $oldVDSName

#Create the new one and rename its uplink
$newvDS = new-vdswitch -name ($”-2″) -location $ -NumUplinkPorts $oldvDS.NumUplinkPorts -mtu $oldvDS.Mtu
$oldUpLink = $oldvDS | get-vdportgroup | where {$_.IsUplink -eq “True”}
$newvDS | get-vdportgroup | where {$_.IsUplink -eq “True”}  | set-vdportgroup -name ($”-2″) -vlantrunkRange $oldUpLink.VlanConfiguration

#Pull the old vDS port groups and recreate them on the new vDS
$Portgroups = $oldvDS | get-vdportgroup | ?{$_.IsUplink -ne “True”}
foreach($port in $portgroups){
$Pname = $ + “-2”
$PVlanid = $port.VlanConfiguration.vlanid
$pNumPorts = $port.numports
$newvDS | New-VDPortgroup -Name $Pname -Vlanid $PVlanid -numports $pNumPorts
$newvDS | New-VDPortgroup -Name $Pname -numports $pNumPorts

#Here you can migrate ESXi Host links and VMs from your old vDS to your new vDS.
#If you want to migrate to the new vDS, you can get some code help here :
#If you copied the vDS to the same vCenter, keep in mind that vDS names and vDS Port group names are vcenter unique.
#You will need to delete your old vDS or rename it to remove the “-2” from the new one.

#Remove the old vDS if you no longer need it – Do this Manual so you can verify that everything has migrated…
#$oldvDS | remove-vdswitch -confirm:$False

#rename the new vDS and its port groups to match the orginal.
$newvDS | set-vdSwitch -name ($ -replace “-2″,””)
$Portgroups = $newvDS | get-vdportgroup

foreach($port in $portgroups){
$port | set-vdportgroup -name ($ -replace “-2″,””)


#Here is some extra code to set the Teaming Load Balancing policy for all port groups on your new vDS. This is configured to set all port groups to “Route based on Physical NIC load”
#Change the port group load policy to Load based
$newvDSPortgroups = get-VDSwitch $newVDS | get-vdportgroup
Function Set-VDPortGroupTeamingPolicy {
param (

Process {
$spec = New-Object VMware.Vim.DVPortgroupConfigSpec
$spec.configVersion = $VDPortgroup.ExtensionData.Config.ConfigVersion
$spec.defaultPortConfig = New-Object VMware.Vim.VMwareDVSPortSetting
$spec.defaultPortConfig.uplinkTeamingPolicy = New-Object VMware.Vim.VmwareUplinkPortTeamingPolicy
$spec.defaultPortConfig.uplinkTeamingPolicy.inherited = $false
$spec.defaultPortConfig.uplinkTeamingPolicy.policy = New-Object VMware.Vim.StringPolicy
$spec.defaultPortConfig.uplinkTeamingPolicy.policy.inherited = $false
$spec.defaultPortConfig.uplinkTeamingPolicy.policy.value = “loadbalance_loadbased”

foreach($port in $newvDSPortgroups){
$port| Set-VDPortgroupTeamingPolicy


Quick Report script to find those VMs that span more than one Numa Boundary.
Meaning:  If your ESX host has two – quad core CPUs and your VM is configured for six vCPUs,  then your VMs is spanning two NUMA boundaries.
Also, if your VM is configured with 32GB of memory but you only have 24GB of ram Per CPU Socket, your VM will cross memory NUMA boundaries!

Add-PSSnapin VMware.*


$temp = get-view -viewtype virtualmachine -property name,,config.hardware
$temphost = get-view -viewtype hostsystem -property name,hardware.cpuinfo,hardware.MemorySize
foreach($a in $temp){
$row = “” | select VMname,VMTotalvCPUs,VMSockets,VMCores,CPUCalcNumaNodes,MemCalcNumaNodes
$row.VMname = $
$row.VMTotalvCPUs = $a.config.hardware.numcpu
$row.VMsockets = ($a.config.hardware.numcpu)/($a.config.hardware.NumCoresPerSocket)
$row.VMcores = $a.config.hardware.NumCoresPerSocket
$t = $temphost | where {$_.moref -eq $}
$nodesCalc = try{[system.math]::ceiling($a.config.hardware.numcpu /($t.hardware.cpuinfo.numcpucores / $t.hardware.cpuinfo.NumCpuPackages))}catch{}
$row.CpuCalcNumaNodes = if($nodesCalc -gt $t.hardware.cpuinfo.NumCpuPackages){$t.hardware.cpuinfo.NumCpuPackages}else{$nodesCalc}
$nodesCalc = if(((($t.hardware.memorysize)/1048576)/$t.hardware.cpuinfo.NumCpuPackages) -lt ($a.config.hardware.MemoryMB)){$nodescalc + 1}else{$nodescalc}
$row.MemCalcNumaNodes = if($nodesCalc -gt $t.hardware.cpuinfo.NumCpuPackages){$t.hardware.cpuinfo.NumCpuPackages}else{$nodesCalc}
$report += $row

### format the below output as needed.  It currently reports any VMs that span across more than one NUMA boundary.
$report | where {($_.CPUCalcNumaNodes -ge 2) -or ($_.MemCalcNumaNodes -ge 2)} | ft