I have a PowerCLI script that, among other things, loops through a list of ESXi hosts (5.0) and executes command(s) on each using PuTTY\plink.exe. While this works 99% of the time, we've run into a couple of occurences (e.g. restarting management services) where it hangs, failing to return program control when the remote command completes. For example, using the following code:
$command = "/sbin/services.sh restart"
foreach ($nextHost in $hostList) { $userhost = $user + "@" + $nextHost
echo "$(date -format s) Executing command '$command' on host $nextHost"
& $plinkPath -v -batch -pw $pw $userhost $command
echo "$(date -format s) Command completed."
echo "Sleeping for $delay seconds"
sleep -Seconds $delay
}
It will successfully connect and run the command, thus restarting services, but at the end, I get this:
...
Running vmware-fdm restart
Starting vmware-fdm:success
Server sent command exit status 0
Where it just sits, waiting for ... something. Since it doesn't close the connection, it doesn't return program control to the PowerShell script and it won't continue on to the next host.
I've even tried running the command '/sbin/services.sh restart && exit' or && return 2' or even && ls' without luck. I've tested this on both multiple 2008 R2 and 2012 systems. You can probably easily replicate it (assuming PuTTY installed) by simply opening up a PowerShell console and executing:
> & 'C:\Program Files (x86)\PuTTY\plink.exe' -v -batch -pw "[root password]" root@[FQDNesxihostname] '/sbin/services.sh restart'
Contrast that behavior with something like:
> & 'C:\Program Files (x86)\PuTTY\plink.exe' -v -batch -pw "[root password]" root@[FQDNesxihostname] 'ls'
Any help on how to get this to close the connection and return program control would be appreciated.
Did you try running the command in the background with something like this
'/sbin/services.sh restart &'
The plink command should return immediatly in this case
Blog: lucd.info Twitter: @LucD22 Co-author PowerCLI Reference
Unfortunately, running it in the background only returns the exit code earlier (Server sent command exit status 0), as soon as the command is executed. But this doesn't actually change the result - it still runs through but fails to disconnect when completed.
Is anyone able to replicate this? I've done this on multiple systems, so I don't think this is something specific to my environment.
Thanks for the help.
Found a solution:
$command = "VAR=`$(pidof -s sshd) && /sbin/services.sh restart && kill `$VAR"
- Grabs the latest/newest ssh connection PID (your own) and stores in VAR
- NOTE: It's conceivable that there's a very small (fraction of a second) window where someone else *MAY* be able to log in after you do, but before the pidof command runs, just be aware
- Run service restart command
- Kill your own ssh connection PID to return control back to powershell script
This does what I needed it to. Hope this approach helps someone else.
Top notch Tocano!!! I was fighting with this exact issue when trying to running "/etc/init.d/hostd restart" with plink. Problem solved!!! Many thanks!!!!
Hi Tocano,
Is it possible for you to post the script in its entirety? I find myself needing to set the syslog server and then restart the management agents for multiple hosts (over 100). Please advise as this script will greatly help my and my colleagues.
Many thanks,
Lenny
very useful as trying to batch up service management restarts with plink to work around this http://kb.vmware.com/selfservice/microsites/search.do?language=en_US&cmd=displayKC&externalId=210973...
when I use the method above I end up killing the entire script "FATEL ERROR: server unexpectedly closed network connection" so it will not continue to the next item in the list
any ideas?