gpt4 book ai didi

c# - 将参数从 C# 传递到调用的 PowerShell 脚本

转载 作者:行者123 更新时间:2023-11-30 12:19:30 24 4
gpt4 key购买 nike

我的 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 脚本;脚本.ps1

Param([PSCredential]$Credentials)
<code part using credentials>

pipeline.Invoke() 之后,C# 代码直接关闭,没有任何操作,也没有抛出任何错误。

我在打电话时有什么地方做错了吗?如果像下面这样从 PowerShell 调用相同的调用,则工作正常:

Invoke-Command -ComputerName <computerName> -FilePath <scipt.ps1> -ArgumentList " +  credential;

最佳答案

如果您使用 .AddScript()使用自包含命令,您必须以字符串形式嵌入参数,作为您正在使用的PowerShell代码片段的一部分通过 - 这不适用于 PSCredential 实例。

为了在单个命令的上下文中将参数作为特定的 .NET 类型传递,您可以改为使用 PowerShell带有 .AddCommand() 的实例和 AddParameter()/AddArgument()方法。

适用于您的场景:

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( ...) block ,然后调用 .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)

另见:

  • This answer有关在 C# 应用程序中使用什么 NuGet 包的指南,具体取决于主机应用程序和/或目标 PowerShell 版本。

  • This answer了解如何在使用 PowerShell SDK 的上下文中处理错误

关于c# - 将参数从 C# 传递到调用的 PowerShell 脚本,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57646703/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com