2

Can someone please tell me what I'm missing here?

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

Why is $Prepend not getting set?

I've tried declaring variables outside the BEGIN/PROCESS blocks, but the interpreter doesn't accept that.

I've tried using: Set-Variable -Name "Prepend" -Value ".." -Scope 1 (and Scope 0, and Scope 2), instead of: $Prepend = "..", but still nothing works.

I'm familiar with $global:Variable, but any idea how to get function-scoped variables in a cmdlet with Advanced Methods?

Edit:

The solution, as per below, is:

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

    BEGIN 
    {
        $_prepend = $Prepend

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

    PROCESS
    {
        write-host ($_prepend + $OtherString)
    }
}
2
  • This bypasses the question all together but could you have not just declared the parameter with a default value? [string] $Prepend="..", Commented Nov 22, 2014 at 2:40
  • @Matt, yes, but this is just an example problem, the real issue wasn't about setting a default, but changing the parameter in the BEGIN block Commented Nov 25, 2014 at 8:48

2 Answers 2

2

Because by defining $Prepend as a parameter an empty string is created so your if condition never applys. You can check for an empty string instead of checking for $null as an alternative.

Regards

Sign up to request clarification or add additional context in comments.

3 Comments

Yes, good point, I normally use if (!$Parameter) { $Parameter = ... }
@SamPorch yep that works too, so was this the problem or does it still not work as expected?
The central issue was setting the variable in the "Begin" block, but certainly this would have caused problems also.
1

I have to assume that you're using Powershell 2.0 for this. In that version, when you set the value of a parameter in the Begin block, it will not retain that value in the Process or End blocks.

This was changed in Powershell 3.0+.

For v2.0, assign a non-parameter variable the value of the parameter and use that throughout all 3 blocks:

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

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.