将字符串参数发送到 Start-Job 脚本块
Send string parameters to a Start-Job script block
我需要使用 shell 初始化作业。该作业将是延迟加上对 vbScript 的调用。以下代码工作正常。对于我的示例,vbScript 只是带有 MsgBox "Hello world!"
的一行
$functions = {
Function execute_vbs {
param ([string]$path_VBScript, [int]$secs)
Start-Sleep -Seconds $secs
cscript /nologo $path_VBScript
}
}
$seconds = 2
Start-Job -InitializationScript $functions -ScriptBlock {execute_vbs -path_VBScript 'C:\Users\[USERNAME]\Desktop\hello_world.vbs' -secs $seconds} -Name MyJob
当我想参数化 vbScript 路径时,问题就来了。 (想法是对一些不同的 vbScript 进行多次不同的调用)。
当我这样做时,命令似乎忽略了参数输入。我用 int
参数做了其他测试,它们工作正常,问题看起来只与 string
参数有关。以下代码不起作用:
$functions = {
Function execute_vbs {
param ([string]$path_VBScript, [int]$secs)
Start-Sleep -Seconds $secs
cscript /nologo $path_VBScript
}
}
$input = 'C:\Users\[USERNAME]\Desktop\hello_world.vbs'
$seconds = 2
Start-Job -InitializationScript $functions -ScriptBlock {execute_vbs -path_VBScript $input -secs $seconds} -Name MyJob
我也试过使用 [-ArgumentList] 命令,但它有同样的问题。
有什么想法吗?
问题是脚本块中的 $input
和 $seconds
变量在不同的范围内,实际上是与主脚本中的变量不同的变量。
我稍微修改了您的脚本以删除对 VBScript 的调用,以便更容易在此处重现 - 我的示例代码是:
$functions = {
Function execute_vbs {
param ([string]$path_VBScript, [int]$secs)
Start-Sleep -Seconds $secs
write-output "filename = '$path_VBScript'"
write-output "secs = '$secs'"
}
}
这里有两种修复方法:
Using:作用域修饰符
请参阅 https://docs.microsoft.com/en-us/powershell/module/microsoft.powershell.core/about/about_scopes?view=powershell-7#the-using-scope-modifier 了解完整详情,但基本上:
For any script or command that executes out of session, you need the Using scope modifier to embed variable values from the calling session scope, so that out of session code can access them.
$filename = 'C:\Users\[USERNAME]\Desktop\hello_world.vbs'
$seconds = 2
$job = Start-Job -InitializationScript $functions -ScriptBlock {
execute_vbs -path_VBScript $using:filename -secs $using:seconds
} -Name MyJob
wait-job $job
receive-job $job
# output:
# filename = 'C:\Users\[USERNAME]\Desktop\hello_world.vbs'
# secs = '2'
请注意脚本块内变量名称前的 $using
- 这允许您将主脚本中的变量“注入”到脚本块中。
脚本块参数
您可以像使用函数那样在脚本块上定义参数,然后在调用 Start-Job
.
时在 -ArgumentList
参数中提供值
$filename = 'C:\Users\[USERNAME]\Desktop\hello_world.vbs'
$seconds = 2
$job = Start-Job -InitializationScript $functions -ScriptBlock {
param( [string] $f, [int] $s )
execute_vbs -path_VBScript $f -secs $s
} -ArgumentList @($filename, $seconds) -Name MyJob
wait-job $job
receive-job $job
# output:
# filename = 'C:\Users\[USERNAME]\Desktop\hello_world.vbs'
# secs = '2'
``
我需要使用 shell 初始化作业。该作业将是延迟加上对 vbScript 的调用。以下代码工作正常。对于我的示例,vbScript 只是带有 MsgBox "Hello world!"
$functions = {
Function execute_vbs {
param ([string]$path_VBScript, [int]$secs)
Start-Sleep -Seconds $secs
cscript /nologo $path_VBScript
}
}
$seconds = 2
Start-Job -InitializationScript $functions -ScriptBlock {execute_vbs -path_VBScript 'C:\Users\[USERNAME]\Desktop\hello_world.vbs' -secs $seconds} -Name MyJob
当我想参数化 vbScript 路径时,问题就来了。 (想法是对一些不同的 vbScript 进行多次不同的调用)。
当我这样做时,命令似乎忽略了参数输入。我用 int
参数做了其他测试,它们工作正常,问题看起来只与 string
参数有关。以下代码不起作用:
$functions = {
Function execute_vbs {
param ([string]$path_VBScript, [int]$secs)
Start-Sleep -Seconds $secs
cscript /nologo $path_VBScript
}
}
$input = 'C:\Users\[USERNAME]\Desktop\hello_world.vbs'
$seconds = 2
Start-Job -InitializationScript $functions -ScriptBlock {execute_vbs -path_VBScript $input -secs $seconds} -Name MyJob
我也试过使用 [-ArgumentList] 命令,但它有同样的问题。
有什么想法吗?
问题是脚本块中的 $input
和 $seconds
变量在不同的范围内,实际上是与主脚本中的变量不同的变量。
我稍微修改了您的脚本以删除对 VBScript 的调用,以便更容易在此处重现 - 我的示例代码是:
$functions = {
Function execute_vbs {
param ([string]$path_VBScript, [int]$secs)
Start-Sleep -Seconds $secs
write-output "filename = '$path_VBScript'"
write-output "secs = '$secs'"
}
}
这里有两种修复方法:
Using:作用域修饰符
请参阅 https://docs.microsoft.com/en-us/powershell/module/microsoft.powershell.core/about/about_scopes?view=powershell-7#the-using-scope-modifier 了解完整详情,但基本上:
For any script or command that executes out of session, you need the Using scope modifier to embed variable values from the calling session scope, so that out of session code can access them.
$filename = 'C:\Users\[USERNAME]\Desktop\hello_world.vbs'
$seconds = 2
$job = Start-Job -InitializationScript $functions -ScriptBlock {
execute_vbs -path_VBScript $using:filename -secs $using:seconds
} -Name MyJob
wait-job $job
receive-job $job
# output:
# filename = 'C:\Users\[USERNAME]\Desktop\hello_world.vbs'
# secs = '2'
请注意脚本块内变量名称前的 $using
- 这允许您将主脚本中的变量“注入”到脚本块中。
脚本块参数
您可以像使用函数那样在脚本块上定义参数,然后在调用 Start-Job
.
-ArgumentList
参数中提供值
$filename = 'C:\Users\[USERNAME]\Desktop\hello_world.vbs'
$seconds = 2
$job = Start-Job -InitializationScript $functions -ScriptBlock {
param( [string] $f, [int] $s )
execute_vbs -path_VBScript $f -secs $s
} -ArgumentList @($filename, $seconds) -Name MyJob
wait-job $job
receive-job $job
# output:
# filename = 'C:\Users\[USERNAME]\Desktop\hello_world.vbs'
# secs = '2'
``