Suppress prompts for mandatory parameters

<p class=“yklcuq-10 hpxQMr”>Is it possible to suppress prompts for mandatory parameters?</p>
<p class=“yklcuq-10 hpxQMr”>Example:</p>
<p class=“yklcuq-10 hpxQMr”>get-process | where</p>
<p class=“yklcuq-10 hpxQMr”>=> prompts for a property</p>
<p class=“yklcuq-10 hpxQMr”>I want this line to simply fail for error handling with try/catch</p>

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.

“that doesn’t make sense” is a bold claim :slight_smile:

How about

get-process | where $a

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

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

'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.
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.

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.

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

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?

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.'

 

Everybody chill :slight_smile: 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):

https://imgur.com/dZw5MJe

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

https://imgur.com/39ZnRpD

 

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

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.

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

What if you type “remove-item -recurse *”?

Then you are screwed. :slight_smile:

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…

 

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.