The input file is in CSV format and has four columns: VM name, source portgroup, destination portgroup and reboot (boolean value to see if reboot the VM or not). You may ask why using the source portgroup as input - I am using it to check that the VM actually has one network adapter connected to that portgroup and I am not randomly migrating everything I find on that VM.
The CSV file looks like this:
vmName,srcPg,dstPg,reboot
vm-1abc*,pg-prod-101,pg-prod-110,false
vm-2def*,pg-prod-101,pg-prod-110,false
I am also using wildcards in the name of the VMs. The reason behind this is the VMs have a very long and randomly generated name which is different from the hostname. For example, actual VM name is vm-1abc-yetcg-93763-andbv-34781, while hostname is vm-1abc. How I am checking that the wildcard does not match multiple VMs, you will see in the description below.
The migration script does the following:
- takes as input the CSV file and tries to load and read the CSV file; if it fails, it will exit the execution
- for each line in the CSV file it searches the VM in vCenter server inventory
- once the VM has been uniquely identified, it searches for a network adapter connected to source portgroup as defined in input file; it doesn't find it or finds multiple portgroups, it does not process the VM
- once the source portgroup is identified it changes the network adapter mapping to destination portgroup (as defined in input file)
- if reboot is required, it will issue a soft reboot to the VM
- and it goes to the next VM in the list
And now the code: as usual, please use it carefully as it has not been tested for all situations. Also, PowerCLI session from where the script will be run needs to be connected to vCenter Server as the script does not handle this.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 | param( [Parameter(Mandatory=$true)][string]$csvVmList ) function VmChangeNetwork($vmName,$srcPg,$dstPg,$reboot){ Write-Host "processing:" $vmName Write-Host " src PG:" $srcPg "dst PG:" $dstPg "reboot required:" $reboot Try { $v = Get-VM | Where {$_.Name -like "$vmName"} } Catch { Write-Host $_.Exception.Message $_.Exception.ItemName } if ($v.Count -eq 1){ $srcPgExist = $v | Get-NetworkAdapter | Where {$_.NetworkName -eq $srcPg} if ($srcPgExist.Count -eq 1) { $v | Get-NetworkAdapter | Where {$_.NetworkName -eq $srcPg} | Set-NetworkAdapter -NetworkName $dstPg -Confirm:$false if (($reboot.ToLower() -match "true") -and ($v.PowerState -match "PoweredOn")){ Write-Host " rebooting VM" Restart-VM -VM $v -RunAsync -Confirm $False } } elseif ($srcPgExist.Count -eq 0) { Write-Host " no adapters connected to" $srcPg "found" } else { Write-Host " multiple adapters connected to" $srcPg "found" } } elseif ($v.Count -eq 0) { Write-Host " "$vmName "was not found" } else { Write-Host " "$v.Count "VMs found with name" $vmName } Write-Host "" } # load CSV file Try { $vmList = Import-Csv $csvVmList } Catch { Write-Host -foregroundcolor red " File is not accessible" exit } # process VMs foreach ($vm in $vmList){ VmChangeNetwork -vmName $vm.vmName -srcPg $vm.srcPg -dstPg $vm.dstPg -reboot $vm.reboot } |