【问题标题】:RedirectStandardInput has no effect for powershell remote executionRedirectStandardInput 对 powershell 远程执行没有影响
【发布时间】:2015-07-23 09:11:08
【问题描述】:

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

它给了我下一个输出:

Windows PowerShell 版权所有 (C) 2009 Microsoft Corporation。保留所有权利。

主机接收失败 10054

看起来它调用了powershell,但是下一个命令没有作为输入传递,没有任何反应,所以进程超时退出。

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

PS 如下执行:

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

执行PowerShell:

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;
        }

【问题讨论】:

    标签: c# powershell input process


    【解决方案1】:

    PowerShell 不使用标准输入或输出,因此我不得不使用解决方法或不同的实现。

    这样解决:

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

    接下来作为输入传递:

    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);
    

    空行不宜,否则卡住

    并为进程本身添加了小技巧:

    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);
    

    【讨论】:

      猜你喜欢
      • 2014-12-15
      • 1970-01-01
      • 1970-01-01
      • 2021-05-10
      • 1970-01-01
      • 1970-01-01
      • 2022-10-12
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多