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.