4

I'm trying to write a script to reboot Macs in a range of IP addresses. Doing it through PowerShell works, but the process waits until each machine reboots before it moves on to the next machine. I'm finding ssh'ing into each machine and rebooting it using sudo shutdown -S shutdown -r now is faster...it's just manual. Here's what I have so far in PowerShell:

$serverRoot = "xxx.xxx.xxx."
$startVal = 100
$stopVal = 150

for ($i=$startVal; $i -le $stopVal; $i++)
{
    $User="username"
    $Password="password"

    $SecurePass=ConvertTo-SecureString -string $Password -AsPlainText -Force

    $Credential = New-Object System.Management.Automation.PSCredential $User, $SecurePass

    $session = New-SSHSession -ComputerName ($serverRoot + $i) -Credential $Credential  -AcceptKey
    Invoke-SSHCommand -SSHSession $session -Command "echo $Password | sudo -S shutdown -r now"   
    Remove-SSHSession -SSHSession $session -Verbose

}

Is there something I can add which will just kick the reboot process off on all the machines at once? Should I use AppleScript?

JasonMArcher
  • 14,195
  • 22
  • 56
  • 52
junton
  • 43
  • 5

3 Answers3

3

If you wrap it to workflow, you can kick it as parallel:

workflow Kill-All {
  param([string[]]$computers)

  foreach -parallel ($computer in $computers) {
      InlineScript {
         # Your powershell stuff.
      }
  }
}

Kill-All -Computers "132.134.123.1", "123.4.53.12"

Alternatively, you can put your stuff to bat file, and use powershell to invoke the bat file. This way you can invoke the bat files without waiting one to finish, before proceeding to the next one.

The best way, as answered by rae1, is to just invoke New-SSHSession directly, as it supports parallelization by default.

Here is a one liner:

$sessions  = New-SSHSession -ComputerName (1..254 | %{ "xxx.xxx.xxx.$_"})

More information: http://blogs.technet.com/b/heyscriptingguy/archive/2012/11/20/use-powershell-workflow-to-ping-computers-in-parallel.aspx

http://community.spiceworks.com/topic/341776-call-a-ps-script-from-another-and-don-t-wait-for-it-to-finish

Erti-Chris Eelmaa
  • 25,338
  • 6
  • 61
  • 78
  • Beware that workflow syntax is subtly different from "regular" PowerShell syntax, so you may want to use [jobs](http://stackoverflow.com/a/12768438/1630171) instead of a workflow if all you want is parallelism. – Ansgar Wiechers Apr 23 '15 at 17:31
  • @AnsgarWiechers; agreed. to be honest, I don't find workflows useful at all, I might be missing something here.. the only thing I can theoretically imagine useful in workflows is the ability to quite simply arrange things to run in parallel while still maintaining sequence for some things. – Erti-Chris Eelmaa Apr 25 '15 at 10:42
3

Actually, the -ComputerName param for New-SSHSession can take a collection of servers, and will invoke the command in parallel for all servers by default,

$serverRoot = "xxx.xxx.xxx."
$startVal = 100
$stopVal = 150

# First start with creating a collection
$servers = @()
for ($i = $startVal; $i -le $stopVal; $i++)
{
    $servers += ($serverRoot + $i)
}

# Then, pass the $servers variable directly when creating the session
$session = New-SSHSession -ComputerName $servers -Credential $credential -AcceptKey

And voilá!

rae1
  • 6,066
  • 4
  • 27
  • 48
0

You could use plink.exe along these lines (untested):

plink root@192.168.0.1-pw secret "shutdown -S shutdown -r now" &
plink root@192.168.0.2-pw secret "shutdown -S shutdown -r now" &
plink root@192.168.0.3-pw secret "shutdown -S shutdown -r now" &
plink root@192.168.0.4-pw secret "shutdown -S shutdown -r now" &

Or like this

for %%a in (...) do plink root@%%a -pw secret "shutdown -S shutdown -r now" &
Mark Setchell
  • 191,897
  • 31
  • 273
  • 432