如何在 C# 中使用 powershell invoke-command?
How to use powershell invoke-command within C#?
如果我 运行 在 Powershell 中执行以下命令,它会按预期工作
invoke-command -computername [name] -scriptblock { ipconfig.exe > c:\ipconfig.txt }
但是当我尝试将其合并到 c# 函数中时,出现了这个错误
{"Cannot bind parameter 'ScriptBlock'. Cannot convert the
\"ipconfig.exe > c:\ipconfig.txt\" value of type \"System.String\" to
type \"System.Management.Automation.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;
}
我觉得你太复杂了:
using (PowerShell ps = PowerShell.Create())
{
ps.AddScript($@"Invoke-Command -ComputerName {name} -ScriptBlock {{ipconfig > C:\ipconfig.txt}}")
ps.Invoke()
}
或者你可以链接 .AddCommand().AddParameter()
如果我 运行 在 Powershell 中执行以下命令,它会按预期工作
invoke-command -computername [name] -scriptblock { ipconfig.exe > c:\ipconfig.txt }
但是当我尝试将其合并到 c# 函数中时,出现了这个错误
{"Cannot bind parameter 'ScriptBlock'. Cannot convert the \"ipconfig.exe > c:\ipconfig.txt\" value of type \"System.String\" to type \"System.Management.Automation.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;
}
我觉得你太复杂了:
using (PowerShell ps = PowerShell.Create())
{
ps.AddScript($@"Invoke-Command -ComputerName {name} -ScriptBlock {{ipconfig > C:\ipconfig.txt}}")
ps.Invoke()
}
或者你可以链接 .AddCommand().AddParameter()