Automating SSH to windows with Ruby

2020-06-16 03:53发布

问题:

I have a 13 windows servers running Jenkins Slaves. For some reason (windows updates?), the Jenkins slaves periodically quit working and the Jenkins Slave service needs to be restarted. If I manually SSH to the machines (cygwin ssh server is running) I simply type:

net stop "Jenkins Slave"
net start "Jenkins Slave"

and this (almost) always solves the problem.

So I wrote a Ruby script to automate this.

Here is is:

#!/usr/bin/env ruby
require 'rubygems'
require 'net/ssh'

USER = 'Administrator'
PASS = 'PASSWORD'
hosts = [:breckenridge, :carbondale, :crestone, :denali, :gunnison, :sneffels, "mammoth", "whitney", "snowmass", "firestone",  "avon", :grizzly, :silverton]

hosts.each {|host|
    puts "SSHing #{host} ..." 
    Net::SSH.start( HOST, USER, :password => PASS ) do |ssh|
        puts ssh.exec!('net stop "Jenkins Slave"')
        puts ssh.exec!('net start "Jenkins Slave"')
        puts "Logging out..."
    end
}

The script executes on all machines, I see output that the service has started. However, this never works. When I ssh back to the machine, the service hasn't started.

Sadly, I can't use Linux - I'm not in control of these machines.

Any ideas on why a manually executed SSH works, but the script doesn't?

Thanks phil

回答1:

I tried it out in Pry and found two issues:

  1. HOST is undefined, it should be host as this is the variable being passed into the block.
  2. SSH.start expects the parameters to be STRING class, so add the .to_s as indicated below.

Also, I switched it to the idiomatic Ruby pattern of using do...end when a block extends past 1 line.

hosts.each do |host|
    puts "SSHing #{host} ..." 
    Net::SSH.start( host.to_s, USER, :password => PASS ) do |ssh|
        puts ssh.exec!('date')
        puts "Logging out..."
    end
end

I tested this in Pry and it's now working. I hope this helps.