I am trying to use Alans function to change ip address on windows guests with an import-csv file
Function Set-WinVMIP ($VM, $IP, $SNM, $GW, $DNS1, $DNS2, $WINS, $GC){
$cmd = @'
netsh interface ip set address "Local Area Connection" static $IP $SNM $GW 1"
netsh interface ip add dns name="Local Area Connection" source=static addr=$DNS1 register=primary
netsh interface ip add dns name="Local Area Connection" source=static addr=$DNS2 index=2
netsh.exe interface ip set wins name="Local Area Connection" source=static addr=$WINS
'@
Invoke-VMScript -VM $VM -GuestCredential $GC -ScriptText $cmd -ScriptType bat
}
$GC = $Host.UI.PromptForCredential("Please enter credentials", "Enter Guest credentials for $VM", "", "")
Import-Csv "C:\Users\tkw\vms.csv" -UseCulture | %{
Set-WinVMIP $_.VM $_.IP $_.SNM $_.GW $_.DNS1 $_.DNS2 $_.WINS $GC
}
but keep getting this error
any idea?
The problem with the code that didn't work is that no variable replacement is happening. In PowerShell a variable inside " will be replaced with the value of the variable, while a variable inside ' will not.
$IP = "10.1.1.1"
CMD = @'
netsh interface ip set address "Local Area Connection" static $IP
'@
Will end up with $CMD being
netsh interface ip set address "Local Area Connection" static $IP
The fix is that instead of @' as the start of a multi-line string (with the single quote blocking variable expansion) to use @" (with the double quote doing variable expansion)
$IP = "10.1.1.1"
CMD = @"
netsh interface ip set address "Local Area Connection" static $IP
"@
Will end up with $CMD being
netsh interface ip set address "Local Area Connection" static 10.1.1.1
my csv file looks like this
netsh interface ip set address "Local Area Connection" static $IP $SNM $GW 1"
doesn't look right (there is an extra quote at the end)
I got this to work instead
Function Set-WinVMIP ($VM, $IP, $SNM, $GW, $DNS1, $DNS2, $WINS){
$netsh = "netsh interface ip set address ""Local Area Connection"" static $IP $SNM $GW 1"
Invoke-VMScript -VM $VM -GuestCredential $GC -ScriptType bat -ScriptText $netsh
$netsh1 = "netsh interface ip set dns ""Local Area Connection"" static $DNS1 primary"
Invoke-VMScript -VM $VM -GuestCredential $GC -ScriptType bat -ScriptText $netsh1
$netsh2 = "netsh interface ip add dns ""Local Area Connection"" addr=$DNS2 index=2"
Invoke-VMScript -VM $VM -GuestCredential $GC -ScriptType bat -ScriptText $netsh2
$netsh3 = "netsh interface ip set wins ""Local Area Connection"" static $WINS"
Invoke-VMScript -VM $VM -GuestCredential $GC -ScriptType bat -ScriptText $netsh3
}
$GC = $Host.UI.PromptForCredential("Please enter credentials", "Enter Guest credentials for $VM", "", "")
Import-Csv "C:\Users\tkw\vms.csv" -UseCulture | %
Set-WinVMIP $_.VM $_.IP $_.SNM $_.GW $_.DNS1 $_.DNS2 $_.WINS $GC
}
but not this
---------------------------------------------------------------------------------------------------------------------------------------------------------------------
Function Set-WinVMIP ($VM, $IP, $SNM, $GW, $DNS1, $DNS2, $WINS, $GC){
$cmd = @'
netsh interface ip set address "Local Area Connection" static $IP $SNM $GW 1
netsh interface ip set dns "Local Area Connection" static $DNS1 primary
netsh interface ip add dns "Local Area Connection" addr=$DNS2 index=2
netsh interface ip set wins "Local Area Connection" static $WINS
'@
Invoke-VMScript -VM $VM -GuestCredential $GC -ScriptType bat -ScriptText $cmd
}
$GC = $Host.UI.PromptForCredential("Please enter credentials", "Enter Guest credentials for $VM", "", "")
Import-Csv "C:\Users\tkw\vms.csv" -UseCulture | %{
Set-WinVMIP $_.VM $_.IP $_.SNM $_.GW $_.DNS1 $_.DNS2 $_.WINS $GC
}
the error was
The problem with the code that didn't work is that no variable replacement is happening. In PowerShell a variable inside " will be replaced with the value of the variable, while a variable inside ' will not.
$IP = "10.1.1.1"
CMD = @'
netsh interface ip set address "Local Area Connection" static $IP
'@
Will end up with $CMD being
netsh interface ip set address "Local Area Connection" static $IP
The fix is that instead of @' as the start of a multi-line string (with the single quote blocking variable expansion) to use @" (with the double quote doing variable expansion)
$IP = "10.1.1.1"
CMD = @"
netsh interface ip set address "Local Area Connection" static $IP
"@
Will end up with $CMD being
netsh interface ip set address "Local Area Connection" static 10.1.1.1
Thanks for the correction. It works fine now.
Can invoke-vmscript runasyn or does it do it only one vm at a time only?
Yes, it can do RunAsync, and yes, you can launch it against multiple VMs in one call.
See the Invoke-VMScript helppage
Blog: lucd.info Twitter: @LucD22 Co-author PowerCLI Reference
Hi Luc,
This script seems to work really well for windows 2008 servers but when i run it against 2012 servers powercli displays (ScriptOutput |) i.e no errors but the windows ip has not changed.. The label is ethernet0 on the adapter however if i change the label in the script i get an error in powerlci saying the label symtax is incorrect
Function Set-WinVMIP ($VM, $IP, $SNM, $GW){
$cmd = @"
netsh interface ipv4 set address name="Local Area Connection" static $IP $SNM $GW 1"
"@
Invoke-VMScript -VM $VM -GuestUser xxxxxxxx -GuestPassword xxxxxxxx -ScriptText $cmd -ScriptType bat
}
Import-Csv "C:\Scripts\ipnetsh.csv" -UseCulture | %{
Set-WinVMIP $_.VM $_.IP $_.SNM $_.GW $GC
}
That must be a netsh error you're getting.
Could you show all the properties of the returned object ?
Something like this (update the Invoke-VMScript cmdlet and its parameters)
Invoke-VMScript -VM $vm -ScriptText '<your command' | Select *
Blog: lucd.info Twitter: @LucD22 Co-author PowerCLI Reference
The syntax for netsh in 2012 and later appears to have changed so that the parameters now need to be explicitly specified. For example
netsh interface ipv4 set address name="Ethernet1" 10.10.20.119 255.255.255.0 10.10.20.1 1
works in 2008 R2 but returns an error in 2012, however
netsh interface ipv4 set address name="Ethernet1" addr=10.10.20.119 mask=255.255.255.0 gateway=10.10.20.1 gwmetric=1
works in 2012 and later
With that being said in 2012 and later there are actual PowerShell cmdlets to set the IP address, etc. without the need for netsh (part of the NetAdapter module). Those are a much cleaner way of doing things that using netsh as you can put in some intelligence to find the adapter name (in case someone has added and removed Ethernet adapters a few times on a VM and its now "Ethernet3" instead of "Ethernet1" or just renamed it a custom value). With the cmdlets you can use Get-NetAdapter to find the right adapter (rather than hard coding it and occasionally breaking) then New-NetIPAddress/Set-NetIPAddress to set the values