%$#@ 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: tel:+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                  : tel:+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 tel:+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 (1)
  1. bingfeng says:

    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.

Comments are closed.

Skip to main content