Régis
Régis

Reputation: 245

powershell v7 - Function pipeline issue

I'm trying to write 2 functions:

[Lab] is a class defined in my module.

When a run Get-Lab I correctly retrieve my lab instance with the correct type : enter image description here

When I run Remove-Lab -Lab (Get-Lab -Name Mylab), the operation is correctly performed: enter image description here

But when I try to pass the [Lab] object through the pipeline it fails.

enter image description here

The function does not receive the object through the pipeline. However I've set the -Lab Parameter as mandatory with ValueFromPipeline=$true.

Function Remove-Lab{
[CmdletBinding(DefaultParameterSetName='Lab')]
param (
    [Parameter(ValueFromPipeline=$true,ParameterSetName='Lab',Position=0,Mandatory=$true)]
    [Lab]
    $Lab,
    
    # Parameter help description
    [Parameter(Position=1,Mandatory=$false)]
    [switch]
    $Force=$false
)

begin {
    Write-host ("`tLabName : {0}" -f $Lab.Name) -ForegroundColor Yellow

    if ($null -ne $Lab) {
        $LabToRemove = $Lab
    }

    if (-not [string]::IsNullOrEmpty($LabId)) {
        $LabToRemove = Get-Lab -Id $LabId
    }

    if (-not [string]::IsNullOrEmpty($Name)) {
        $LabToRemove = Get-Lab -Name $Name
    }

    if ($null -eq $LabToRemove) {
        throw "There is no Lab with specified characteristics. Please check your input"
    }
}

process {
    $DoRemoval = $true
    if ($Force.IsPresent -eq $false) {
        while ($null -eq $UserInput -or $UserInput -notin @('Y','N')) {
            $UserInput = Read-HostDefault -Prompt "Are you sure want to remove the selected Lab and all its components ? [Y]es, [N]o" -Default 'N'

            if ($UserInput -eq 'N') {
                $DoRemoval = $false
            }
        }

        Write-Host ("`tUser Input : {0}" -f $UserInput) -ForegroundColor Green
    }

    if ($DoRemoval -eq $true) {
        Write-Host ("`tAbout to Remove the following Lab : {0}" -f $LabToRemove.Name) -ForegroundColor Green
    }
}

end {

}

}

As you can see below when a debug this function, the $Lab Parameter is null. enter image description here

Do you have any idea about this issue ?

Upvotes: 0

Views: 53

Answers (2)

Mathias R. Jessen
Mathias R. Jessen

Reputation: 174445

begin runs before anything else, including pipeline parameter binding - so you need to move code that inspects a pipeline-bound parameter (like $Lab) to the process block:

Function Remove-Lab{
[CmdletBinding(DefaultParameterSetName='Lab')]
param (
    [Parameter(ValueFromPipeline=$true,ParameterSetName='Lab',Position=0,Mandatory=$true)]
    [Lab]
    $Lab,
    
    # Parameter help description
    [Parameter(Position=1,Mandatory=$false)]
    [switch]
    $Force=$false
)

process {
    Write-host ("`tLabName : {0}" -f $Lab.Name) -ForegroundColor Yellow

    if ($null -ne $Lab) {
        $LabToRemove = $Lab
    }

    if (-not [string]::IsNullOrEmpty($LabId)) {
        $LabToRemove = Get-Lab -Id $LabId
    }

    if (-not [string]::IsNullOrEmpty($Name)) {
        $LabToRemove = Get-Lab -Name $Name
    }

    if ($null -eq $LabToRemove) {
        throw "There is no Lab with specified characteristics. Please check your input"
    }

    $DoRemoval = $true
    if ($Force.IsPresent -eq $false) {
        while ($null -eq $UserInput -or $UserInput -notin @('Y','N')) {
            $UserInput = Read-HostDefault -Prompt "Are you sure want to remove the selected Lab and all its components ? [Y]es, [N]o" -Default 'N'

            if ($UserInput -eq 'N') {
                $DoRemoval = $false
            }
        }

        Write-Host ("`tUser Input : {0}" -f $UserInput) -ForegroundColor Green
    }

    if ($DoRemoval -eq $true) {
        Write-Host ("`tAbout to Remove the following Lab : {0}" -f $LabToRemove.Name) -ForegroundColor Green
    }
}

Upvotes: 0

Theo
Theo

Reputation: 61028

Since the function is testing on $LabId or $Name, these variables need to exist in the function and at the moment they do not. Try changing the parameters to:

[CmdletBinding(DefaultParameterSetName='LabId')]
param (
    [Parameter(ValueFromPipeline=$true, ValueFromPipelineByPropertyName = $true, ParameterSetName='LabId',Position=0,Mandatory=$true)]
    [string]$LabId,

    [Parameter(ValueFromPipeline=$true, ValueFromPipelineByPropertyName = $true, ParameterSetName='LabName',Position=0,Mandatory=$true)]
    [string]$Name,

    # Parameter help description
    [switch]$Force  # no need to set a switch to $false because if you don't send that param, the undelying value will be $false by default
)

Then remove

Write-host ("`tLabName : {0}" -f $Lab.Name) -ForegroundColor Yellow

if ($null -ne $Lab) {
    $LabToRemove = $Lab
}

Important part here is the ValueFromPipelineByPropertyName = $true declaration

Upvotes: 1

Related Questions