# Advanced Function Optional Parameter Problem

**URL:** https://forums.powershell.org/t/advanced-function-optional-parameter-problem/2719
**Category:** PowerShell Help
**Created:** [June 18, 2014, 2:28am UTC](https://forums.powershell.org/t/advanced-function-optional-parameter-problem/2719 "2014-06-18T02:28:10Z")
**Posts on this page:** 6
**Page:** 1

<div class="post-metadata">

### Author: ![szarka-istvan](https://avatars.discourse-cdn.com/v4/letter/s/49beb7/32.png) [@szarka-istvan](https://forums.powershell.org/u/szarka-istvan)
#### Post date: [June 18, 2014, 2:28am UTC](https://forums.powershell.org/t/advanced-function-optional-parameter-problem/2719/1 "2014-06-18T02:28:10Z")

</div>

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
         }
}
```

---

<div class="post-metadata">

### Author: ![donj](https://sea1.discourse-cdn.com/flex019/user_avatar/forums.powershell.org/donj/32/137_2.png) [@donj](https://forums.powershell.org/u/donj)
#### Post date: [June 18, 2014, 2:32am UTC](https://forums.powershell.org/t/advanced-function-optional-parameter-problem/2719/2 "2014-06-18T02:32:16Z")

</div>

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.

---

<div class="post-metadata">

### Author: ![bjornhouben](https://sea1.discourse-cdn.com/flex019/user_avatar/forums.powershell.org/bjornhouben/32/867_2.png) [@bjornhouben](https://forums.powershell.org/u/bjornhouben)
#### Post date: [June 18, 2014, 2:33am UTC](https://forums.powershell.org/t/advanced-function-optional-parameter-problem/2719/3 "2014-06-18T02:33:05Z")

</div>

How do you call the function?

---

<div class="post-metadata">

### Author: ![system](https://us1.discourse-cdn.com/flex019/uploads/powershell/original/1X/385e4f9fe133561ad30a814262fe0e0ae6bc3ef0.png) [@system](https://forums.powershell.org/u/system)
#### Post date: [June 18, 2014, 2:34am UTC](https://forums.powershell.org/t/advanced-function-optional-parameter-problem/2719/4 "2014-06-18T02:34:18Z")

</div>

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.

---

<div class="post-metadata">

### Author: ![szarka-istvan](https://avatars.discourse-cdn.com/v4/letter/s/49beb7/32.png) [@szarka-istvan](https://forums.powershell.org/u/szarka-istvan)
#### Post date: [June 18, 2014, 2:45am UTC](https://forums.powershell.org/t/advanced-function-optional-parameter-problem/2719/5 "2014-06-18T02:45:17Z")

</div>

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

---

<div class="post-metadata">

### Author: ![dotnVo](https://avatars.discourse-cdn.com/v4/letter/d/4af34b/32.png) [@dotnVo](https://forums.powershell.org/u/dotnVo)
#### Post date: [May 16, 2024, 8:47pm UTC](https://forums.powershell.org/t/advanced-function-optional-parameter-problem/2719/6 "2024-05-16T20:47:55Z")

</div>


