none
Parameter - ValidateSet/ValueFromPipeline RRS feed

  • Frage

  • Hallo allseits,

    das folgende CodeSchnipsel funktioniert (meiner Meinung nach) nicht immer richtig, und mir ist nicht klar, wieso nicht:

    Param-Example.ps1

    PARAM(
        [Parameter(Mandatory=$true,
                   ValueFromPipeline=$true,
                   HelpMessage="Geben sie die Umgebung ein (Prod/Dev/Entw)",
                   Position=0)]
        [alias("m", "modus", "umgebung")]
        [ValidateSet("Prod", "Entw", "Dev")]
        [String] 
        $mode
    )
    
    Write-Host "OK, `$mode enthaelt (anscheinend) einen gueltigen Wert!"
    Write-Host Übergebener Parameter mode: $mode
    


    Folgende Aufrufe dieses Schnipsels funktionieren völlig korrekt, bei der Parameterübergabe eines falschen Wertes (eines Wertes der nicht in obigem ValidateSet enthalten ist) gibt die PS eine Fehlermeldung aus und bricht das Script ab, bei der Übergabe eines gültigen Params wird das Script vollständig ausgeführt:

    .\Param-Example.ps1 Prod # Das Script wird vollständig, ohne Fehlermeldung ausgeführt - OK .\Param-Example.ps1 Bla # "Bla" ist kein gültiger Wert, das Script wird erwartungsgemäss abgebrochen

    # Die beiden abschliessenden "Write-Host" werden also NICHT ausgeführt - OK "Prod" | .\Param-Example.ps1 # Ein gültiger Wert wird via Pipeline übergeben, das Script wird vollständig, ohne Fehlermeldung ausgeführt - OK

    So weit ist alles klar, das funktioniert alles. Folgender Aufruf allerdings führt zu einem für mich völlig unerwarteten Verhalten...:

    PS >"Bla" | .\Param-Example.ps1
    C:\Users\31300035\PowerShell\TestScripts\Param-Example.ps1 : Das Argument für den Parameter "mode" kann nicht 
    überprüft werden. Das Argument "Bla" gehört nicht zu dem vom ValidateSet-Attribut angegebenen Satz "Prod;Entw;Dev". 
    Geben Sie ein Argument an, das in dem Satz enthalten ist, und führen Sie dann den Befehl erneut aus.
    In Zeile:1 Zeichen:9
    + "Bla" | .\Param-Example.ps1
    +         ~~~~~~~~~~~~~~~~~~~
        + CategoryInfo          : InvalidData: (Bla:String) [Param-Example.ps1], ParameterBindingValidationException
        + FullyQualifiedErrorId : ParameterArgumentValidationError,Param-Example.ps1
     
    OK, $mode enthaelt (anscheinend) einen gueltigen Wert!
    Übergebener Parameter mode: 
    
    PS >

    Wie man sieht, übergebe ich via Pipeline den eigentlich ungültigen String "Bla". Die PS erkennt offensichtlich auch, dass dieser Wert ungültig, d.h. nicht im ValidateSet enthalten ist und gibt eine dementsprechende Fehlermeldung aus.

    Allerdings wird das Script in diesem Fall NICHT abgebrochen, die beiden abschliessenden "write-host" werden (mit einem eigentlich ungültigen Wert der Variable $mode !) ausgeführt?!?

    Warum das?!?

    Wie verhindere ich bei der Parameterübergabe via Pipeline, dass das Script mit einem ungültigen Wert von $mode weiter ausgeführt wird?

    Donnerstag, 13. August 2020 16:57

Antworten

  • Moin,

    schau Dir Begin, Process und End an ;-) Wenn Du Pipeline-Eingaben akzeptieren willst, ist es nicht egal, in welchem Block Dein Code ausgeführt wird...


    Evgenij Smirnov

    http://evgenij.smirnov.de

    Donnerstag, 13. August 2020 17:20
  • Gäbe auch diese Variante:
    https://learn-powershell.net/2014/02/04/using-powershell-parameter-validation-to-make-your-day-easier/

    "It sounds like you are talking about using a function in a script that has parameter validation in which case you are correct in that it is not a terminating error in the script. What I am demonstrating is that it will cause a terminating error within the actual function that has the parameter validation, not the script. Any code that should have run in the function will not run because it was terminating during parameter validation."

    Take this example:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    Function Test-Something {
        [cmdletbinding()]
        Param(
            [parameter(ValueFromPipeline)]
            [ValidateLength(1,8)]
            [string]$Item
        )
        Process {
            $Item
        }
        End {Write-Verbose "Should display"}
    }
     
    Test-Something -Item SomeLongValue -Verbose

    You will see that the End block never runs because it fails the parameter validation. Now if I put this into another script, the error will not be terminating unless you specify $ErrorActionPreference=’Stop’ so the error with the function becomes terminating. Hope this helps!

    Donnerstag, 13. August 2020 17:55

Alle Antworten

  • Moin,

    schau Dir Begin, Process und End an ;-) Wenn Du Pipeline-Eingaben akzeptieren willst, ist es nicht egal, in welchem Block Dein Code ausgeführt wird...


    Evgenij Smirnov

    http://evgenij.smirnov.de

    Donnerstag, 13. August 2020 17:20
  • Gäbe auch diese Variante:
    https://learn-powershell.net/2014/02/04/using-powershell-parameter-validation-to-make-your-day-easier/

    "It sounds like you are talking about using a function in a script that has parameter validation in which case you are correct in that it is not a terminating error in the script. What I am demonstrating is that it will cause a terminating error within the actual function that has the parameter validation, not the script. Any code that should have run in the function will not run because it was terminating during parameter validation."

    Take this example:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    Function Test-Something {
        [cmdletbinding()]
        Param(
            [parameter(ValueFromPipeline)]
            [ValidateLength(1,8)]
            [string]$Item
        )
        Process {
            $Item
        }
        End {Write-Verbose "Should display"}
    }
     
    Test-Something -Item SomeLongValue -Verbose

    You will see that the End block never runs because it fails the parameter validation. Now if I put this into another script, the error will not be terminating unless you specify $ErrorActionPreference=’Stop’ so the error with the function becomes terminating. Hope this helps!

    Donnerstag, 13. August 2020 17:55