PowerShell中的函数范围变量(使用高级方法)?

时间:2014-11-21 23:29:08

标签: powershell scope powershell-v2.0

有人可以告诉我我在这里缺少什么吗?

function Test-Cmdlet {
    [CmdletBinding()]
    Param (
        [string] $Prepend,
        [parameter(ValueFromPipeline=$true)] [string] $OtherString
    )

    BEGIN 
    {
        if ($Prepend -eq $null) {
            $Prepend = ".."
        }
    }

    PROCESS
    {
        write-host ($Prepend + $OtherString)
    }
}

# success:
PS> @( "ab", "cd" ) | Test-Cmdlet "-"
-ab
-cd

# failure:
PS> @( "ab", "cd" ) | Test-Cmdlet
ab
cd

# should be:
..ab
..cd

为什么$ Prepend没有设置?

我尝试在BEGIN / PROCESS块之外声明变量,但解释器不接受。

我尝试过使用:Set-Variable -Name "Prepend" -Value ".." -Scope 1 (和范围0和范围2),而不是:$Prepend = "..",但仍然无效。

我熟悉$global:Variable,但是有没有想过如何使用高级方法在cmdlet中获取函数范围的变量?

修改

如下所示,解决方案是:

function Test-Cmdlet {
    [CmdletBinding()]
    Param (
        [string] $Prepend,
        [parameter(ValueFromPipeline=$true)] [string] $OtherString
    )

    BEGIN 
    {
        $_prepend = $Prepend

        if (!$Prepend) {
            $_prepend = ".."
        }
    }

    PROCESS
    {
        write-host ($_prepend + $OtherString)
    }
}

2 个答案:

答案 0 :(得分:2)

因为通过将$Prepend定义为参数,所以创建了一个空字符串,因此if条件永远不会应用。 您可以检查空字符串,而不是检查$null作为替代。

此致

答案 1 :(得分:1)

我必须假设您正在使用Powershell 2.0。在该版本中,当您在Begin块中设置参数值时,它不会在ProcessEnd块中保留该值。

在Powershell 3.0 +中已经改变了。

对于v2.0,为参数的值分配一个非参数变量,并在所有3个块中使用它:

function Test-Cmdlet {
    [CmdletBinding()]
    Param (
        [string] $Prepend,
        [parameter(ValueFromPipeline=$true)] [string] $OtherString
    )

    BEGIN 
    {
        if ($Prepend -eq $null) {
            $doPrepend = ".."
        } else {
            $doPrepend = $Prepend
        }
    }

    PROCESS
    {
        write-host ($doPrepend + $OtherString)
    }
}