%$#@ Special Characters! Part 1
Published May 20 2019 02:24 PM 151 Views
Occasional Visitor
First published on TECHNET on Jul 14, 2010

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


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                  :

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 –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 .

Version history
Last update:
‎May 20 2019 02:24 PM
Updated by: