%$#@ Special Characters! Part 1
By Edwin Young, Microsoft
PowerShell has quite a sophisticated syntax, with lots of special characters and variables. For the most part, this is very useful. But there are a few “gotchas” that can leave you scratching your head. Here are some common examples people on our team have run into. Hopefully, sharing them with you will help you avoid getting too sore a head.
PS> Set-CsDialInConferencingDtmfConfiguration -CommandChar #
That ought to set things up so dial-in users press the # (pound, or hash) key on the phone to enter a command. Right? But what it actually does is return this message:
Set-CsDialInConferencingDtmfConfiguration : Missing an argument for parameter 'CommandCharacter'. Specify a parameter of type 'System.String' and try again.
Why did we get this error? Because ‘#’ is PowerShell’s comment character, so PowerShell ignores it and everything that comes after it. Instead you need to do:
[PS]> Set-CsDialInConferencingDtmfConfiguration -CommandChar `#
which escapes the # character; or
[PS]> Set-CsDialInConferencingDtmfConfiguration -CommandChar '#'
which makes it clear the character is a string.
[PS]> New-CsVoiceNormalizationRule mydialplan/myrule -Pattern "(\d{4})" -Translation "+1425555$1"
Well, that ought to create a normalization rule that matches 4-digit numbers, and puts the string “+1425555” at the front. After all, $1 means “whatever was matched inside the first set of parentheses in the pattern”.
But the new rule actually looks like this:
Identity : mydialplan/myrule
Priority : 1
Description :
Pattern : (\d{4})
Translation : +1425555
Name : myrule
IsInternalExtension : False
What happened to $1? PowerShell silently interpolated it away – and in this case, you don’t even get an error.
Interpolation is a neat feature borrowed from Perl which lets you create formatted strings very easily. For example:
[PS]> $foo = "world"
[PS]> "hello $foo"
hello world
But here, we want to keep the $ signs uninterpreted, whic means we need to use single-quotes instead of double quotes:
[PS]> New-CsVoiceNormalizationRule mydialplan/myrule -Pattern "(\d{4})" -Translation '+1425555$1'
(In general, whenever something doesn’t do quite what you expect, try putting single quotes around it!)
By the way, there’s actually another bug in this normalization rule, which we can demonstrate with the Test-CsDialPlan helper cmdlet:
[PS]> $p = Get-CsDialPlan mydialplan
[PS]> Test-CsDialPlan -Dialplan $p -DialedNumber 666666
TranslatedNumber MatchingRule
---------------- ------------
+ 1425555666666 Description=;Pattern=(\d{4});Translation=+1425555$1;Name...
The test was successful. How come our rule still matched? Because the pattern matches if four digits occur anywhere in the input number, not just if the entire input consists of exactly 4 digits. So we need to anchor the pattern to match the whole string by including ‘^’ (start of string) and ‘$’ (end of string) in the pattern, like so:
[PS]> New-CsVoiceNormalizationRule mydialplan/myrule -Pattern " ^ (\d{4}) $ " -Translation '+1425555$1'
Finally, a real stumper:
[PS] > New-CsAnalogDevice
cmdlet New-CsAnalogDevice at command pipeline position 1
Supply values for the following parameters:
LineUri: +14255551213
RegistrarPool: pool0.contoso.com
AnalogFax: $false
Gateway: 192.168.0.240
OU: OU=AnalogDevices,DC=Contoso,DC=com
If you don’t enter the mandatory parameters for a cmdlet, PowerShell will prompt you for them. Here, we’re trying to set up an analog device connected to a gateway for use with Microsoft Lync Server 2010. But when we retrieve the new device, we get:
Gateway : 192.168.0.240
AnalogFax : True
…
LineURI : +14255551213
…
RegistrarPool : pool0.contoso.com
(I’ve left out most of the properties to save space.)
But we didn’t want a fax machine. How come it’s a fax? And, to make it weirder, suppose we enter the exact same information on the command-line without being prompted:
[PS] > New-CsAnalogDevice –LineURI +14257270002 –RegistrarPool pool0.vdomain.com –AnalogFax $false –Gateway 192.168.0.240 –OU "OU=AnalogDevices,DC=Contoso,DC=com"
It works! The AnalogFax property is false as expected.
If you know why, or would like to hazard a guess, please suggest your answer in the comments. The solution is posted in Part 2 .
Comments
- Anonymous
July 19, 2010
Because the prompted parameter input just accepts literal value, it doesn't interpolate. But, how to set boolean value correctly when prompted? I tried 0/1, it seems not work.