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?

3 Answers 3

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á!

Sign up to request clarification or add additional context in comments.

Comments

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

2 Comments

Beware that workflow syntax is subtly different from "regular" PowerShell syntax, so you may want to use jobs instead of a workflow if all you want is parallelism.
@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.
0

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

plink [email protected] secret "shutdown -S shutdown -r now" &
plink [email protected] secret "shutdown -S shutdown -r now" &
plink [email protected] secret "shutdown -S shutdown -r now" &
plink [email protected] secret "shutdown -S shutdown -r now" &

Or like this

for %%a in (...) do plink root@%%a -pw secret "shutdown -S shutdown -r now" &

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.