title: How to create a powershell script which can be reflected to show allowed parameter values
body: <p>I need to reliably read the allowed values for a Cmdlet or PowerShell Script. For example, the allowed values for the <code>Method</code> parameter of <code>Invoke-RestMethod</code> are <code>"Get", "Head", "Post",</code>... etc.</p>
  
  <p>I thus annotate my scripts with <code>ValidateSet</code>:</p>
  
  <pre class="lang-bsh prettyprint-override"><code>param(
      [Parameter()]
      [ValidateSet("GET", "POST")]
      [string]$Method="GET"
  )
  </code></pre>
  
  <p>The problem is that I am able to use Get-Help to query these values for Cmdlets like <code>Invoke-RestMethod</code> but not for my own scripts.</p>
  
  <p>Here is the output of <code>$cmd = Get-Help -Full Invoke-RestMethod</code> looking at <code>$cmd.syntax.syntaxItem[0].parameter[1].parameterValueGroup.parameterValue</code></p>
  
  <p><a href="https://i.stack.imgur.com/2qxVy.png" rel="nofollow noreferrer"><img src="https://i.stack.imgur.com/2qxVy.png" alt="enter image description here"></a></p>
  
  <pre><code>{
      "name":  "Method",
      "required":  "false",
      "pipelineInput":  "false",
      "isDynamic":  "false",
      "parameterSetName":  "(All)",
      "parameterValue":  {
                             "value":  "WebRequestMethod",
                             "variableLength":  false,
                             "required":  "true"
                         },
      "type":  {
                   "name":  "WebRequestMethod"
               },
      "position":  "Named",
      "aliases":  "None",
      "parameterValueGroup":  {
                                  "parameterValue":  [
                                                         "Default",
                                                         "Get",
                                                         "Head",
                                                         "Post",
                                                         "Put",
                                                         "Delete",
                                                         "Trace",
                                                         "Options",
                                                         "Merge",
                                                         "Patch"
                                                     ]
                              }
  }
  
  </code></pre>
  
  <p>The following script allows <code>"GET"</code> and <code>"POST"</code> as the <code>Method</code> parameter but Get-Help does not reflect this.</p>
  
  <pre class="lang-bsh prettyprint-override"><code>&lt;#
   .Synopsis
   Foo
  
   .Parameter Method
   Something about method
  #&gt;
  [CmdletBinding()]
  param(
      [Parameter()]
      [ValidateSet("GET", "POST")]
      [string]$Method="GET"
  )
  </code></pre>
  
  <p>Now, if I try to retrieve the "GET" and "POST" allowed values:</p>
  
  <pre class="lang-bsh prettyprint-override"><code>Set-StrictMode -Off
  
  # 1. Self-reflect
  $me = Get-Help .\tmp.ps1 -Full
  $me | convertto-json -depth 10  &gt; tmpOP1.json
  $methodParamMe = $me.Syntax.syntaxItem[0].parameter | Where-Object Name -eq "Method"
  if ($methodParamMe.parameterValueGroup.parameterValue -eq $null) {
      "My ValidateSet is missing!"
  } else {
      $methodParam.parameterValueGroup.parameterValue
  }
  
  # 2. Look at Invoke-Webreq  
  $cmd = Get-Help Invoke-RestMethod -Full
  $cmd | convertto-json -depth 10 &gt; tmpOP2.json
  $methodParamIWR = $cmd.Syntax.syntaxItem[0].parameter | Where-Object Name -eq "Method"
  $methodParamIWR | convertto-json -depth 10 &gt; tmpOP3.json
  if ($methodParamIWR.parameterValueGroup.parameterValue -eq $null) {
      "Invoke-RestMethod has no ValidateSet"
  } else {
      "Invoke-RestMethod has the set of allowed values!"
      $methodParamIWR.parameterValueGroup.parameterValue | ConvertTo-Json
  }
  </code></pre>
  
  <p><strong>Output:</strong></p>
  
  <pre><code>My ValidateSet is missing!
  Invoke-RestMethod has the set of allowed values!
  [
      "Default",
      "Get",
      "Head",
      "Post",
      "Put",
      "Delete",
      "Trace",
      "Options",
      "Merge",
      "Patch"
  ]
  </code></pre>
  
  <p>Is there any way I can annotate my scripts so that I can query the allowed parameters?</p>