Show a Help message (Syntax) instead of an error when no parameters specified

Welcome Forums General PowerShell Q&A Show a Help message (Syntax) instead of an error when no parameters specified

Viewing 3 reply threads
  • Author
    Posts
    • #233062
      Participant
      Topics: 2
      Replies: 3
      Points: 34
      Rank: Member

      I wrote a script to retrieve VM metrics from VMware vCenter.

      A user needs to provide 2 arguments/parameters. One is the vCenter server and the other is 1 of the following : Single VM name or a file containing a list of VMs.

      The script works fine, but if someone tries to run this script at the PS console without providing any arguments, it throws an exception. (shown below)

      Questions :

      1. Is the exception pointing to an issue I don’t know ?
      2. I would rather, the user be shown the Syntax instead of an exception. Is that possible ?
      [CmdletBinding()]
      
      Param (
      
          [Parameter( Mandatory = $true, ParameterSetName = 'List' )]
          [Parameter( Mandatory = $true, ParameterSetName = 'OneVM' )]
          [string]$vCenterServer,
      
          [Parameter( Mandatory = $true, ParameterSetName = 'List' )]
          [ValidateNotNullOrEmpty()]
          [ValidateScript( { Test-Path -LiteralPath $_ -Type Leaf })]
          [string]$vmListFile,
      
          [Parameter( Mandatory = $true, ParameterSetName = 'OneVM' )]
          [string]$MyVM
      )
      

      When I run this without providing arguments/parameters, here is what I see.

      PS> c:\Temp\vCenter_RT_PerfData.ps1
      C:\Temp\vCenter_RT_PerfData.ps1 : Parameter set cannot be resolved using the specified named parameters.
          + CategoryInfo          : InvalidArgument: (:) [vCenter_RT_PerfData.ps1], ParentContainsErrorRecordException
          + FullyQualifiedErrorId : AmbiguousParameterSet,vCenter_RT_PerfData.ps1
      

      Here is what I wish they would see.

      SYNTAX
          C:\Temp\vCenter_RT_PerfData.ps1 -vCenterServer <String> -MyVM <String> [<CommonParameters>]
      
          C:\Temp\vCenter_RT_PerfData.ps1 -vCenterServer <String> -vmListFile <String> [<CommonParameters>]

      Any suggestions on presenting this another/better way are also welcome.

    • #233083
      Participant
      Topics: 3
      Replies: 431
      Points: 1,533
      Helping Hand
      Rank: Community Hero

      You could use the help message parameter attribute in combination with mandatory to guide the user on what to input.

      https://docs.microsoft.com/en-us/powershell/module/microsoft.powershell.core/about/about_functions_advanced_parameters?view=powershell-7
      Otherwise you should drop mandatory and in your function check if there are no arguments and display the syntax help to them

    • #233095
      Participant
      Topics: 12
      Replies: 1651
      Points: 2,702
      Helping Hand
      Rank: Community Hero

      Multiple parametersets are defined, you need to set a default parameterset to tell it the default parameters to ask for:

      function Test-It {
          [CmdletBinding(DefaultParameterSetName = 'OneVM')]
          param (
              [Parameter( Mandatory = $true, ParameterSetName = 'List' )]
              [Parameter( Mandatory = $true, ParameterSetName = 'OneVM' )]
              [string]$vCenterServer,
      
              [Parameter( 
                  Mandatory = $true, 
                  ParameterSetName = 'List',
                  HelpMessage="Enter path to vmlist file."
               )]
              [ValidateNotNullOrEmpty()]
              [ValidateScript( { Test-Path -LiteralPath $_ -Type Leaf })]
              [string]$vmListFile,
      
              [Parameter( 
                  Mandatory = $true, 
                  ParameterSetName = 'OneVM',
                  HelpMessage="Enter the VM name"
              )]
              [string]$MyVM
          )
          begin{}
          process{}
          end{}
      }
      
      Test-It
      

      However, the parameters are not normally how you would handle providing a file to a function. Use other cmdlets as examples for parameter names as something like ‘MyVM’ could be an Alias, but Name or VMName would be a better descriptive name:

      function Test-It {
          [CmdletBinding()]
          param (
              [Parameter( 
                  Mandatory = $true,
                  HelpMessage="Enter the VCenter Server name"
              )]
              [string]$vCenterServer,
      
              [Parameter( 
                  Mandatory = $true, 
                  HelpMessage="Enter the VM name"
              )]
              [string[]]$VMName
          )
          begin{}
          process{
              foreach ( $vm in $vmname ) {
                  Write-Verbose -Message ('Processing {0} on vcenter server {1}' -f $vm,$vCenterServer)
              }
          }
          end{}
      }
      
      Test-It -vCenterServer Server -VMName vm1,vm2 -Verbose
      
      #or
      
      $vms = Get-Content -Path C:\Script\vmlist.txt
      Test-It -vCenterServer Server -VMName $vms -Verbose
      
    • #236191
      Participant
      Topics: 2
      Replies: 3
      Points: 34
      Rank: Member

      Thank you Rob!

      DefaultParameterSet did the trick.

Viewing 3 reply threads
  • You must be logged in to reply to this topic.