Sample code for 30+ languages & platforms
Lianja

SSH Parallel Remote Commands on Multiple Servers

See more SSH Examples

Shows how to execute a command in parallel on multiple servers.

Chilkat Lianja Downloads

Lianja
llSuccess = .F.

// This example requires the Chilkat API to have been previously unlocked.
// See Global Unlock Sample for sample code.

// Executing a command on multiple servers simultaneously is straightforward.
// It's just a matter of using one SSH object per server..
loSsh1 = createobject("CkSsh")
loSsh2 = createobject("CkSsh")
loSsh3 = createobject("CkSsh")

lnPort = 22
llSuccess = loSsh1.Connect("ssh-server1.com",lnPort)
if (llSuccess <> .T.) then
    ? loSsh1.LastErrorText
    release loSsh1
    release loSsh2
    release loSsh3
    return
endif

// Authenticate using login/password:
llSuccess = loSsh1.AuthenticatePw("sshLogin1","sshPassword1")
if (llSuccess <> .T.) then
    ? loSsh1.LastErrorText
    release loSsh1
    release loSsh2
    release loSsh3
    return
endif

// Connect and authenticate with 2 more servers.
// For brevity, the success/failure won't be checked...
llSuccess = loSsh2.Connect("ssh-server2.com",lnPort)
llSuccess = loSsh2.AuthenticatePw("sshLogin2","sshPassword2")
llSuccess = loSsh3.Connect("ssh-server3.com",lnPort)
llSuccess = loSsh3.AuthenticatePw("sshLogin3","sshPassword3")

// Note: If we wanted, we could've used ConnectAsync and AuthenticatePwAsync
// to do the connecting and authenticating in parallel...

// The command to be run on each SSH server will sleep for 5 seconds,
// and then show the current system date/time.
lcCmd = "sleep 5; date"

// Start each command
lnSsh1Channel = loSsh1.QuickCmdSend(lcCmd)
if (lnSsh1Channel < 0) then
    ? loSsh1.LastErrorText
    release loSsh1
    release loSsh2
    release loSsh3
    return
endif

// For brevity, we're not checking the return values here:
lnSsh2Channel = loSsh2.QuickCmdSend(lcCmd)
lnSsh3Channel = loSsh3.QuickCmdSend(lcCmd)

// OK, at this point the command is running simultaneously on each server.

// Now collect the results of each command.
lnPollTimeoutMs = 50
lnNumFinished = 0

// Note: You would rewrite this code to use arrays.
llSsh1Finished = .F.
llSsh2Finished = .F.
llSsh3Finished = .F.
do while lnNumFinished < 3
    // Check to see if anything has finished.
    // QuickCmdCheck returns -1 if there are no errors and nothing else finished
    // QuickCmdCheck returns -2 if there was an error (such as a lost connection)
    // QuickCmdCheck returns a channel number if a channel finished.
    if (llSsh1Finished <> .T.) then
        lnChannel = loSsh1.QuickCmdCheck(lnPollTimeoutMs)
        if (lnChannel = -2) then
            ? loSsh1.LastErrorText
            release loSsh1
            release loSsh2
            release loSsh3
            return
        endif

        if (lnChannel = lnSsh1Channel) then
            ? "---- ssh1 channel " + str(lnChannel) + " finished ----"
            ? loSsh1.GetReceivedText(lnChannel,"ansi")
            lnNumFinished = lnNumFinished + 1
            llSsh1Finished = .T.
        endif

    endif

    if (llSsh2Finished <> .T.) then
        lnChannel = loSsh2.QuickCmdCheck(lnPollTimeoutMs)
        if (lnChannel = -2) then
            ? loSsh2.LastErrorText
            release loSsh1
            release loSsh2
            release loSsh3
            return
        endif

        if (lnChannel = lnSsh2Channel) then
            ? "---- ssh2 channel " + str(lnChannel) + " finished ----"
            ? loSsh2.GetReceivedText(lnChannel,"ansi")
            lnNumFinished = lnNumFinished + 1
            llSsh2Finished = .T.
        endif

    endif

    if (llSsh3Finished <> .T.) then
        lnChannel = loSsh3.QuickCmdCheck(lnPollTimeoutMs)
        if (lnChannel = -2) then
            ? loSsh3.LastErrorText
            release loSsh1
            release loSsh2
            release loSsh3
            return
        endif

        if (lnChannel = lnSsh3Channel) then
            ? "---- ssh3 channel " + str(lnChannel) + " finished ----"
            ? loSsh3.GetReceivedText(lnChannel,"ansi")
            lnNumFinished = lnNumFinished + 1
            llSsh3Finished = .T.
        endif

    endif

enddo

// --------------
// Sample output:

// 	---- ssh2 channel 101 finished ----
// 	Fri Dec 23 00:25:48 UTC 2016
// 
// 	---- ssh3 channel 102 finished ----
// 	Thu Dec 22 18:25:12 CST 2016
// 
// 	---- ssh1 channel 100 finished ----
// 	Thu Dec 22 18:25:48 CST 2016


release loSsh1
release loSsh2
release loSsh3