在使“开始作业”脚本块输出到文件时遇到一些问题。以下三行代码可以正常工作:
$about_name = "C:\0\ps_about_name.txt"
$about = get-help about_* | select Name,Synopsis
if (-not (Test-
Path $about_name)) { ($about | select Name | sort Name | Out-String).replace("[Aa]bout_", "") > $about_name }
文件在C:\ 0 \中创建
但是我需要做很多这样的收集,因此我自然地将它们作为单独的工作并行堆叠。我遵循了在线示例,因此将上面的最后一行作为由Start-Job调用的脚本块:
Start-Job { if (-not (Test-Path $about_name)) { { ($about | select Name | sort Name | Out-String).replace("[Aa]bout_", "") > $about_name } }
作业已创建,进入运行状态,然后进入已完成状态,但未创建文件。没有Start-Job,所有工作,有了Start-Job,什么都没有...我对此进行了很多尝试,但无法创建文件。有人可以告诉我我在做什么错吗?
您必须将参数发送到您的工作。这不起作用:
$file = "C:\temp\_mytest.txt"
start-job {"_" | out-file $file}
虽然这样做:
$file = "C:\temp\_mytest.txt"
start-job -ArgumentList $file -scriptblock {
Param($file)
"_" | out-file $file
}
IMO,通过使用$using
范围修饰符解决此问题的最简单方法。
$about_name = "C:\0\ps_about_name.txt"
$about = get-help about_* | select Name,Synopsis
$sb = { if (-not (Test-Path $using:about_name)) {
$using:about.Name -replace '^about_' | Sort-Object > $using:about_name
}
}
Start-Job -Scriptblock $sb
说明:
$using
允许您在远程命令中访问局部变量。这在运行Start-Job
和Invoke-Command
时特别有用。语法为$using:localvariable
。
此特定问题是可变范围问题。 Start-Job创建一个具有自己范围的后台作业。使用-Scriptblock
参数时,您正在该范围内工作。它不知道您当前的作用域/会话中定义的变量。因此,您必须使用一种将在范围内定义变量,传递变量的值或从脚本块访问局部范围的技术。您可以在About_Scopes上了解有关范围的更多信息。
此外,.NET []
方法中不支持字符集.Replace()
。您需要切换到-replace
才能使用它们。我更新了代码以不区分大小写地使用-replace
执行替换。
HCM's perfectly fine solution使用一种将值传递到作业的脚本块中的技术。通过在脚本块中定义参数,可以使用-ArgumentList
将值传递给该参数。
另一种选择是只在Start-Job
脚本块中定义变量。
$sb = { $about_name = "C:\0\ps_about_name.txt"
$about = get-help about_* | select Name,Synopsis
if (-not (Test-Path $about_name)) {
$about.Name -replace '^about_' | Sort-Object > $about_name
}
}
Start-Job -Scriptblock $sb