%$#@ Special Characters!, Part 2

By Edwin Young

Last time , we looked at some curious behavior when running the New-CsAnalogDevice cmdlet: when you leave out a mandatory parameter like AnalogFax, then PowerShell prompts you for it; but weirdly, even if you enter $false, the property ends up true. Why is that?

This isn’t strictly about special characters, but it’s due to a difference between how PowerShell interprets arguments passed “normally” on the command line, and arguments it prompts for. On the command line, everything is fully parsed and interpreted, but prompts are just treated as strings. It’s as if you ran

New-CsAnalogDevice –AnalogFax '$false'

Which would also end up with AnalogFax as $true, because any non-empty string, including “0”, “$false”, and “false”, evaluates as true. So if you do get prompted for a Boolean value and you want to set it to false, you can just hit Enter when prompted for that variable – this resolves to an empty string, which evaluates to $false.

This is deliberate, if rather surprising, behavior on PowerShell’s part. The thing to remember is that when you enter values in response to a prompt, they will be treated as if you surrounded them with single quotes.

Another example might make it clearer:

PS > Set-Content -Path foo.txt

cmdlet Set-Content at command pipeline position 1

Supply values for the following parameters:

Value[0]: (1+1)

Value[1]:

PS > more .\foo.txt

(1+1)

PS > Set-Content -Path foo.txt -Value (1+1)

PS > more .\foo.txt

2

Here, 1+1 is evaluated on the command-line, but not when prompted for.


Finally, here’s a problem you can hit when you use the command line, but not when you are prompted.

PS > New-CsAnalogDevice -LineUri +14257270002 -RegistrarPool pool1.contoso.com -AnalogFax $false -Gateway 192.168.0.240 -OU OU=AnalogDevices,DC=contoso,DC=com

Produces the message:

New-CsAnalogDevice : Cannot convert 'System.Object[]' to the type 'Microsoft.Rtc.Management.AD.OUIdParameter' required by parameter 'OU'. Specified method is not supported.

Why is that? Well, PowerShell uses commas to form arrays, so OU=AnalogDevices,DC=contoso,DC=com is actually treated as an array of three strings: "OU=AnalogDevices", “DC=contoso" and "DC=com". Since the cmdlet expects only a single string, PowerShell complains that the type of the input is wrong. To avoid this, just quote the string:

PS > New-CsAnalogDevice -LineUri +14257270002 -RegistrarPool pool1.contoso.com -AnalogFax $false -Gateway 192.168.0.240 -OU "OU=AnalogDevices,DC=contoso,DC=com"


Anyway, these are the most common confusions I’ve seen arise due to PowerShell’s quoting and parsing behavior. I hope it saves you some time!

I also hope I haven’t made it sound too alarming – it’s really fairly straightforward once you get used to it. Happy scripting!