Hi,
I have a script that sets the IP Address of multiple servers in a foreach loop. The Script runs and changes the IP Address, but the problem i have is once the IP address has changed it loses connection to the remote server and throws an error.
Not sure of a way to get round the error, but i was thinking i could use a invoke-command and pass the variables for the IP,DNS,Gateway to the remote session? would this get round the error?
Or is there a better way?
Thanks
TommyQ
and where is the script ? and error ? if you get connection error than you get this error with any way of parameter passing
Yeah i did think the error would appear if i invoke.
The script is using a WMI command to set the ip, so i don’t seem to be able to specify an error action.
foreach($Node in $VMs)
{
$NetAdapter = Get-WmiObject win32_networkadapterconfiguration -ComputerName $Node.NodeName |
Where { $_.DHCPEnabled -like "True" -and $_.DefaultIPGateway -notcontains "***.***..***.***" -and $_.Description -like "vmxnet*" -and $_.IPENABLED -eq "$True"}
write-host "Setting IP Address for $Node"
$NetAdapter.SetGateways(($Node).Gateway ,1)
$NetAdapter.SetDNSServerSearchOrder(($Node).DNS)
$NetAdapter.EnableStatic(($Node).IP , $SubnetLan)
}
Thanks
Tommy
You are not going to avoid the error. Your session is using DCOM is connected with an IP address, names are just for us to have an easy reference. While you can’t ignore the error, you can handle the error. You should start by looking at the eBook link above for The Big Book of PowerShell Error Handling. Here is a basic example:
foreach($Node in $VMs) {
try {
$NetAdapter = Get-WmiObject win32_networkadapterconfiguration -ComputerName $Node.NodeName -ErrorAction Stop |
Where { $_.DHCPEnabled -like "True" -and $_.DefaultIPGateway -notcontains "***.***..***.***" -and $_.Description -like "vmxnet*" -and $_.IPENABLED -eq "$True"}
write-host "Setting IP Address for $Node"
$NetAdapter.SetGateways(($Node).Gateway ,1)
$NetAdapter.SetDNSServerSearchOrder(($Node).DNS)
$NetAdapter.EnableStatic(($Node).IP , $SubnetLan)
}
catch {
"An error occured on {0}. {1}" -f $Node.NodeName, $_
}
}
Now this code is going to get ANY terminating error and catch it thanks to -ErrorAction Stop. You can handle specific exceptions, so take a look at the ebook.
Thanks for the Reply Rob,
I originally had run the script in a Try Catch block, but the problem is it takes for ever to move onto the next step for some reason. It’s doesn;t seem to throw the exception/error for almost 10mins per server and I’m IPing about 30 servers each time
Is there a way in the Try/Catch that will adjust this behavior?
Thanks
TommyQ
Are you able to use PSRemoting? Your issue is that each time you execute a wmi method in your code it processes that command before executing the next command in your code. If using invoke-command you could send an entire script block to execute and that script block will continue to execute until completion, even if your session is disconnected.
Especially when changing NIC settings you want to find a way to ensure your code gets executed to completion because it’s almost guaranteed that you will lose connection to the remote host once you make a change to the NIC.
If DCOM and WMI are your only options, I’d consider using the Win32_Process class to start a powershell process and pass your commands as arguments to the -command parameter of powershell.exe all at once and that should act like a rudimentary invoke-command.
Simply put, you want to send all of your commands at once so they will get executed regardless of you losing connection to the remote host.
Hi Peter, thanks for the reply.
Yes i can use PSRemoting. That was what i was kinda thinking by passing a script block of variables, but I’m not sure how to pass multiple variables to the remote session as i need to pass DNS, IP, Gateway etc?
this is examples for you
$comp = 'server1', 'server2'
0..1 | Foreach-Object {
$data = $_;
$value = get-random;
Invoke-Command -ComputerName $comp[$_] -Script { ('Data: {0}; Value: {1}, Comp: {2}' -f $using:data, $using:value, $env:computername) }
}
and Output is
Data: 0; Value: 1515173641, Comp: SERVER1
Data: 1; Value: 91612878, Comp: SERVER2
the other variant:
0..1 | Foreach-Object {
$data = $_;
$value = get-random;
Invoke-Command -ComputerName $comp[$_] -Script { ('Data: {0}; Value: {1}, Comp: {2}' -f $args[0], $args[1], $env:computername) } -ArgumentList $data, $value
}
and third:
0..1 | Foreach-Object {
$data = $_;
$value = get-random;
Invoke-Command -ComputerName $comp[$_] -Script {param($d,$v) ('Data: {0}; Value: {1}, Comp: {2}' -f $d, $v, $env:computername) } -ArgumentList $data, $value
}
$using:
does not work with PSv2
but I’m still not sure that remoting will not wait for answer after ip change
may be you should use start /w netsh …
for this thing.
because I haven’t free computer system for testing I’ll wait for your report
Thanks for the reply Max Kozlov,
Sorry i’ve taken so long to get back to you. I tested passing the params via a scriptblock, but annoyingly i still get the issue with the waiting to complete and then throwing the exception.
I’ll try and find another way and post my results.
Thanks everyone for your help.
TommyQ