Advanced Function Optional Parameter Problem

Welcome Forums General PowerShell Q&A Advanced Function Optional Parameter Problem

This topic contains 4 replies, has 4 voices, and was last updated by

 
Participant
4 years, 8 months ago.

  • Author
    Posts
  • #16331

    Participant
    Points: 0
    Rank: Member

    Hello,

    I've written an advanced function that creates one or more VMs. I have a mandatory parameter and many optional, with some default values.
    The problem is with the optional parameters that have no default values.
    For example, there is a SwitchName parameter that is optional and has no default value, because I don't always want a new VM to connect to a switch.
    However, if I don't supply any value to it, I get this error, even if I use [AllowEmptyString()] and [AllowNull()] in the PARAM block:

    New-VM : Cannot validate argument on parameter 'SwitchName'. The argument is null or empty. Provide an argument that is not null or empty, and then try the command again.

    I want the VMs to connect to a switch only if I supply the name of a switch, otherwise I don't want them to connect anywhere. How can I do this?
    These are the relevant snippets from my code (sorry for the formatting, it gets messed up whatever I do):

    #Some of the parameters:
    
    [CmdletBinding()]
    param(
          [Parameter(Mandatory,
                ValueFromPipeline,
                ValueFromPipelineByPropertyName)]
          [string[]]
          $VMName,
    
          [Parameter(ValueFromPipeline,
                ValueFromPipelineByPropertyName)]
          [AllowEmptyString()]
          [AllowNull()]
          [string]
          $SwitchName,
    
    #And so on
    )
    
    PROCESS
    {
            foreach ($name in $VMName)
            {
                    $params = @{Name                          = $name
                                             MemoryStartupBytes = $MemoryStartupBytes
                                             Generation                  = 2
                                             NewVHDPath             = "$VHDFolder\$name\$name.vhdx"
                                             NewVHDSizeBytes    = $VHDSizeBytes
                                             BootDevice                  = $BootDevice
                                             ComputerName         = $ComputerName
                                             Path                              = $VMFolder
                                             SwitchName               = $SwitchName}
                    New-VM @params
    
                    $params = @{VMName                              = $name
                                              DynamicMemoryEnabled = $true
                                              MinimumBytes                    = $MemoryMinimumBytes
                                              ComputerName                 = $ComputerName}
                    Set-VMMemory @params
             }
    }
    
  • #16332

    Keymaster
    Points: 1,811
    Helping HandTeam Member
    Rank: Community Hero

    You need to put some logic in your script to not provide the SwitchName parameter is $SwitchName is null.

    if ($SwitchName) { $params.Add('SwitchName',$SwitchName) }
    

    Something along those lines.

    The [AllowNull()] means YOUR FUNCTION will accept a null value from $SwitchName. That doesn't mean New-VM will do so.

  • #16333

    Member
    Points: 0
    Rank: Member

    How do you call the function?

  • #16334

    Member
    Points: 0
    Rank: Member

    The problem is probably when you pass a null / empty value to the New-VM cmdlet, based on what I can see so far. You'd need to construct your $params hashtable so that only the defined parameters are in it when you call New-VM. Something like this:

    $params = @{
        Name               = $name
        MemoryStartupBytes = $MemoryStartupBytes
        Generation         = 2
        NewVHDPath         = "$VHDFolder\$name\$name.vhdx"
        NewVHDSizeBytes    = $VHDSizeBytes
        BootDevice         = $BootDevice
        ComputerName       = $ComputerName
        Path               = $VMFolder
    }
     
    if ($SwitchName) { $params['SwitchName'] = $SwitchName }
     
    New-VM @params
    

    Also, you'll want to get away from using ValueFromPipeline in combination with String parameters. Any object can be represented as a string, which will give you some crazy results when you start trying to pipe objects to this function. Based on what I see so far, ValueFromPipelineByPropertyName should be all you need.

  • #16337

    Participant
    Points: 0
    Rank: Member

    Thank you a lot, it works! I haven't encountered this amazing technique yet.
    Thank you for the advice on pipeline imput too!

The topic ‘Advanced Function Optional Parameter Problem’ is closed to new replies.

denizli escort samsun escort muğla escort ataşehir escort kuşadası escort