通过SSH和Python从远程机器获取Eflow状态:无法执行PowerShell命令

1 投票
1 回答
39 浏览
提问于 2025-04-12 20:48

我在一台远程机器上运行EFlow,想要定期检查它的状态,以确保它在正常运行。

如果我通过SSH连接到这台机器,执行命令就非常简单:

powershell Get-EflowVm

但是,把这个过程自动化到Python脚本中就变得比较困难了。一般来说,通过Python进行SSH连接是很顺利的,但我就是无法让它执行这个命令。不知道为什么,特别是在运行这个命令的时候(而不是通过Python和SSH运行其他PowerShell命令),它就卡住了,无法执行这个命令,最后超时了。

我尝试了几种不同的方法来实现这个操作,下面是一些例子:

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)

或者使用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()

同样,在这两种情况下,它都只是卡在那里,没有任何响应。其他的PowerShell命令可以正常工作,而如果我手动SSH进入机器并执行这个PowerShell命令,我就能得到正常的响应。

如果能得到一些帮助,我将非常感激。

1 个回答

0

我其实并不太清楚我做的和之前有什么实际上的区别,但我还是成功解决了这个问题。结果是有效的。

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

撰写回答