Get Eflow status from a remote machine via ssh and python: does not execute powershell command

41 views Asked by At

I have EFlow running on a remote machine and want to poll the status to ensure that it is running.

If I SSH into the machine, it is as easy as running the command

powershell Get-EflowVm

however, automating this in a python script have proven more difficult. In general, ssh via python works like a charm, I just can't get it to run this command. Somehow, specifically when running this command (and not other powershell commands via python and ssh) it stalls, does not execute the command, and end up timing out.

I have tried in a few different ways to do this manouvre, some examples below:

import subprocess

r = subprocess.Popen(f"sshpass -p <pw> ssh <user>@<host> ""powershell Get-EflowVm", shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE).communicate(timeout=60)

or with paramiko:

import paramiko

host = <host>
user = <user>
pw = <pw>

client = paramiko.client.SSHClient()

client.set_missing_host_key_policy(paramiko.AutoAddPolicy())

client.connect(host, port=22, username=user, password=pw, timeout=60)

stdin, stdout, stderr = client.exec_command("powershell Get-EflowVm")

client.close()

Again, in either case, it just hangs and provides no response. Other powershell commands work, and if I manually ssh into the machine and execute the powershell command, I get a response just fine.

Any help would be much appreciated.

1

There are 1 answers

0
Jesper Christensen On

I was able to solve this without really knowing what the difference in practice is compared to what I was already doing. It works, however.

import threading
import paramiko

class ssh:
    shell = None
    client = None
    transport = None

    def __init__(self, address, username, password):
        print("Connecting to server on ip {}".format(address))
        
        self.fulldata = ""
        self.running = False
        
        self.client = paramiko.client.SSHClient()
        self.client.set_missing_host_key_policy(paramiko.client.AutoAddPolicy())
        
        self.client.connect(address, username=username, password=password, look_for_keys=False)
        
        self.transport = paramiko.Transport((address, 22))
        
        self.transport.connect(username=username, password=password)

        thread = threading.Thread(target=self.process)
        thread.daemon = True
        thread.start()

    def close_connection(self):
        if(self.client != None):
            self.client.close()
            self.transport.close()
            self.running = False

    def open_shell(self):
        self.shell = self.client.invoke_shell()

    def send_shell(self, command):
        if(self.shell):
            self.shell.send(command + "\n")
        else:
            print("Shell not opened.")

    def process(self):
        self.running = True
        
        while self.running:
            # Print data when available
            if self.shell is not None and self.shell.recv_ready():
                alldata = self.shell.recv(1024).decode()
                while self.shell.recv_ready():
                    alldata += self.shell.recv(1024)
                
                self.fulldata = self.fulldata + str(alldata)
                

def get_eflow_status(config):
    sshUsername = config["username"]
    sshPassword = config["password"]
    sshServer = config["address"]

    connection = ssh(sshServer, sshUsername, sshPassword, debug_logger)
    connection.open_shell()
    connection.send_shell('powershell "Get-EflowVM | Select -ExpandProperty VmPowerState | Format-List"\r')
    time.sleep(15)
    ret = connection.fulldata
    connection.close_connection()
    if "Running" in ret:
        return True
    else:
        return False