Sometimes it might be necessary to do a mass change of all the IPs of all the vms, specially if the underlying infrastructure is being moved to a different datacenter. Along with the IPs the vlans might change. This is a script where new network labels have been created on a distributed switch and all the vms will need to be updated to the new label and IP. I found it easier to first update the IP and then the label instead of the other way round.

 

  • First a CSV file (list.csv) containing list of servers to be updated. It has the Name of the vm, the new IP, the Gateway address and the new Network label already created in the Vcenter server. Assuming that it's a /24 network address space, the subnet mask of 255.255.255.0 is hard-coded in the script. Different IPs can be part of the same script. The DNS server IPs are also hard-coded in.

 

name,ip,gw,label
server01,10.10.100.10,10.10.100.1,VMNet_100
server02,10.10.100.11,10.10.100.1,VMNet_100
server03,10.10.100.12,10.10.100.1,VMNet_100
server04,10.10.100.13,10.10.100.1,VMNet_100
server05,10.10.100.14,10.10.100.1,VMNet_100
server06,10.10.200.10,10.10.200.1,VMNet_200
server07,10.10.200.11,10.10.200.1,VMNet_200
server08,10.10.200.12,10.10.200.1,VMNet_200
server09,10.10.200.13,10.10.200.1,VMNet_200
server10,10.10.200.14,10.10.200.1,VMNet_200

 

  • And here is the actual Windows Powershell script. To run from  vSphere PowerCLI, remove "Add-PSSnapin VMware.VimAutomation.Core" at the beginning of the code. After powering on the vms, it sends out an email with the list of vms.

 

  • It first checks if VMware Tools are running on the vm. All vms will need VMware Tools installed and running else the script will skip that vm and the name of the vm will be added to "issues.txt" file. Successful names will be added to "report.txt" file.

 

  • This assumes the vm has only one nic. Also do not include VCenter server in the list, that IP should be changed manually.
#Add-in necessary modules
Add-PSSnapin VMware.VimAutomation.Core
Set-PowerCLIConfiguration -InvalidCertificateAction ignore -ProxyPolicy NoProxy -Confirm:$False

#Connect to vcenter server
$vcenter = "<FQDN or IP of vcenter server>"
connect-viserver $vcenter

#Import list of vms
Import-csv C:\list.csv |
foreach {
    $computer = $_.name
    $ip = $_.ip
    $gw = $_.gw
    $label = $_.label

    #Check if VMware Tools are running in the vm without which most of the following commands will not work
    $toolstatus = (Get-VM $computer | Get-View).Guest.ToolsStatus
    if ($toolstatus -eq 'toolsOk'){
        Write-Host (Get-Date).DateTime
        Write-Host -ForegroundColor Green "$computer is up."

        #Read current network settings, needs Domain Admin credentials
        $vmguestnic = Get-VM -Name $computer | Get-VMGuestNetworkInterface -GuestUser '<Domain Admin>' -GuestPassword '<Domain Admin Password>'  -ToolsWaitSecs 30
     
        #Add current network settings to local text file
        Write-Host -ForegroundColor Green "Current network settings are being added to report.txt file."

        "`r`n`r`n"+ (Get-Date).DateTime + "`r`n Current settings:  " +$computer+", "+ $vmguestnic.Ip +", "+$vmguestnic.DefaultGateway | Out-File C:\report.txt -Append

        #Set new IP settings, needs Domain Admin credentials. Double check Subnet Mask and DNS IPs.
        Set-VMGuestNetworkInterface -GuestUser '<Domain Admin>' -GuestPassword '<Domain Admin Password>' -VmGuestNetworkInterface $vmguestnic -IPPolicy Static -Ip $ip -Gateway $gw -Netmask 255.255.255.0 -Dns 10.10.10.2,10.10.10.3
        Write-Host -ForegroundColor Green "Changing IP address."

        #Change port group label which needs to be created before-hand in the Vcenter server.
        Write-Host -ForegroundColor Green "Changing network label."
        Get-VM -Name $computer | Get-NetworkAdapter  | Set-NetworkAdapter -NetworkName $label -connected:$true -StartConnected:$true -confirm:$false

        #Ping the server till it's successful
        do {
            Write-Host -ForegroundColor Green "Could not ping server $computer, sleeping for 5 seconds."
            sleep 5
        } while (((Get-WmiObject win32_pingstatus -Filter "address='$ip'").statuscode) -eq 1)

        #Add current network settings to report text file
        Write-Host (Get-Date).DateTime
        Write-Host -ForegroundColor Green "$computer ping was successful, writing new settings to report.txt file."
        "`r`n New Settings" | Out-File C:\report.txt -Append
        $nic = Get-VM -Name $computer | Get-VMGuestNetworkInterface -GuestUser '<Domain Admin>' -GuestPassword '<Domain Admin Password>'  | Select Ip,SubnetMask,DefaultGateway,Dns,Mac
        $nic | Out-File C:\report.txt -Append
        (Get-Date).DateTime | Out-File C:\report.txt -Append
        "`r`n-------------------------------------------------------------------------------------------------------------"| Out-File C:\report.txt -Append

     } else {
        Write-Host (Get-Date).DateTime
        Write-Host -ForegroundColor Green "$computer - cannot ping server, check if it's running. "
        #Add server to issue text file
        "`r`n" + (Get-Date).DateTime + "`r`n" + $computer | Out-File C:\issues.txt -Append
    }
}

#Disconnect from vcenter server
Disconnect-viserver $vcenter -Confirm:$False