Winforms 向PowerShell中的SSH会话发送命令,并在文本框中接收输出

Winforms 向PowerShell中的SSH会话发送命令,并在文本框中接收输出,winforms,powershell,ssh,batch-processing,plink,Winforms,Powershell,Ssh,Batch Processing,Plink,我需要向几个设备发送命令列表。对于每个IP,使用来自用户和密码文本框的给定凭据打开SSH连接,运行所有命令并将输出返回到输出文本框 通常我会用 plink.exe-sshadmin@172.16.17.18-pw PassW0rd“命令” 不幸的是,远程主机不允许我这样做: 已发送密码 允许访问 作为主渠道的开幕式 开放式主航道 服务器拒绝启动shell/命令 致命错误:服务器拒绝启动shell/命令 但是,如果我连接时未传递命令: 已发送密码 允许访问 作为主渠道的开幕式 开放式主航道

我需要向几个设备发送命令列表。对于每个IP,使用来自用户和密码文本框的给定凭据打开SSH连接,运行所有命令并将输出返回到输出文本框

通常我会用

plink.exe-sshadmin@172.16.17.18-pw PassW0rd“命令”
不幸的是,远程主机不允许我这样做:

已发送密码
允许访问
作为主渠道的开幕式
开放式主航道
服务器拒绝启动shell/命令
致命错误:服务器拒绝启动shell/命令
但是,如果我连接时未传递命令:

已发送密码
允许访问
作为主渠道的开幕式
开放式主航道
分配pty(ospeed 38400bps,ispeed 38400bps)
启动一个shell/命令
欢迎来到XXX
系统名称>#
现在,我可以键入命令并执行它们。我尝试了Poshsh,它允许我连接,但任何命令都会超时

我将IP和命令框中的行分解为字符串数组并生成循环。然后我用
Start Job
SystemDiagnostics.Process*
尝试了几种方法,但都没有成功。 现在我有点不知所措,希望能得到任何帮助:

($a=0;$a-lt$IPArray.Length;$a++)的
{
#使用类似于plink的工具打开交互式会话
#plink.exe-ssh'+$User+'@'+$IPArray[$a]+'-pw'+$Passwd
对于($b=0;$b-lt$CommandArray.Length;$b++){
#将$CommandArray[$b]发送到plink会话
#等待命令完成
#读取输出并将其发送到文本框
}
}

编辑:感谢Martin Prikryl的回答,我更进一步:

($a=0;$a-lt$IPArray.Length;$a++)的
{
$User=$UserTextBox.text
$IP=$IPArray[$a]
#$Passwd=$PwdTextBox.Text
$Outputtext=$Outputtext+“~~~~~~~+$IP+”~~~~~~“+”`r`n”
$isSession=新SSHSSession-ComputerName$IP-Credential$User
$isStream=$isSession.Session.CreateShellStream(“PS-SSH”,0,0,0,0,1000)
对于($b=0;$b-lt$CommandArray.Length;$b++){
$Command=$CommandArray[$b]
$isStream.WriteLine($Command)
开始睡眠-秒1
}
$isReturn=$isStream.Read()
$Outputtext=$Outputtext+$isReturn+“`r`n”
$outputBox.Text=$Outputtext
}
返回:

~~~~~~~172.16.17.18~~~~~
欢迎来到XXX
系统18>回声1
1.
系统18>回声2
2.
系统_18>#ping 8.8.8.8
PING 8.8.8.8 56个数据字节
~~~~~ 172.16.17.19 ~~~~~
欢迎来到XXX
系统_19>#回波1
1.
系统19>回声2
2.
系统_19>#ping 8.8.8.8
PING 8.8.8.8 56个数据字节
~~~~~ 172.16.17.20 ~~~~~
欢迎来到XXX
系统20>回声1
1.
系统20>回声2
2.
系统(U 20>#ping 8.8.8.8
PING 8.8.8.8 56个数据字节
现在我需要实现两件事:

  • 从相应的输入字段获取凭据(目前,我需要为每个IP键入一次密码)

    完成:

    $User=$UserTextBox.text
    $Passwd=converttosecurestring$PwdTextBox.Text-AsPlainText-Force
    $SSHCred=新对象System.Management.Automation.PSCredential-ArgumentList($User,$Passwd)
    # ...
    $isSession=新SSHSSession-ComputerName$IP-Credential$SSHCred
    
  • 让它等待命令完成,然后再发送下一个命令。(目前,它只需等待1秒)

  • 然而,我很高兴远程主机现在至少能和我交谈。 多谢各位


    如果我需要脚本方面的进一步帮助或继续记录进度,我是否应该在此处提出新问题?

    您显然连接到了某个“设备”,而不是完整的服务器。嵌入式SSH实现通常不实现SSH“exec”通道。您必须使用“shell”通道(否则不推荐用于命令自动化)

    使用Plink,您可以通过将“命令”写入Plink输入,而不是使用
    -m
    开关来实现这一点

    另见


    尽管您不应该运行外部应用程序来实现SSH。使用本机.NET SSH实现,如。在“shell”通道中使用SSH.NET执行命令的伪代码:


    “shell”通道是一个带有输入和输出的黑盒。没有可靠的方法使用它来执行命令、读取其输出以及执行其他命令。当命令执行结束时,您没有API可以告诉您。这就是为什么我在上面写到,命令自动化不建议使用“shell”通道。您所能做的就是解析shell输出并查找设备的命令提示符:
    System\u 20>

    ,并提供指针。另外,您希望远程运行哪个shell?1)不要运行外部应用程序来实现SSH。使用本机.NET SSH实现,如SSH.NET。2) 显然,您正在连接到某个“设备”,而不是完整的服务器。嵌入式SSH实现通常不实现SSH“exec”通道。你必须使用“shell”频道(否则不推荐用于命令自动化)。在发布这个问题之前,我阅读了这两个频道。远程设备是诺基亚接入多路复用器,运行专有操作系统。恐怕在这方面我无能为力。向下投票是不合理的,因为它为我指明了正确的方向。解析shell输出是有效的:``` for($b=0;$b-lt$CommandArray.Length;$b++){$Command=$CommandArray[$b]$isStream.WriteLine($Command),而($isReturn.Endswith(“>#”)则是-ne“True”){$isReturn=$isStream.Read()$Outputtext=$Outputtext+$isReturn$outputBox.Text=$Outputtext$outputBox.SelectionStart=$outputBox.TextLength;$outputBox.ScrollToCaret();开始睡眠-200毫秒}“现在一切正常,再次感谢你。”。
    var client = new SshClient(...);
    client.Connect();
    var shell = client.CreateShellStream(...);
    shell.WriteLine("command");
    var output = shell.Read();