Suppress prompts for mandatory parameters

Welcome Forums General PowerShell Q&A Suppress prompts for mandatory parameters

This topic contains 17 replies, has 5 voices, and was last updated by

 
Participant
4 months, 3 weeks ago.

  • Author
    Posts
  • #118831

    Participant
    Points: 38
    Rank: Member

    Is it possible to suppress prompts for mandatory parameters?

    Example:

    get-process | where

    => prompts for a property

    I want this line to simply fail for error handling with try/catch

  • #118842

    Participant
    Points: 1,628
    Helping Hand
    Rank: Community Hero

    You can't suppress prompting of a mandatory parameter, that doesn't make sense.
    You can do something like below for throwing exception.

    Param(
    [Parameter()]
    $Param = $(Throw "You have to pass some value for Param")
    )
    

    This is by making thro statement as default value for this parameter, and when the value is not passed, it will take the default value which is a throw statement.

    • #118894

      Participant
      Points: 38
      Rank: Member

      "that doesn't make sense" is a bold claim 🙂

  • #118900
    js

    Participant
    Points: 743
    Helping Hand
    Rank: Major Contributor

    How about

    get-process | where $a
    

    Then if $a is null, it will trigger a terminating error.

  • #118905

    Participant
    Points: 1,628
    Helping Hand
    Rank: Community Hero

    @kort3x , Can you let us know what you are trying to achieve ?

  • #119256

    Participant
    Points: 1,139
    Helping Hand
    Rank: Community Hero

    'Is it possible to suppress prompts for mandatory parameters?'

    Simply put, nope. This is like saying can I start my car without any fuel in it.  ;^}   Mandatory means, you have to have it.

    'get-process | where # => prompts for a property'

    and that is by design, you are asking a question and the question must be complete or it cannot be answered.

    'I want this line to simply fail for error handling with try/catch'

    You cannot catch what you do not define in some way.

    Otherwise..

    • What kvprasoon said in the post before mine...
    • If you are just trygint o throw a random error to see what is in it, the what js said.
    • #119259

      Participant
      Points: 38
      Rank: Member

      Simply put, nope. This is like saying can I start my car without any fuel in it.  ;^}   Mandatory means, you have to have it.

      It's more like turning of the gas gage.

      and that is by design, you are asking a question and the question must be complete or it cannot be answered.

      I don't want an answer if i haven't finished the question yet.

      You cannot catch what you do not define in some way.

      That is excactly what try/catch is for, like this:

      try{
         $null | Get-Acl -ErrorAction Stop
      }
      catch {
         write-host "It's null dude"
      }

      "-path" is missing which get's caught.

  • #119262

    Participant
    Points: 38
    Rank: Member

    For those interested and not simply writing off my question as nonsense:

    I think I found a way by pre-parsing and analyzing the paramters/parametersets.

    • #119294

      Participant
      Points: 1,628
      Helping Hand
      Rank: Community Hero

      When you say pre parsing, Is it by getting the function/script properties and understanding the parameter attributes and proceed ?

  • #119312
    js

    Participant
    Points: 743
    Helping Hand
    Rank: Major Contributor
    That is excactly what try/catch is for, like this:
    
    try{
       $null | Get-Acl -ErrorAction Stop
    }
    catch {
       write-host "It's null dude"
    }
    
    "-path" is missing which get's caught.
    

    Well, in this case you're sending the path over the pipe as $null, since path can be sent byvalue over the pipe. What are you trying to do?

  • #119330

    Participant
    Points: 1,139
    Helping Hand
    Rank: Community Hero

    As for ...

    For those interested and not simply writing off my question as nonsense:

    … I don't think that is what any of us are, saying, well, I'm, not, but I just can't come to any resolution as to why this would be a use case.

    So, by this...

    I think I found a way by pre-parsing and analyzing the paramters/parametersets.

    … that's cool and all, but you are not showing it, thus you being able to solve this without any of our input thus far. Which again is cool and a feel good moment for you. We applaud that. Yet, if you mean you did stuff like the below (may be even using this in a dynamic param approach in your use case), then that's a pretty common approach in the dev cycle.

    (Get-Command -Name Get-ADUser).Parameters
    
    Get-Help Get-Service -Parameter * | Select-Object -ExpandProperty name
    
    Get-Help Get-Service -Parameter * `
    | Where-Object { $_.pipelineInput.Length -gt 10 } `
    | Select-Object -Property name, pipelineinput, parameterValue
    
    # List of all parameters that a given cmdlet supports along with a short description:
    Get-Help dir -para * |
    Format-Table Name, { $_.Description[0].Text } -wrap
    
    # Find all cmdlets / functions with a target parameter
    Get-Command -CommandType Function |
    Where-Object { $_.parameters.keys -match 'credential'} |
    Out-GridView -PassThru -Title 'Available functions which has a specific parameter'
    
    Get-Command -CommandType Cmdlet |
    Where-Object { $_.parameters.keys -match 'credential'} |
    Out-GridView -PassThru -Title 'Results for cmdlets which has a specific parameter'
    
    # Get named aliases
    Get-Alias |
    Out-GridView -PassThru -Title 'Available aliases'
    
    # Get cmdlet / function parameter aliases
    (Get-Command Get-ADUser).Parameters.Values |
    where aliases |
    select Name, Aliases | Out-GridView -PassThru -Title 'Alias results for a given cmdlet or function.'
    

     

    • #119332

      Participant
      Points: 38
      Rank: Member

      Everybody chill 🙂 I am sorry for losing my cool.

      Here is my parsing function so far (work in progress):

      function parse-dypCommand ($userCommand) {
         $tokens=$null
         $errors=$null
         [System.Management.Automation.Language.Parser]::ParseInput($userCommand, [ref]$tokens, [ref]$errors) | Out-Null
      
         foreach($token in $tokens){
            $index= (0..($tokens.Count-1)) | where {$tokens[$_] -eq $token}
            $token | Add-Member-NotePropertyName Index -NotePropertyValue $index
         }
      
         $commands = $tokens | where tokenflags -eq"commandname"
      
         foreach($command in $commands){
            $defaultParameterSet=$null
            $mandatoryParameterInDefaultSet=$null
      
            try{
               $gcm=Get-Command$command-ErrorAction Stop
               if ($gcm.CommandType-eq"Alias"){
                  $gcm=$gcm.ResolvedCommand
               }
               $defaultParameterSet=$gcm.DefaultParameterSet
               $mandatoryParameterInDefaultSet=$gcm.ParameterSets|where name -EQ$defaultParameterSet|Select-Object-ExpandProperty parameters |where ismandatory -EQ$true
             }catch{
                #todo
             }finally{
                if($mandatoryParameterInDefaultSet){
                   $command|Add-Member-NotePropertyName HasMandatoryParameter -NotePropertyValue $true
                   if(($tokens[$command.index+1]).TokenFlags -ne"None"){
                      $command|Add-Member-NotePropertyName IsMissingMandatoryParameter -NotePropertyValue $true
                   }else{
                      $command|Add-Member-NotePropertyName IsMissingMandatoryParameter -NotePropertyValue $false
                   }
                }else{
                   $command|Add-Member-NotePropertyName HasMandatoryParameter -NotePropertyValue $false
                   $command|Add-Member-NotePropertyName IsMissingMandatoryParameter -NotePropertyValue $false
                }
            }
         }
      
         #todo: Consider impactlevel for stuff like remove-item
      
         if($commands.IsMissingMandatoryParameter-contains$true){
            return $false
         }else{
            return $true
         }
      }

      And here is my usecase: realtime result preview for pipes (still buggy):

      View post on imgur.com

      Here you can see how where-object used to break everything:

      View post on imgur.com

       

  • #119341

    Participant
    Points: 1,628
    Helping Hand
    Rank: Community Hero

    Real time preview, crazy idea. Above shared code alone wont do it. If possible can you share the complete code via gist here ?

    And you hero here is DefaultParameterValues…

    #Below expression sets the default value of -Property parameter of Where-Object to '-'
    $PSDefaultParameterValues = @{'Where-Object:Property'='-'}
    
    #See more at 
    Get-Help about_Parameters_Default_Values
    
  • #119344

    Participant
    Points: 1,139
    Helping Hand
    Rank: Community Hero

    OK, interesting, so, ditto on what kvprasoon stated.

    Not something I would have dreamed up as I spend zero time in the consolehost. I am always in the ISE or VSCode. I shell to it when needed from ISE / VSCode.

    The only time I am in the console host is when I use the Azure Cloud Shell, and that is all PSCore of course.

    Yet, still, interesting concept / use case. Meaning you are trying to reproduce natively in the consolehost, what you can already do in the ISE / VSCode, making the consolehost act like a light editor and display output window.

    Try it, open the ISE/VSCode and do the same thing you are doing here. Except, you'd hit F8 to run the line vs Enter. I do this sort of thing before converting to a script every day. Which is why I've never needed console host on the regular. It's an OOBE feature of the ISE / VSCode.

  • #120463

    Participant
    Points: 38
    Rank: Member

    I have been busy but I will work on it this weekend and publish it on github.

  • #120466
    js

    Participant
    Points: 743
    Helping Hand
    Rank: Major Contributor

    What if you type "remove-item -recurse *"?

    • #120481

      Participant
      Points: 38
      Rank: Member

      Then you are screwed. 🙂

      That's one thing I have to work on before i put it on github.

      It's really unfortunate, that cmdlets like remove-item has the the same ConfirmImpact value (= medium) as for example Get-Date, as it would have been a good way to catch dangerous inputs. If anyone has an idea how I could catch this in my preparse function...

       

  • #120495

    Participant
    Points: 457
    Helping Hand
    Rank: Contributor

    Best way is simply *not* to attempt to take in arbitrary user input in the first place and find a better solution for whatever actual problem you're trying to solve here.

    Or, take it, convert it to a proper script block, and invoke that in a sessionstate where specific commands or parameters are forbidden to be used.

The topic ‘Suppress prompts for mandatory parameters’ is closed to new replies.

denizli escort samsun escort muğla escort ataşehir escort kuşadası escort