PowerShell作业,正在写入文件

PowerShell作业,正在写入文件,powershell,jobs,Powershell,Jobs,获取要输出到文件的开始作业脚本块时遇到一些问题。以下三行代码工作正常: $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

获取要输出到文件的开始作业脚本块时遇到一些问题。以下三行代码工作正常:

$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中创建的\

但是我需要做很多这样的收集工作,所以我很自然地把它们作为单独的工作并行地堆叠起来。我遵循了在线示例,因此将上面的最后一行作为启动作业调用的脚本块:

启动作业{if-not Test Path$about_name{{{$about | select name | sort name | Out String.replace[Aa]about|,>$about_name}


作业已创建,进入“运行状态”,然后进入“已完成状态”,但未创建任何文件。如果没有“启动作业”,则所有作业都可以,如果没有“启动作业”,则什么也没有…我尝试了很多方法,但无法让它创建文件。有人能告诉我这方面的错误吗?

您必须将参数发送到作业中。 这不起作用:

$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
}

你必须将你的参数发送到你的工作中。 这不起作用:

$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允许您访问远程命令中的本地变量。这在运行启动作业和调用命令时特别有用。语法为$using:localvariable

此特定问题是一个变量作用域问题。创建一个具有自己作用域的后台作业。使用-Scriptblock参数时,您正在该作用域内工作。它不知道在当前作用域/会话中定义的变量。因此,您必须使用一种技术来定义作用域内的变量,传入变量的值,或从脚本块访问本地作用域。有关作用域的详细信息,请访问

另一方面,.NET.Replace方法不支持字符集[]。您需要切换到-Replace以利用这些字符集。我更新了代码以不敏感地使用-Replace大小写执行Replace

使用将值传递到作业脚本块的技术。通过在脚本块中定义参数,可以使用-ArgumentList将值传递到该参数

另一个选项是只在开始作业脚本块中定义变量

$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

在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允许您访问远程命令中的本地变量。这在运行启动作业和调用命令时特别有用。语法为$using:localvariable

此特定问题是一个变量作用域问题。创建一个具有自己作用域的后台作业。使用-Scriptblock参数时,您正在该作用域内工作。它不知道在当前作用域/会话中定义的变量。因此,您必须使用一种技术来定义作用域内的变量,传入变量的值,或从脚本块访问本地作用域。有关作用域的详细信息,请访问

另一方面,.NET.Replace方法不支持字符集[]。您需要切换到-Replace以利用这些字符集。我更新了代码以不敏感地使用-Replace大小写执行Replace

使用将值传递到作业脚本块的技术。通过在脚本块中定义参数,可以使用-ArgumentList将值传递到该参数

另一个选项是只在开始作业脚本块中定义变量

$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

这是一个范围问题,您在当前范围中定义的变量没有在作业的范围中定义。您只需将作业脚本块中的$about\u name和$about替换为$using:about\u name和$using:about。谢谢,我更喜欢您答案中的语法,因为这意味着我不必在块中定义参数,所以我将使用您r方式,因为它更清晰和简洁,但hcm的答案对我来说也很重要,以了解如何处理这些问题,因此我将其标记为答案,就像它是唯一一个集作为答案一样。我认为您的字符串替换代码没有按预期工作,因为.Replace不理解字符集[]。如果你想要那个功能,你应该切换到-replace。我应该已经看到了,当然你是对的!我有时会把它们弄混,但我在这里还没有看到。谢谢,这节省了我一些时间,因为我不可避免地要找到它!:这是一个范围问题,你在当前范围内定义的变量在你可以简单地用$using:about\u name和$using:about替换你的作业脚本块中的$about\u name和$about。谢谢,我更喜欢你答案中的语法,因为这意味着我不必在块中定义参数,所以我将使用你的方式,因为它更清晰、简洁,但hcm的答案对我理解h也很重要如何处理这些问题,所以我将把它标记为答案,就像它是唯一的一个答案一样
字符串替换代码未按预期工作,因为.Replace不理解字符集[]。如果你想要这个功能,你应该切换到-replace。我应该看到这一点,当然你是对的!我有时把他们搞混了,我还没在这里看到。谢谢,这节省了我一些时间,因为我不可避免地要找到它