如何将ScriptBlocks合并到托管的powershell环境中

本文关键字:powershell 环境 ScriptBlocks 合并 | 更新日期: 2023-09-27 18:22:08

我最近开始探索powershell脚本和powershell托管。

在powershell命令提示符下,如我所期望的那样执行以下行。

"fee" | &{ process { $_; $args } } "fi" "fo" "fum"

该脚本输出管道中的"费用"($_)加上作为参数传递给scriptBlock($args)的"fi"、"fo"answers"fum"。

我正试图通过使用System.Management.Automation.Powershell类来实现同样的结果。

当我尝试这个:

        using (var ps = PowerShell.Create())
        {
            var result = ps
                .AddScript(@"&{ process { $_; $args} }")
                    .AddArgument("fi")
                    .AddArgument("fo")
                    .AddArgument("fum")
                .Invoke(Enumerable.Repeat("fee", 1));
        }

我的结果数组包含一个null元素(不确定那里发生了什么)。

如果我尝试这个:

        using (var ps = PowerShell.Create())
        {
            var result = ps
                .AddCommand("Invoke-Command")
                    .AddParameter("ScriptBlock", ScriptBlock.Create(@"&{ process { $_; $args } }"))
                    .AddParameter("ArgumentList", new string[] { "fi", "fo", "fum"})
                .Invoke(Enumerable.Repeat("fee", 1));
        }

只输出"费用"。$args数组为空。

最后,当我尝试这个:

        using (var ps = PowerShell.Create())
        {
            var result = ps
                .AddCommand("Invoke-Command")
                    .AddParameter("ScriptBlock", ScriptBlock.Create(@"&{ process { $_; $args } } ""fi"" ""fo"" ""fum"""))
                .Invoke(Enumerable.Repeat("fee", 1));
        }

我离得最近。管道化的"fee"、"fi"、"fo"answers"fum"参数都会输出。然而,这个问题是,理想情况下,我更喜欢动态地将参数传递给scriptBlock,而不是将它们连接到脚本块表达式中。

我的问题是,如何在托管的powershell环境中创建一个脚本块,既可以访问调用它的管道中的数据,也可以接受参数?我只能实现其中的一个。我使用的是.Net框架的4.5版和System.Management.Automation程序集的3版。

如何将ScriptBlocks合并到托管的powershell环境中

这是因为AddScript使用了错误的脚本,不应该使用&{},因为它实际上是由C#代码中的Invoke()完成的。以下是运行的C#代码的PowerShell模拟:

$ps = [powershell]::Create()
$ps.AddScript('process { $_; $args}').
AddArgument('fi').
AddArgument('fo').
AddArgument('fum').
Invoke(@('fee'))

输出:

fee
fi
fo
fum

正如预期的那样。