Dynamic Parameter IP Messing Things Up

Welcome Forums General PowerShell Q&A Dynamic Parameter IP Messing Things Up

Viewing 5 reply threads
  • Author
    Posts
    • #193352
      Participant
      Topics: 4
      Replies: 11
      Points: 92
      Rank: Member

      Dynamic parameter disappears, but only if typed second.

      I’m writing a function with a DynamicParam code block defining a parameter attribute, but there is very definitely strange behavior going on.  In the following function I have three separate parameter attribute definitions for the $Subnet mask parameter.  The first one is what I want in the end.  The second one is a short list just to see if the length of the list changed things (spoiler alert; it didn’t).  The third one was a test to see if the data within it changed things (spoiler alert; it DID).

      All right. The bottom line is that this function works with the any of these parameter attribute definitions so long as you type the Application parameter first when using the function. If you type the SubnetMask parameter first, then the dynamic parameter called Application is no longer available.  But here’s where it gets interesting. Change the list of values from IPs to anything else (I used fruit) and it stays visible and the function works great.

      Is there something I need to change to make sure my Application parameter doesn’t disappear?

      $TheseApps = @('this','that','other')
      function Get-This {
      [CmdletBinding()]
      param(
      
      [ValidateSet('255.0.0.0','255.128.0.0','255.192.0.0','255.224.0.0','255.252.0.0','255.254.0.0','255.255.0.0','255.255.128.0','255.255.192.0','255.255.224.0','255.255.240.0','255.255.248.0','255.255.252.0','255.255.254.0','255.255.255.0','255.255.255.128','255.255.255.192','255.255.255.224','255.255.255.240','255.255.255.248','255.255.255.252','255.255.255.254','255.255.255.255')]
      #[ValidateSet('255.0.0.0','255.128.0.0')]
      #[ValidateSet('banana','cherry','apple','kiwi','peach')]
      [string]
      $SubnetMask
      
      )
      DynamicParam 
      {
      # Parameter Attribute
      $AppAttribute = New-Object System.Management.Automation.ParameterAttribute -Property @{
      Mandatory = $true
      Position = 0
      HelpMessage = 'Select from the list of applications'
      ValueFromPipeline = $false
      ValueFromPipelineByPropertyName = $false
      DontShow = $false
      }
      
      # Values Collection
      $attributeCollection = New-Object -Type System.Collections.ObjectModel.Collection[System.Attribute]
      $attributeCollection.Add( $AppAttribute )
      $ValidateSet = New-Object System.Management.Automation.ValidateSetAttribute( $TheseApps )
      $attributeCollection.Add( $ValidateSet )
      
      # Runtime Defined Parameter
      $dynParam1 = New-Object -Type System.Management.Automation.RuntimeDefinedParameter( "Application", [string], $attributeCollection )
      
      # Runtime Defined Parameter Dictionary
      $paramDictionary = New-Object -Type System.Management.Automation.RuntimeDefinedParameterDictionary
      $paramDictionary.Add( "Application", $dynParam1 )
      
      return $paramDictionary
      }
      Begin{}
      Process
      {
      foreach( $Key in $PSBoundParameters.Keys )
      {
      Write-Host "$Key is $( $PSBoundParameters.Item($Key) )"
      }
      }
      End{}
      }
    • #193379
      Participant
      Topics: 4
      Replies: 11
      Points: 92
      Rank: Member

      Replying to my own post here.  I figured out a way to get it to work, but only by creating both parameters listed as dynamic parameters. I’d still love to know why IPs put in as strings into an array mess up the whole ValidateSet() piece of all this.

       

      Cheers to all who stumble upon this.

    • #194138
      Participant
      Topics: 4
      Replies: 11
      Points: 92
      Rank: Member

      I still haven’t found the answer, but I have found out that using anything that starts out like an IP seems to cause the second parameter to disappear.  It appears to need only the first two octets to throw off the second parameter.

      So in the example code below, starting the function call with anything like these make the Application parameter disappear:
      <p style=”padding-left: 40px;”>Get-This -SubnetMask ‘10.20.10.10’</p>
      <p style=”padding-left: 40px;”>Get-This -SubnetMask ‘255.255.p’</p>
      These examples; however, let you still use the Application parameter:
      <p style=”padding-left: 40px;”>Get-This -SubnetMask ‘p.192.250.250’</p>
      <p style=”padding-left: 40px;”>Get-This -SubnetMask ‘p’</p>
      <p style=”padding-left: 40px;”>Get-This -SubnetMask ‘192.p’</p>
      I gave the following list for the validated set.  The first two cause the missing parameter, but the rest don’t.

      ‘10.20.10.10’

      ‘255.255.p’

      ‘p.192.250.250’

      ‘p’

      ‘192.p’

       

      The full code follows if you want to try it out.  Anyone who knows why, please let me know.  I’ll start looking through classes and interfaces next.

      $TheseApps = @('this','that','other')
      function Get-This {
        [CmdletBinding()]
        param(
          [ValidateSet('10.20.10.10','255.255.p','p.192.250.250','p','192.p')]
          [string]
          $SubnetMask
        )
        DynamicParam 
        {
          # Parameter Attribute
          $AppAttribute = New-Object System.Management.Automation.ParameterAttribute -Property @{
            Mandatory = $true
            Position = 0
            HelpMessage = 'Select from the list of applications'
            ValueFromPipeline = $false
            ValueFromPipelineByPropertyName = $false
            DontShow = $false
          }
      
          # Values Collection
          $attributeCollection = New-Object -Type System.Collections.ObjectModel.Collection[System.Attribute]
          $attributeCollection.Add( $AppAttribute )
          $ValidateSet = New-Object System.Management.Automation.ValidateSetAttribute( $TheseApps )
          $attributeCollection.Add( $ValidateSet )
      
          # Runtime Defined Parameter
          $dynParam1 = New-Object -Type System.Management.Automation.RuntimeDefinedParameter( "Application", [string], $attributeCollection )
      
          # Runtime Defined Parameter Dictionary
          $paramDictionary = New-Object -Type System.Management.Automation.RuntimeDefinedParameterDictionary
          $paramDictionary.Add( "Application", $dynParam1 )
      
          return $paramDictionary
        }
        Begin{}
        Process
        {
          foreach( $Key in $PSBoundParameters.Keys )
          {
            Write-Host "$Key is $( $PSBoundParameters.Item($Key) )"
          }
        }
        End{}
      }
    • #194192
      Participant
      Topics: 4
      Replies: 11
      Points: 92
      Rank: Member

      A friend just pointed out that the IPs get strings added around them, but the other values do not. So after letting intellisense (tab-complete), if you remove the quotes from the IP, then it evaluates correctly and the second parameter shows up.

    • #194261
      Participant
      Topics: 13
      Replies: 1683
      Points: 2,849
      Helping Hand
      Rank: Community Hero

      Is there a reason you are using string vs specify the type as an IPAddress

      PS C:\WINDOWS\system32> [System.Net.IPAddress]"1.1.1."
      Cannot convert value "1.1.1." to type "System.Net.IPAddress". Error: "An invalid IP address was specified."
      At line:1 char:1
      + [System.Net.IPAddress]"1.1.1."
      + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
          + CategoryInfo          : InvalidArgument: (:) [], RuntimeException
          + FullyQualifiedErrorId : InvalidCastParseTargetInvocation
      
       param(
          [ValidateSet('10.20.10.10','255.255.p','p.192.250.250','p','192.p')]
          [IPAddress]
          $SubnetMask
        )
      

      What does ‘p’ represent?

    • #194288
      Participant
      Topics: 4
      Replies: 11
      Points: 92
      Rank: Member

      Thanks for the response Rob.

      I’ve tried both and string was the only way to demonstrate how some values work and others don’t.  The second parameter goes missing for all values when using System.Net.IPAddress.  I definitely agree that IPAddress would be the ideal type to provide, though, and would like to go back to if it would only work the way I want it to.

      Also, nearly everything about the function I’m using at the office is different from this example. I made up this example in hopes of finding the root cause and to demonstrate the strange behavior.

Viewing 5 reply threads
  • The topic ‘Dynamic Parameter IP Messing Things Up’ is closed to new replies.