redirectstanddinput对powershell远程执行没有影响

本文关键字:执行 有影响 powershell 程执行 redirectstanddinput | 更新日期: 2023-09-27 18:04:07

我正在尝试重定向输入powershell.exe远程执行。

它给出了下一个输出:

版权所有(C) 2009 Microsoft Corporation。版权所有

主机接收失败10054

所以看起来它调用了powershell,但是下一个命令没有作为输入传递,什么也没有发生,所以进程超时退出。

为什么?PowerShell是否有一些特定的输入,所以它不能像这样启动?有解决方法吗?

PS执行如下:

RemoteExecute.ExecutePowerShell(testPSName, testIp, testUserName, testPasswd);

ExecutePowerShell:

FTPTransfer.SendBinary(shellScriptName, ipaddress, userName, password); // This one sends script to remote system. Works OK.
string fullFilePath = "'"" + FTPTransfer.UploadDirectoryRootPath + shellScriptName + "'"";
string cmd;
using (StringWriter sw = new StringWriter())
{
                //sw.WriteLine("powershell.exe"); // Tried launch remexec with cmd, and then pass powershell as first parameter. Results the same, as now, so no matter.
                sw.WriteLine("Set-ExecutionPolicy RemoteSigned");
                sw.WriteLine(fullFilePath);
                cmd = sw.ToString();
}
result = ExecutePSCommandWithInput(cmd, ipaddress, userName, password);

ExecutePSCommandWithInput:

//command = cmd from ExecutePowerShell
string remexecCmd = "remexec.exe";
string remexecArgs = string.Format("{0} -q -t {1} -l {2} -p {3} powershell.exe 2>&1", ipaddress, timeout, userName, password);
result = Common.ExecuteCmdWithInput(remexecCmd, remexecArgs, command, out outp, timeout);

ExecuteCmdWithInput:

public static int ExecuteCmdWithInput(string mainCmd, string arguments, string commands, out string output, int timeout = 60000)
        {
            List<string> commandsArr = new List<string>();
            using (StringReader sr = new StringReader(commands))
            {
                string line = sr.ReadLine();
                while (!string.IsNullOrEmpty(line))
                {
                    commandsArr.Add(line);
                    line = sr.ReadLine();
                }
            }
            return ExecuteCmdWithInput(mainCmd, arguments, commandsArr.ToArray(), out output, timeout);
        }
public static int ExecuteCmdWithInput(string mainCmd, string arguments, string[] commands, out string output, int timeout = 60000)
        {
            Process p = new Process();
            p.StartInfo.UseShellExecute = false;
            p.StartInfo.RedirectStandardOutput = true;
            p.StartInfo.RedirectStandardInput = true;
            p.StartInfo.RedirectStandardError = true;
            p.StartInfo.CreateNoWindow = true;
            p.StartInfo.FileName = mainCmd;
            p.StartInfo.Arguments = arguments;
            p.Start();
            using (StreamWriter inputWriter = p.StandardInput)
            {
                foreach(string line in commands)
                {
                    inputWriter.WriteLine(line);
                }
            }
            output = p.StandardOutput.ReadToEnd();
            output += Environment.NewLine;
            output += p.StandardError.ReadToEnd();
            p.WaitForExit(timeout);
            return p.ExitCode;
        }

redirectstanddinput对powershell远程执行没有影响

PowerShell不使用标准输入或输出,所以我不得不使用变通方法,或不同的实现。

像这样解决:

string remexecArgs = string.Format("{0} -q -t {1} -l {2} -p {3} cmd 2>&1", ipaddress, timeout, userName, password);

和作为输入传递的next:

using (StringWriter sw = new StringWriter())
{
   sw.WriteLine("powershell.exe -Command Set-ExecutionPolicy RemoteSigned");
   sw.WriteLine();
   string logFilePath = "'"" + FTPTransfer.UploadDirectoryRootPath + shellScriptName + ".log'"";
   sw.WriteLine("powershell.exe -File " + fullFilePath + " " + (pars ?? string.Empty) + "> " + logFilePath);
   sw.WriteLine();
   sw.WriteLine();
   sw.WriteLine("type " + logFilePath);
   cmd = sw.ToString();
}
ExecuteOneCommandWithInput(cmd, ipaddress, userName, password, timeoutS);

必须为空行,否则会卡住

和添加到进程本身的小hack:

Process p = new Process();
p.StartInfo.UseShellExecute = false;
p.StartInfo.RedirectStandardOutput = true;
p.StartInfo.RedirectStandardInput = true;
p.StartInfo.RedirectStandardError = true;
p.StartInfo.CreateNoWindow = true;
p.StartInfo.FileName = mainCmd;
p.StartInfo.Arguments = arguments;
p.Start();
using (StreamWriter inputWriter = p.StandardInput)
{
   foreach(string line in commands)
   {
      //Wait before next input in case when empty string passed
      if (string.IsNullOrEmpty(line))
         System.Threading.Thread.Sleep(1000 * 2);
      inputWriter.WriteLine(line);
   }
}
output = p.StandardOutput.ReadToEnd();
output += Environment.NewLine;
output += p.StandardError.ReadToEnd();
p.WaitForExit(timeout);