Using filters against objects containing special characters with Invoke-Command

Continuing the series “blog this so you don’t forget about it later”, here’s another interesting example on how PowerShell handles special characters. In a previous blog post, we discussed how to use server-side filters against objects containing a special character in the DistinguishedName attribute, more specifically an apostrophe (‘). The example used there will work just fine when you are running the cmdlets directly in console, however if you try the Implicit remoting method, it will fail. It took me a while, but now I finally have a working solution for this scenario as well.

Let’s describe the issue in more detail first. The task is simple enough, use server-side filtering to return a list of groups a specific user is a member of. Which in turn means, get the DN attribute of the user, put it in the –Filter statement and use the Members clause. Like this:

Get-Recipient -Filter {Members -eq 'CN=user,OU=tenant.onmicrosoft.com,OU=Microsoft Exchange Hosted Organizations,DC=EURPR03A001,DC=prod,DC=outlook,DC=com'}

All very straightforward, with the exception of the special care you need to pay to characters such as apostrophes (which is totally legit character to have in a DN). However, using a server-side filtering is even more efficient if you combine it with the Invoke-Command method of executing the query directly against the remote shell, as it allows you to minimize the amount of data returned. This might not sound like a big deal, but in a large organization you can have thousands upon thousands of users, each member of dozens of groups. As the Get-Recipient cmdlet will return the full ReducedRecipient object with over 100 properties, this can easily result in huge overhead. So, combining server-side filtering and Invoke-Command can make your scripts run a lot faster, and way more reliable.

For the purposes of the task at hand, all I needed was an unique identifier for each group the user is a member of, such as the PrimarySMTPAddress – everything else can be dropped. So, how does on adapt this to work against Invoke-Command? After banging my head for a while trying all sorts of variations, it turned out that the solution is very simple. So simple indeed that I can just adapt the example from the previous post with minor changes. Here’s how:

$dn = (Get-Mailbox user).DistinguishedName
$dnnew = "'" + "$($dn.Replace("'","''"))" + "'"
$cmd = 'Invoke-Command -Session $session -ScriptBlock { Get-Recipient -Filter "Members -eq $using:dnnew" | Select-Object PrimarySmtpAddress } -HideComputerName'
$list = Invoke-Expression $cmd

The culprit – use two apostrophes instead of four. Sheesh!

The example also takes advantage of the Using scope modifier, which we’ve talked about previously. In case you need more information about it, read here.

 

This entry was posted in Exchange Online, Office 365, PowerShell. Bookmark the permalink.

Leave a Reply

Your email address will not be published. Required fields are marked *