如何使用$\uAutomatic变量调用powershell脚本块

如何使用$\uAutomatic变量调用powershell脚本块,powershell,scriptblock,automatic-variable,Powershell,Scriptblock,Automatic Variable,什么有效- 假设我有一个scriptblock,它与Select-Objectcmdlet一起使用 $jobTypeSelector = ` { if ($_.Type -eq "Foo") { "Bar" } elseif ($_.Data -match "-Action ([a-zA-Z]+)") { $_.Type + " [" + $Matches[1]

什么有效-

假设我有一个
scriptblock
,它与
Select-Object
cmdlet一起使用

$jobTypeSelector = `
    {
        if ($_.Type -eq "Foo")
        {
            "Bar"
        }
        elseif ($_.Data -match "-Action ([a-zA-Z]+)")
        {
            $_.Type + " [" + $Matches[1] + "]"
        }
        else
        {
            $_.Type
        }
    }

$projectedData = $AllJobs | Select-Object -Property State, @{Name="Type"; Expression=$jobTypeSelector}
$fooType = $jobTypeSelector.Invoke($fooJob)
这很好,我得到了预期的结果

我想做的事-

但是,在代码的后面,我想重用定义为
$jobTypeSelector
scriptblock

例如,我希望下面的代码将
$fooJob
注意,它是一个单独的对象)作为下面的参数传递,并用于
脚本块
中的
$\ucode>自动变量,并返回与在
选择对象
cmdlet上下文中执行时相同的结果

$jobTypeSelector = `
    {
        if ($_.Type -eq "Foo")
        {
            "Bar"
        }
        elseif ($_.Data -match "-Action ([a-zA-Z]+)")
        {
            $_.Type + " [" + $Matches[1] + "]"
        }
        else
        {
            $_.Type
        }
    }

$projectedData = $AllJobs | Select-Object -Property State, @{Name="Type"; Expression=$jobTypeSelector}
$fooType = $jobTypeSelector.Invoke($fooJob)
什么不起作用-

它没有像我期望的那样工作,我得到了空值

我已经尝试过的-

  • 我检查了,所有属性都设置正确,这不是因为相关属性本身为空或
    $null

  • 我在网上查了一下,似乎很难找到任何关于这个主题的相关页面,但我最终找到了一个接近于在稍微不同的背景下解释这个问题的页面-。博客并没有直接回答我的问题,任何相关的解释只会导致一个解决方案,在我看来,这个解决方案非常难看,难以阅读和维护

  • 问题-


    那么,对于使用
    $\ucode>自动变量作为参数的
    单个对象调用
    scriptblock
    的最佳方法是什么(而不是
    param
    block)

    在摆弄了varoius选项之后,我最终以一种黑客的方式解决了这个问题。。但我发现它是最好的解决方案,因为它体积小,易于阅读、维护和理解

    即使我们讨论的是单个对象,也可以在管道中使用它(当
    PowerShell
    定义
    $\ucode>自动变量时),使用
    ForEach object
    cmdlet

    $fooType = $fooJob | ForEach-Object $jobTypeSelector
    

    您当然可以使用您提到的
    foreach
    foreach对象

    如果通过将
    IsFilter
    设置为
    $true
    ,将ScriptBlock从函数ScriptBlock更改为过滤器ScriptBlock,则也可以直接通过管道连接到ScriptBlock:

    $jobTypeSelector.IsFilter = $true
    
    $fooType = $fooJob | $jobTypeSelector
    
    但是,如果使用命名函数而不是匿名脚本块,则更好,例如:

    function Get-JobType
    {
        Param ( 
            [object] $Job 
        )
    
        if ($Job.Type -eq "Foo")
        {
            "Bar"
        }
        elseif ($Job.Data -match "-Action ([a-zA-Z]+)")
        {
            $Job.Type + " [" + $Matches[1] + "]"
        }
        else
        {
            $Job.Type
        }
    }
    
    然后您可以将其与
    Select Object
    aka
    Select
    一起使用,如下所示:

    $projectedData = $AllJobs |
        select -Property State, @{Name="Type"; Expression={Get-JobType $_}}
    
    $fooType = Get-JobType $fooJob
    
    或者只做一份工作,就像这样:

    $projectedData = $AllJobs |
        select -Property State, @{Name="Type"; Expression={Get-JobType $_}}
    
    $fooType = Get-JobType $fooJob
    

    谢谢你的回复。。我知道这可能是一个函数。。但是关于你提到的另一个选择。。将
    IsFilter
    设置为
    $true
    。。我收到以下错误-
    异常设置“IsFilter”:“由于对象的当前状态,操作无效。”
    。知道为什么吗?如何设置它。。?该物业的文档和示例似乎非常差。。我找不到任何方法来创建使用此状态初始化的脚本块。