PowerCLI: Changing a VM IP Address with Invoke-VMScript

One of the cmdlets that has been much improved in the recent version of PowerCLU 4 U1 is the Invoke-VMScript cmdlet,

This cmdlet runs a script or command inside the guest OS of each of the specified virtual machines. To run Invoke-VMScript, the user must have read access to the folder containing the virtual machine and a Virtual Machine.Interaction.Console Interaction privilege.

The virtual machines must be powered on and have PowerShell and VMware Tools installed.

Network connectivity to the ESX system hosting the virtual machine on port 902 must be present.

You must also have both the Host and guest credentials available.

One question asked of me recently was “Is there a way to set the IP address of some windows virtual machines with PowerCI ?”.

So with the power of the invoke-cmdlet in the following example you can see how you can change the ip address by using the netsh command inside the VM.

As a note, you no longer need PowerShell inside the guest OS for this cmdlet to work, as you can see below I am calling a batch command, you can also use this cmdlet against *nix machines to run shell commands.

This of course can easily be adjusted to read all ip addresses from a csv file or text file and apply them to multiple virtual machines if needed.

The script is as follows:

Function Set-WinVMIP ($VM, $HC, $GC, $IP, $SNM, $GW){
 $netsh = "c:\windows\system32\netsh.exe interface ip set address ""Local Area Connection"" static $IP $SNM $GW 1"
 Write-Host "Setting IP address for $VM..."
 Invoke-VMScript -VM $VM -HostCredential $HC -GuestCredential $GC -ScriptType bat -ScriptText $netsh
 Write-Host "Setting IP address completed."
}

Connect-VIServer MYvCenter

$VM = Get-VM ( Read-Host "Enter VM name" )
$ESXHost = $VM | Get-VMHost
$HostCred = $Host.UI.PromptForCredential("Please enter credentials", "Enter ESX host credentials for $ESXHost", "root", "")
$GuestCred = $Host.UI.PromptForCredential("Please enter credentials", "Enter Guest credentials for $VM", "", "")

$IP = "192.168.0.81"
$SNM = "255.255.255.0"
$GW = "192.168.0.1"

Set-WinVMIP $VM $HostCred $GuestCred $IP $SNM $GW

And to see it in action I shot a quick video of the script in action:

PowerCLI Invoke-VMScript cmdlet from Alan Renouf on Vimeo.

Further examples of this cmdlet can be found in Arnim’s great example here:

http://www.van-lieshout.com/2010/01/powercli-get-wmi-info-from-isolated-guests/

And  Arne’s great script here:

http://ict-freak.nl/2010/01/20/update-linux-vms-with-powercli-thanks-to-invoke-vmscript/

24 thoughts on “PowerCLI: Changing a VM IP Address with Invoke-VMScript”

  1. Hi Alan

    Can I have same kind of script which can pull the data from .CSV file like vmname/IP/SNM/GW, since I have to assign IP for 150 virtual desktops.
    Thanks
    Raj

  2. Hi,

    I need a help for create this script with “foreach”. I have multiple vm’s and need set ip address in all vm’s.
    I try but not working.

  3. hi

    Is it possible to change the dns primary and secondary into the function?

    I tried

    $netsh = “c:\windows\system32\netsh.exe interface ip set address “”Local Area Connection”” static $IP $SNM $GW 1″
    $netshdns1 = “c:\windows\system32\netsh.exe interface ip set dns “name=”Local Area Connection”” source=static addr=$DNS1 register=primary”
    #$netshdns2 = “c:\windows\system32\netsh.exe interface ip set dns “name=”Local Area Connection”” source=static addr=$DNS2 index=2″

    but I keep getting the error

    + $netshdns1 = “c:\windows\system32\netsh.exe interface ip set dns
    “name=”Local Ar …
    +
    ~~~~~~~~~~~~~~
    Unexpected token ‘name=”Local Area Connection”” source=static addr=$DNS1
    register=primary”‘ in expression or statement.
    + CategoryInfo : ParserError: (:) [], ParseException
    + FullyQualifiedErrorId : UnexpectedToken

  4. This is a good script. But in order to make it worthy for large scale deployments you first must query the guest OS to determine what # local area connection is in use. As you may or may not be aware, windows will often show local area connection 1 or 2 or 3 or whatever, and this script needs to pinpoint what the active local area connection is for it to configure the IP address. Any thoughts on how to collect this information so the script can then configure the correct connection?

    1. Were you able to find an answer to your problem, as how to know local area connection number….I have same issue. Thanks.

      1. I know this is an old post, but I just came across it.

        A variation of this may be helpful to you

        $nic=$(Invoke-VMScript -vm $machine -ScriptText ‘gwmi Win32_NetworkAdapter|Where-Object {$_.description.contains(“vmx”)}|select -expandproperty netconnectionid’ -ScriptType Powershell -guestcredential $localcreds).scriptoutput.trim()

  5. ScriptOutput : The requested operation requires elevation (Run as administrator
    ).

    Disable Windows UAC in control panel, my works after a restart of the machine 🙂

  6. Set-WinVMIP is the name of the function in this script, you will need to run the function in your PowerShell session before it is available to use.

  7. Is set-winvmip a valid power cli command?

    Im getting a “The Term ‘Set-WinVMIP’ is not recognized as the name of a cmdlet.

  8. great script. do you know a workaround for the following:

    ScriptOutput : The requested operation requires elevation (Run as administrator
    ).

  9. Tim,

    As far as I know what this actually does is use the same method as invoke-vmscript but pushes a pre-defined bat file to the machine and runs that, unfortunatly I do not have the same issue as you as my nic is attached !

    I have mentioned this in the forums and it would seam a few other people have an issue with the bat file too.

    Hopefully this will be resolved in a future release.

    Alan

  10. Al,

    I am playing around with some automation stuff and was getting the same “unable to parse script output” error as you were while using Get-VMGuestNetworkInterface. The issue was actually that when I had called Set-NetworkAdapter I didn’t pass -Connected:$true in that statement. If the VM network adapter is not connected, it will throw the “unable to parse script output”. As soon as I changed the vNIC settings on the VM to “Connected” my scripts worked just fine.

    HTH,
    Tim

  11. Al , a great Script again .

    Considering that Starting Windows 2008 , Powershell comes with the OS by default , This would be a great script .

  12. Just tried that one and couldnt get it working, was getting an error with Get-VMGuestNetworkInterface: Unable to parse script output.

    1. Please note that Get-VMGuestNetworkInterface is bound to OS’s languages (in Windows OS at least)

      In fact, the scripts provided by vmware (ex. : GetVmGuestNetworkInterface_windows7Server64Guest.bat) is parsing the output of the command “ipconfig /all” … the parsing is looking for specific words/characters/spaces/etc in the output … and as you can imagine, it only works when that output is run on English version of the OS. Hence the “Unable to parse script output” error when running in a French or German or whatever non-english guest Windows version.

      Since I was struggling with that error myself, I hope it helps someone else..

Leave a Reply