Reputation: 771
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)
}
}
Upvotes: 2
Views: 896
Reputation: 5861
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
Upvotes: 2
Reputation: 47792
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)
}
}
Upvotes: 1