How to hide a parameter from Get-Help (not just tab completion) in PowerShell?

Viewed 203

I've searched around, and I can't find a straight answer of 'no', but also no straight answer of yes either.

What I already know:

  • [Parameter(DontShow)] only affects tab completion
  • One suggestion was to use a Common Parameter and test for it's existence in $PSBoundParameters - while technically viable, this has the side-effect of not having the name that I want for it.
  • Another suggestion was to hide it within another param as an Alias, but that suits deprecation more.

The scenario I have is having a parameter that shouldn't be used by any 3rd Party, but is used by companion scripts

example:

[CmdletBinding(SupportsShouldProcess)]param(
  [switch]$VisibleSwitch,
  [switch]$HiddenSwitch ### This switch should not be visible to human-beings.
)
#...
if( $HiddenSwitch) {
  #do something
  return
}
#...
2 Answers

I fear that there is no good solution as of PowerShell 7.2, but the closest approximation of what you want is probably the following:

  • Define a proxy parameter whose name signals that it isn't to be used directly.

  • Declare this parameter with both the DontShow and ValueFromRemainingArguments [Parameter()]properties.

  • Manually check the argument(s) bound to the proxy parameter to look for the "hidden" parameter.

[CmdletBinding(SupportsShouldProcess)]
param(
  [switch] $Switch
  ,
  [Parameter(DontShow, ValueFromRemainingArguments)]
  ${(ignore)}
)

# Examine the quasi-hidden parameter value 
# for containing the switch name of interest.
$HiddenSwitch = ${(ignore)}.Count -eq 1 -and ${(ignore)}[0] -eq '-HiddenSwitch'

# Make sure that no unexpected arguments were passed.
if (-not $HiddenSwitch -and ${(ignore)}.Count -gt 0) { throw "Unexpected arguments specified: ${(ignore)}"}

# Output what switches were passed.
[pscustomobject] @{
  '-Switch' = $Switch
  '-HiddenSwitch' = $HiddenSwitch
}

Note:

  • This won't prevent the proxy parameter from showing up in the syntax diagram (e.g. with -?) - it'll show as [-(ignore) <Object>] - but it won't reveal the true parameter name.

    • GitHub issue #7868 asks for an official way to hide parameters from syntax diagrams, in the context of no longer showing obsolete (deprecated) parameters.
  • Strictly speaking, you'd also have to check ${(ignore)} for the (rarely used) syntax that allows explicitly passing a Boolean to the switch (e.g., -HiddenSwitch:$true), but I've omitted that for brevity in the code above.

  • Similarly, more work would be required to support passing an unambiguous prefix of the hidden parameter name (e.g., -Hidden).


If not having an extra parameter show up in the syntax diagram is paramount, an - also suboptimal - alternative is to use a "private" variable with an obscure name, say $__HiddenSwitch, that the caller must set in order to emulate a -HiddenSwitch parameter, and which the callee (your script/function) removes after checking it.

Note that if the callee is defined in a module, extra effort is required to access the caller's scope.

Here's another possible approach where the extra param will just be ignored if the function is called from the command line.

Function Test-Parm {

  Param (
    [Parameter(Mandatory=$True)]
      [Int] $Value,
    [Parameter(Mandatory=$False)]
      [String] $FromCode

  )

  $Calledby = $($MyInvocation).ScriptName
  

  If ($CalledBy.Length -eq 0) {
    "Called from Command Line"
  }
  Else { "Called from Code" }
  
}

Results:

PSv7>..\Test\Test-HideParam.ps1
Called from Code
PSv7>Test-Parm -Value 3 -FromCode "NO"
Called from Command Line
PSv7>

HTH

Related