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
1 month, 1 week 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: 866
    Helping Hand
    Rank: Major Contributor

    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: 318
    Helping Hand
    Rank: Contributor

    How about

    get-process | where $a
    

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

  • #118905

    Participant
    Points: 866
    Helping Hand
    Rank: Major Contributor

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

  • #119256

    Participant
    Points: 319
    Helping Hand
    Rank: Contributor

    '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: 866
      Helping Hand
      Rank: Major Contributor

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

  • #119312
    js

    Participant
    Points: 318
    Helping Hand
    Rank: 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: 319
    Helping Hand
    Rank: Contributor

    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: 866
    Helping Hand
    Rank: Major Contributor

    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: 319
    Helping Hand
    Rank: Contributor

    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: 318
    Helping Hand
    Rank: 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: 290
    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.

You must be logged in to reply to this topic.