- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我并不是要让这个问题听起来太可爱,但这确实是眼前的问题。考虑安装在 $env:PSModulePath 下的 PowerShell 模块 Test.psm1 中定义的以下两个函数:
function Start-TestAsync
{
[CmdletBinding()]
param([ScriptBlock]$Block, [string]$Name = '')
Start-Job { Start-Test -Name $using:Name -Block $using:Block }
}
function Start-Test
{
[CmdletBinding()]
param([ScriptBlock]$Block, [string]$Name = '')
# do some work here, including this:
Invoke-Command -ScriptBlock $Block
}
导入模块后,我可以运行同步功能...
PS> Start-Test -Name "My Test" -Block { ps | select -first 9 }
...并显示 Get-Process 的适当输出。
但是,当我尝试运行异步版本时...
PS> $testJob=Start-TestAsync -Name "My Test" -Block { ps | select -first 9 }
...然后查看其输出...
PS> Receive-Job $testJob
...它无法将参数引入 Start-Test 函数,报告它无法将 String 转换为 ScriptBlock。因此,-Block $using:Block
传递的是字符串而不是 ScriptBlock!
经过一些实验,我确实找到了解决方法。如果我修改 Start-Test,使 $Block 参数的类型为 [string] 而不是 [ScriptBlock] —— 然后将该字符串转换回 block 以提供给 Invoke-Command...
function Start-Test
{
[CmdletBinding()]
param([string]$Block, [string]$Name = '')
$myBlock = [ScriptBlock]::Create($Block)
Invoke-Command -ScriptBlock $myBlock
}
当我从上面运行相同的命令时,我得到了正确的结果:
PS> $testJob=Start-TestAsync -Name "My Test" -Block { ps | select -first 9 }
PS> Receive-Job $testJob
using
范围在我的初始示例中是否正常工作(将 ScriptBlock 转换为字符串)?关于它的有限文档(about_Remote_Variables,about_Scopes)提供的指导很少。最后,当 Start-Test 的 $Block 参数被键入为 [ScriptBlock] 时,有没有办法让 Start-Test 工作?
最佳答案
解决方法(来自上面的链接)是使用[ScriptBlock]::Create()
:
This happens because the $ScriptToNest scriptblock is getting converted into a string because of how PowerShell serialization works. You can work around this by explicitly creating the scriptblock. Replace the param() block in your $OuterScriptblock with the following ($ip is the input):
[scriptblock]$OuterScriptblock = {
param($ip)
[ScriptBlock]$ScriptToRun = [ScriptBlock]::Create($ip)
这将是您的解决方法(如您所见):
function Start-TestAsync
{
[CmdletBinding()]
param([ScriptBlock]$Block, [string]$Name = '')
Start-Job { Start-Test -Name $using:Name -Block $using:Block }
}
function Start-Test
{
[CmdletBinding()]
param($Block, [string]$Name = '')
# do some work here, including this:
$sb = [ScriptBlock]::Create($Block)
Invoke-Command -ScriptBlock $sb
}
关于powershell - 什么时候 ScriptBlock 不是 ScriptBlock?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25728616/
我并不是要让这个问题听起来太可爱,但这确实是眼前的问题。考虑安装在 $env:PSModulePath 下的 PowerShell 模块 Test.psm1 中定义的以下两个函数: function
我在 Scriptblock 参数中运行多个命令时遇到问题。所有文档都指向使用分号来分隔 cmdlet。使用通过分号分隔 cmdlet 的相同方法在我的本地机器上工作,但不能通过 invoke-com
我无法理解 ScriptBlock 中的范围s。我指望某种类似闭包的系统,但我似乎无法让它工作。 我有一个 ScriptBlock这需要 param并返回另一个 ScriptBlock : $sb1
我正在尝试找到一些在 PowerShell 中灵活更改/替换管道元素的方法: Function Where-DirectlyReportsTo { Param ( [Param
我写了以下代码: cls function GetFoo() { function GetBar() { $bar = "bar" $bar }
运行以下代码会产生错误,因为用于 path 的变量虽然在脚本中定义,但被解析为 null 事件: $ServerName = "test01" $RemotePath = "C:\Test\" $Te
我的程序执行用户指定的脚本 block ,我希望它以增量方式返回其输出(例如,如果脚本 block 运行很长时间)。 但是,ScriptBlock 的 API 似乎没有公开任何与管道相关的内容! 它有
PowerShell ScriptBlock 不是 lexical closure因为它不会关闭在其声明环境中引用的变量。相反,它似乎利用了在运行时绑定(bind)在 lambda 表达式中的动态范围
我正在尝试通过在文件中添加基于递增计数器的前缀来重命名文件,例如: $directory = 'C:\Temp' [int] $count=71; gci $directory | sort -Pro
我试图弄清楚 ScriptBlock.GetNewClosure() 是如何工作的。基于this线程(请参阅 Stej 的答案)我有以下代码: $i = 1 $block1 = { $i }
我的 powershell 脚本有一个 GUI。如果 C: 中的文件夹“Temp”不存在 - 创建文件夹并记录条目“Path C:\Temp 不存在 - 创建文件夹”。 这是我的代码的摘录: $inf
我的 powershell 脚本有一个 GUI。如果 C: 中的文件夹“Temp”不存在 - 创建文件夹并记录条目“Path C:\Temp 不存在 - 创建文件夹”。 这是我的代码的摘录: $inf
我有一个脚本,它有一些函数,然后在使用这些函数的同一个脚本中有多个作业。当我开始一份新工作时,它们似乎无法在 [ScriptBlock] 中访问。我有我的工作。 这是一个演示这一点的最小示例: # A
我正在尝试使用 invoke-command 在远程机器上执行代码。该方法的一部分包括一个 ScriptBlock 参数,我感觉我做的事情不正确。 首先,我尝试在脚本中创建一个方法,如下所示: par
我正在编写通用的 powershell 脚本来在远程机器上执行部署。我遇到了一个不能超限的问题,这个问题是关于在 Scriptblock 中由 ArgumentList 传递的带双引号的参数 我有这样
我正在尝试在 PowerShell ISE 中自动创建一堆选项卡 我已经开始使用一个函数,例如 function Start-NewTab($name, [ScriptBlock]$scriptBlo
我正在尝试更改 ScriptBlock 中的变量。我做错了什么? $reader=(New-Object System.Xml.XmlNodeReader $xaml) $Window=[Window
我有一个文件,我正在使用 PowerShell 4.0 从一台计算机传输到另一台计算机.我创建了一个读取缓冲区,将其转换为 Base64String,然后打开一个新的 PSSession。最后,我将这
我正在编写一个 PowerShell 脚本,它将使用 Invoke-Command 在远程主机上执行命令及其 -ScriptBlock 参数。例如, function Foo { ...
我有以下代码。 function createZip { Param ([String]$source, [String]$zipfile) Process { echo "zip: $source`
我是一名优秀的程序员,十分优秀!