![](/img/trans.png)
[英]Calling powershell script with C# - passing in string array as argument in powershell
[英]Passing argument from C# to called PowerShell Script
我在C#文件中有以下功能:
private void RunScriptFile(string scriptPath, string computerName, PSCredential credential)
{
RunspaceConfiguration runspaceConfiguration = RunspaceConfiguration.Create();
Runspace runspace = RunspaceFactory.CreateRunspace(runspaceConfiguration);
runspace.Open();
RunspaceInvoke scriptInvoker = new RunspaceInvoke(runspace);
Pipeline pipeline = runspace.CreatePipeline();
string scriptCommand = "Invoke-Command -ComputerName " + computerName + " -FilePath " + scriptPath + " -ArgumentList " + credential;
pipeline.Commands.AddScript(scriptCommand);
Collection<PSObject> results = pipeline.Invoke();
runspace.Close();
}
我使用上面的C#代码中传递的凭据调用以下PowerShell脚本; script.ps1
Param([PSCredential]$Credentials)
<code part using credentials>
在pipeline.Invoke()
,C#代码只是在没有任何操作的情况下关闭,也没有抛出任何错误。
打电话时我有什么问题吗? 如果从PowerShell调用如下调用相同的调用工作正常:
Invoke-Command -ComputerName <computerName> -FilePath <scipt.ps1> -ArgumentList " + credential;
如果你使用带有自包含命令的.AddScript()
- 看似是CommandCollection.AddScript()
的唯一选项 - 你只能以字符串形式嵌入参数 ,作为你传递的PowerShell代码片段的一部分 - 而且不适用于PSCredential
实例。
为了在单个命令的上下文中将参数作为特定的.NET类型传递 ,您可以使用带有.AddCommand()
和AddParameter()
/ AddArgument()
方法的PowerShell
实例。
适用于您的场景:
private void RunScriptFile(string scriptPath, string computerName, PSCredential credential) {
Collection<PSObject> results;
using (var ps = PowerShell.Create()) {
ps.AddCommand("Invoke-Command")
.AddParameter("ComputerName", computerName)
.AddParameter("FilePath", scriptPath)
.AddParameter("ArgumentList", new object[] { credential })
results = ps.Invoke();
}
}
这种方法的另一个优点是不需要解析PowerShell代码,这样可以更快,更健壮。
通常, PowerShell
类的使用简化了PowerShell SDK的使用,并且在许多情况下已足够(通常不需要明确地管理运行空间,管道,...)。
但是,正如PetSerAl指出的那样, PowerShell.AddScript()
可以接受类型化参数 ,如果您通过param(...)
块重新.AddParameter()
声明(类型化)参数的代码片段 ,然后调用.AddParameter()
/ .AddArgument()
:
ps.AddScript(@"param([string] $ComputerName, [string] $FilePath, [pscredential] $Credential) Invoke-Command -ComputerName $ComputerName -FilePath $FilePath -ArgumentList $Credential")
.AddArgument(computerName)
.AddArgument(scriptPath)
.AddArgument(credential)
然而,正如您所看到的,这使得解决方案更加冗长。
声明参数会使意图更加明显,但您也可以使用自动的,数组值$args
变量来访问以位置方式传递的参数 :
ps.AddScript(@"Invoke-Command -ComputerName $args[0] -FilePath $args[1] -ArgumentList $args[2]")
.AddArgument(computerName)
.AddArgument(scriptPath)
.AddArgument(credential)
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.