"ValidateScript" and "ValueFromPipelinebyPropertyName" : good together?

This topic contains 2 replies, has 2 voices, and was last updated by Profile photo of Michel Dube Michel Dube 2 years, 1 month ago.

  • Author
    Posts
  • #26720
    Profile photo of Michel Dube
    Michel Dube
    Participant

    EDIT and answer:
    Turns out I was wrong believing that the error generated by ValidateScript would terminate the whole pipeline.

    My tests on this behavior were incomplete and led me to believe that the result would be the same as a terminating error generated inside a PROCESS code block (which terminates the whole pipeline).

    ======

    Let's say I write a function that gets a path via a parameter ($Path) and do something with it.

    Usually, I'll use the handy "ValidateScript" parameter attribute to ensure that the path is valid.

    But, if the function is written in a "pipelined" form (BEGIN, PROCESS, END) and can get the value of $Path via pipeline ("ValueFromPipelinebyPropertyName"), the entire pipeline will terminate at the first invalid $Path it encouters (because "ValidateScript" generates a terminating error).

    What would be the best practice to validate values obtained in a pipeline without terminating the entire pipeline? So, If the pipeline receives an invalid path, it displays a (non terminating) error message and just moves on to the next object.

    I managed to get this kind of behavior with a "try-catch" inside the PROCESS code block but it can get very complicated if the function can get more than 1 of its parameters via a pipeline.

    Am I missing a better way to do this?

  • #26721
    Profile photo of Don Jones
    Don Jones
    Keymaster

    Sure, that's valid. But you control whether or not the validation script returns a terminating error. Maybe it should return a non-terminating error.

    Keep in mind that whoever is RUNNING your command can add "-EA Stop" to force non-terminating errors to be trappable, terminating ones – if they want to. But the general pattern is, if you CAN keep going, you toss a non-term and keep going.

    How are you currently producing your terminating error in the validation script?

  • #26722
    Profile photo of Michel Dube
    Michel Dube
    Participant

    Thanks for the reply.

    I did some additional testing and I was wrong assuming that the error generated by ValidateScript terminates the whole pipeline.

    My tests on this behavior were incomplete and led me to believe that the result would be the same as a terminating error generated inside a PROCESS code block (which terminates the whole pipeline).

    In fact, it behaves exactly like I first expected: the pipeline moves on to the next object if ValideScript throws an error:

    function Test-PipelineError
    {
    [CmdletBinding()]
    param(    
        [parameter(ValueFromPipeline=$true,ValueFromPipelinebyPropertyName=$True)]        
        [ValidateNotNullorEmpty()]    
        [ValidateScript({Test-Path $_})]
        [string]$Path
        )
    
    BEGIN
    {    
    }
    
    PROCESS
    {
    Write-Verbose "Doing something with $Path..."
    }
           
    END
    {
    }
    
    }
    
    $Paths = "C:\Windows","invalid path","C:\Users"
    
    $Paths | Test-PipelineError -Verbose
    
    

    The output would be something like: (exactly what's expected (and preferred)

    VERBOSE: Doing something with C:\windows...
    Test-PipelineError : Cannot validate argument on parameter 'Path'....
    VERBOSE: Doing something with C:\Users...

    So, assuming that errors generated by ValidateScript are terminating, they affect pipeline execution differently than a terminating error generated inside a PROCESS block.

    Am I right?

You must be logged in to reply to this topic.