Monday, August 17, 2020

PowerShell: Cmdlet Parameter Sets

PowerShell cmdlet parameter sets are documented at Cmdlet parameter sets where they are defined as follows:

Each parameter set must contain a unique  parameter that allows the PowerShell runtime to identify which parameter set is being used. In order to demonstrate parameter sets consider the Get-Depth function from the post PowerShell: Converting Json-Formatted Strings to/from Json-Objects and Json-Object Depth. The Get-Depth function has been modified as follows, GetDepthEx, to take two parameters where each parameter belongs to a separate parameter set (see the attribute property, ParameterSetName, below):

function Get-DepthEx()
{
  param (
    [Parameter(
      Mandatory=$true,
      ParameterSetName='FormattedJsonString')]
      [string] $json,
    [Parameter(
      Mandatory=$true,
      ParameterSetName='JsonObject')]
      [PSCustomObject] $jsonObject
  )

The code for GetDepthEx is the original GetDepth code save it has been modified (see text demarcated by boldface) to work with a Json-formatted string parameter (parameter set name, FormattedJsonString) or with  Json-Object (parameter set name, JsonObject):

function Get-DepthEx()
{
    param (
        [Parameter(
            Mandatory=$true,
            ParameterSetName='FormattedJsonString')]
        [string] $json,
        [Parameter(
            Mandatory=$true,
            ParameterSetName='JsonObject')]
        [PSCustomObject] $jsonObject
    )

    if (($null -ne $json) -and ($json.Length -gt 0))
    {
        # This step verifies that $json is a valid Json object
        $jsonObject = ConvertFrom-Json $json   
        if ($null -eq $jsonObject)
        {
            return 0
        }
    }

    if ($null -ne $jsonObject)
    {
        # As of PowerShell 7.0 the max -Depth is 100
        $json = ConvertTo-Json $jsonObject -Depth 100
    }
   

    [int] $maximumDepth = -1
    [int] $depth = 0
    [char[]] $startingBrackets = '[', '{'
    [char[]] $endingBrackets = @(']', '}')

    foreach ($c in $json.ToCharArray())
    {
        if ($c -in $startingBrackets)
        {
            ++$depth
            $maximumDepth = if ($maximumDepth -ge $depth)
                { $maximumDepth } else { $depth }
        }

        elseif ($c -in $endingBrackets)
        {
            --$depth
        }
    }

    return $maximumDepth
}

The GetDepthEx method is invoked as follows where each invocation uses a different parameter set as is show using the code from the previous post "PowerShell: Reading, Modifying, and Saving Json Files":

[string] $sourceWindowsVmTemplateFilename =
             'Template2019.json'
[string] $destinationWindowsVmTemplateFilename =
             'TemplateAnyWindowsVM.json'
[string] $content =
             Get-Content -Raw -Path $sourceWindowsVmTemplateFilename
[PSCustomObject] $jsonObject =
    $content |
    ConvertFrom-Json

[int] $depthParameterSetFormattedJsonString =
        Get-DepthEx -Json $content
[int] $depthParameterSetJsonObject =
        Get-DepthEx -JsonObject $jsonObject

There are many permutations to parameter sets. For example it possible for a parameter to be included in multiple parameter sets. As a feature of PowerShell, parameter sets are not part of the day-to-day coding performed by most developers.  It is more likely that a developer will have to read the documentation associated with a cmdlet that supports multiple parameter sets. Cmdlets that contain multiple parameters sets include;

  • Add-AzVMNetworkInterface
  • Get-AzGallery
  • Get-AzHost
  • Get-AzHostGroup
  • New-AzVM
  • New-AzVMConfig
  • New-AzVMSqlServerAutoBackupConfig
  • Publish-AzVMDscConfiguration
  • Remove-AzGallery
  • Remove-AzHost
  • Remove-AzHostGroup

No comments :

Post a Comment