«

»

Aug 10

Change IP Address on Windows 2012 VMs with PowerCLI

Just a quick script I put together to change the IP Address of Windows 2012 (including R2) virtual machines using PowerCLI. The script determines the current IP address of the VM and replaces part of the address with a defined value. For example if the original VM had an IP address of 192.168.1.25, it could change it to 172.28.238.25 – keeping the last octet of the IP address. Could be useful if restoring a bunch of VMs to a DR site or into a testing or development sandbox.

I am using the Invoke-VMScript to execute PowerShell and batch commands within the VM Guest. This requires VMware Tools to be installed on the Guest. I would have used Set-VMGuestNetworkInterface but Windows 2012 is not currently supported. 🙁

The script gets all VMs in vCenter Inventory with names matching on $matchVMs and determines the current IP Address configuration and Interface Alias by matching the $origIP, creates the new IP Address to assign by replacing the part of the IP Address matching $origIP with $newIP, sets the new IP Address, sets the new DNS Servers, and registers the VM with DNS.

#######################################
# PowerCLI to replace guest network information for restored VMs with new IP Address, Gateway and DNS Servers
# example: Original IP Address is 192.168.1.252, change to 172.28.238.252
#
# Must be connected to vCenter or ESXi using Connect-VIServer
#
# Script: ChangeVMIPAddress.ps1
#
# History:
# 7/26/2015 - Hersey http://www.vhersey.com/ - Created
#
###############VARIABLES###############
#Original IP to replace"
$origIp = "192.168.2."

#New IP Information
$newIp = "192.168.1."
$newMask = "255.255.255.0"
$newGateway = "192.168.1.1"
$newDNS = "192.168.1.150"

#Guest Credentials - Must have required permissions to change IP address
$GuestUserName = "Administrator"
$GuestPassword = "Password"

#VM Inventory names to match
$matchVMs = "restore"

##############NO CHANGES BEYOND THIS POINT##############
#List of VMs (vCenter Inventory Names) to change
Write-Host "Getting list of VMs from Inventory where Inventory Name contains $matchVMs"
$VMs = (get-vm | where {$_.Name -match $matchVMs -and $_.PowerState -eq "PoweredOn"}).Name

foreach ($vm in $VMs) {
   Write-Host "Working on $vm"
   #PowerShell used by Invoke-VMScript to retrieve current IP Address
   $ipscript = '(Get-NetIPAddress | where-object {$_.IPAddress -match "' + $origIp + '" -and $_.AddressFamily -eq "IPv4"}).IPAddress'
   $currentIp = invoke-vmscript -ScriptText $ipscript -ScriptType PowerShell -VM $vm -GuestUser $GuestUserName -GuestPassword $GuestPassword
   $currentIp = $currentIp -replace "`t|`n|`r",""
   write-host "$currentIp is the current IP Address"

   #Adjust Original IP to Replacement IP
   $changeIp = $currentIp.replace("$origIp", "$newIp")
   $changeIp = $changeIp -replace "`t|`n|`r",""
   Write-Host "Changing IP to $changeIp"

   #Get the Interface Name (Alias)
   $aliasscript = '(Get-NetIPAddress | where-object {$_.IPAddress -match "' + $origIp + '" -and $_.AddressFamily -eq "IPv4"}).InterfaceAlias'
   $getIntAlias = invoke-vmscript -ScriptText $aliasscript -ScriptType PowerShell -VM $vm -GuestUser $GuestUserName -GuestPassword $GuestPassword
   $getIntAlias = $getIntAlias -replace "`t|`n|`r",""
   write-host "The interface name is $getIntAlias"

   #Change the IP Address
   $changingIp = '%WINDIR%\system32\netsh.exe interface ipv4 set address name="' + $getIntAlias + '" source=static address=' + $changeIp + ' mask=' + $newMask + ' gateway=' + $newGateway + ' gwmetric=1 store=persistent'
   Write-host "Changing IP Address of $vm interface $getIntAlias from $currentIp to $changeIp"
   $setIp = invoke-vmscript -ScriptText $changingIp -ScriptType bat -VM $vm -GuestUser $GuestUserName -GuestPassword $GuestPassword

   #Change DNS Servers
   Write-Host "Setting DNS Server to $newDNS"
   $changeDNS = '%WINDIR%\system32\netsh.exe interface ipv4 set dnsservers name="' + $getIntAlias + '" source=static address=' + $newDNS + ' register=primary'
   $setDNS = invoke-vmscript -ScriptText $changeDNS -ScriptType bat -VM $vm -GuestUser $GuestUserName -GuestPassword $GuestPassword

   #Register with DNS
   Write-Host "Registering with DNS"
   $registeringDNS = '%WINDIR%\System32\ipconfig /registerdns'
   $segDNS = invoke-vmscript -ScriptText $registeringDNS -ScriptType bat -VM $vm -GuestUser $GuestUserName -GuestPassword $GuestPassword

   Write-Host "Finished with $vm"
}

You can also find the script on GitHub – ChangeVMIPAddress.ps1

Any thoughts or comments appreciated.

Have fun!

About the author

vHersey

Hersey Cartwright is an IT professional with extensive experience designing, implementing, managing, and supporting technologies that improve business processes. Hersey is Solutions Architect for SimpliVity covering Virginia, Washington DC, and Maryland. He holds the VMware Certified Design Expert (VCDX-DV #128) certification. Hersey actively participates in the VMware community and was awarded the VMware vExpert title in 2016, 2015, 2014, 2013, and 2012. He enjoys working with, teaching, and writing about virtualization and other data center technologies. Follow Hersey on Twitter @herseyc

2 comments

  1. Mike

    Thanks a lot! This worked perfectly. I thought we were screwed.

  2. aenagy

    Does this script assume that UAC is disabled on the target system?

Leave a Reply

Your email address will not be published. Required fields are marked *

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <s> <strike> <strong>

2 × 3 =