首页 > 解决方案 > 如何在 C# 中使用 powershell 调用命令?

问题描述

如果我在 Powershell 中运行以下命令,它会按预期工作

invoke-command -computername [name] -scriptblock { ipconfig.exe > c:\ipconfig.txt }

但是当我尝试将其合并到 ac# 函数中时,我收到了这个错误

{"无法绑定参数 'ScriptBlock'。无法将类型为 \"System.String\" 的 \"ipconfig.exe > c:\ipconfig.txt\" 值转换为类型 \"System.Management.Automation.ScriptBlock\"。 "}

即使我将 scriptblock 参数值转换为 System.Management.Automation.ScriptBlock 对象?我在做什么不正确?

    private void btnInstallTest_Click(object sender, EventArgs e)
    {
        List<string> commands = new List<string>();

        commands.Add("invoke-command");
        List<Tuple<String, String>> parameters = new List<Tuple<string, string>>();
        parameters.Add(new Tuple<string, string>("computername", @"server"));
        parameters.Add(new Tuple<string, string>("ScriptBlock", @"ipconfig.exe > c:\ipconfig.txt"));

        Collection<PSObject> psobject = runRemotePowerShellCommands(commands, parameters, "server", @"domain\user", convertToSecureString("password"));          
    }

    private Collection<PSObject> runRemotePowerShellCommands(List<string> commands, List<Tuple<String, String>> parameters, string remoteMachineName, string domainAndUsername, SecureString securePW)
    {
        Collection<PSObject> psobjs = new Collection<PSObject>();
        string result = "";
        string shellUri = "http://schemas.microsoft.com/powershell/Microsoft.PowerShell";
        PSCredential psCredential = new PSCredential(domainAndUsername, securePW);
        WSManConnectionInfo connectionInfo = new WSManConnectionInfo(false, remoteMachineName, 5985, "/wsman", shellUri, psCredential);
        connectionInfo.AuthenticationMechanism = AuthenticationMechanism.Kerberos; //.Basic;

        using (Runspace runspace = RunspaceFactory.CreateRunspace(connectionInfo))
        {
            PowerShell powershell = PowerShell.Create();
            for (int i = 0; i < commands.Count; i++)
            {
                if (commands[i].Contains(";"))
                {

                    string[] commandsSplit = commands[i].Split(';');
                }
                else
                {
                    powershell.AddCommand(commands[i]);
                }

                System.Management.Automation.ScriptBlock sb = null;
                if (parameters != null)
                {
                    foreach (Tuple<string, string> param in parameters)
                    {
                        if (param.Item1.ToLower() == "scriptblock")
                        {
                            sb = ScriptBlock.Create(param.Item2);                                
                            powershell.AddParameter(param.Item1, sb);
                            //powershell.AddParameter(param.Item1, param.Item2);
                        }
                        else
                        {
                            powershell.AddParameter(param.Item1, param.Item2);
                        }
                    }
                }

                if (runspace.RunspaceStateInfo.State == RunspaceState.Opened)
                {
                    // do nothing, the runspace is already open
                }
                else
                {
                    runspace.Open();                        
                    powershell.Runspace = runspace;
                }

                try
                {
                    psobjs = powershell.Invoke();

                    if (powershell.HadErrors == true)
                    {
                        result = "Failed - " + powershell.Streams.Error[0].ToString();
                        result = result.Replace("\"", "*");
                        psobjs.Add(result);
                    }
                }
                catch (Exception ex)
                {
                    result = "Failed: " + ex.Message;
                    psobjs.Add(result);
                }
            }

            powershell.Commands.Clear();                
        }

        return psobjs;
    }

标签: c#powershellrunspacescriptblock

解决方案


我觉得你把这个超级复杂化了:

using (PowerShell ps = PowerShell.Create())
{
    ps.AddScript($@"Invoke-Command -ComputerName {name} -ScriptBlock {{ipconfig > C:\ipconfig.txt}}")
    ps.Invoke()
}

或者,您可以链接.AddCommand().AddParameter()


推荐阅读