Sample code for 30+ languages & platforms
Visual FoxPro

SSH Parallel Remote Commands on Multiple Servers

See more SSH Examples

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

Chilkat Visual FoxPro Downloads

Visual FoxPro
LOCAL lnSuccess
LOCAL loSsh1
LOCAL loSsh2
LOCAL loSsh3
LOCAL lnPort
LOCAL lcCmd
LOCAL lnSsh1Channel
LOCAL lnSsh2Channel
LOCAL lnSsh3Channel
LOCAL lnPollTimeoutMs
LOCAL lnNumFinished
LOCAL lnChannel
LOCAL lnSsh1Finished
LOCAL lnSsh2Finished
LOCAL lnSsh3Finished

lnSuccess = 0

* 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('Chilkat.Ssh')
loSsh2 = CreateObject('Chilkat.Ssh')
loSsh3 = CreateObject('Chilkat.Ssh')

lnPort = 22
lnSuccess = loSsh1.Connect("ssh-server1.com",lnPort)
IF (lnSuccess <> 1) THEN
    ? loSsh1.LastErrorText
    RELEASE loSsh1
    RELEASE loSsh2
    RELEASE loSsh3
    CANCEL
ENDIF

* Authenticate using login/password:
lnSuccess = loSsh1.AuthenticatePw("sshLogin1","sshPassword1")
IF (lnSuccess <> 1) THEN
    ? loSsh1.LastErrorText
    RELEASE loSsh1
    RELEASE loSsh2
    RELEASE loSsh3
    CANCEL
ENDIF

* Connect and authenticate with 2 more servers.
* For brevity, the success/failure won't be checked...
lnSuccess = loSsh2.Connect("ssh-server2.com",lnPort)
lnSuccess = loSsh2.AuthenticatePw("sshLogin2","sshPassword2")
lnSuccess = loSsh3.Connect("ssh-server3.com",lnPort)
lnSuccess = 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
    CANCEL
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.
lnSsh1Finished = 0
lnSsh2Finished = 0
lnSsh3Finished = 0
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 (lnSsh1Finished <> 1) THEN
        lnChannel = loSsh1.QuickCmdCheck(lnPollTimeoutMs)
        IF (lnChannel = -2) THEN
            ? loSsh1.LastErrorText
            RELEASE loSsh1
            RELEASE loSsh2
            RELEASE loSsh3
            CANCEL
        ENDIF

        IF (lnChannel = lnSsh1Channel) THEN
            ? "---- ssh1 channel " + STR(lnChannel) + " finished ----"
            ? loSsh1.GetReceivedText(lnChannel,"ansi")
            lnNumFinished = lnNumFinished + 1
            lnSsh1Finished = 1
        ENDIF

    ENDIF

    IF (lnSsh2Finished <> 1) THEN
        lnChannel = loSsh2.QuickCmdCheck(lnPollTimeoutMs)
        IF (lnChannel = -2) THEN
            ? loSsh2.LastErrorText
            RELEASE loSsh1
            RELEASE loSsh2
            RELEASE loSsh3
            CANCEL
        ENDIF

        IF (lnChannel = lnSsh2Channel) THEN
            ? "---- ssh2 channel " + STR(lnChannel) + " finished ----"
            ? loSsh2.GetReceivedText(lnChannel,"ansi")
            lnNumFinished = lnNumFinished + 1
            lnSsh2Finished = 1
        ENDIF

    ENDIF

    IF (lnSsh3Finished <> 1) THEN
        lnChannel = loSsh3.QuickCmdCheck(lnPollTimeoutMs)
        IF (lnChannel = -2) THEN
            ? loSsh3.LastErrorText
            RELEASE loSsh1
            RELEASE loSsh2
            RELEASE loSsh3
            CANCEL
        ENDIF

        IF (lnChannel = lnSsh3Channel) THEN
            ? "---- ssh3 channel " + STR(lnChannel) + " finished ----"
            ? loSsh3.GetReceivedText(lnChannel,"ansi")
            lnNumFinished = lnNumFinished + 1
            lnSsh3Finished = 1
        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