Hi,

Trying to create a dynamic distribution list based on titles but getting an error when I try to create the group.

As you can see “Get” works OK, but when I try the “New” it fails with *

PS /home/azureuser> $Filter = "(RecipientType -eq 'UserMailbox') -and (Title -like '*contract*')"
PS /home/azureuser> Get-Recipient -RecipientPreviewFilter $Filter | Select-Object title

Title
-----
IT Project Manager (Contract)
Business Analyst (Contract)
Program Manager (Contract)
Project Manager (Contract)
Communications & Design Specialist (Contract)
Business Analyst (Contract)
Project Manager (Contract)
Project Management (Contract)
Business Analyst (Contract)
Enterprise Architect (Contract)
Financial Services Consultant (Contract)
Business Analyst (Contract)
Project Manager (Contract)
Business Analyst (Contract)
Project Manager (Contract)
IT Consultant (Contract)

PS /home/azureuser> New-DynamicDistributionGroup -Name "All contractors-Worldwide" -RecipientFilter {(RecipientType -eq 'UserMailbox') -and (Title -like '*contract*')}
1000: Wildcards cannot be used as the first character. Please revise the filter criteria.
6 Spice ups

It says in the documentation:

In cloud-based environments, you can’t use a wildcard as the first character. For example, ‘Sales*’ is allowed, but ‘*Sales’ isn’t allowed


Title -like '*contract*'
# should be 
Title -like 'contract*'

2 Spice ups

@alexw ​ Not sure if there is a workaround for this?

have you tried

Title -like '(*contract*'

as they all seem to be the same format?

I assume that’s for Exchange Online?

PS /home/azureuser> $Filter = "(RecipientType -eq 'UserMailbox') -and (Title -like '(*contract*')"
PS /home/azureuser> Get-Recipient -RecipientPreviewFilter $Filter | Select-Object title
PS /home/azureuser> $Filter = "(RecipientType -eq 'UserMailbox') -and (Title -like '(*contract*)')"
PS /home/azureuser> Get-Recipient -RecipientPreviewFilter $Filter | Select-Object title
PS /home/azureuser>

Trying Title -like ‘(contract’ or Title -like ‘(contract’) shows no results.

It is for Exchange Online.

what about

New-DynamicDistributionGroup  -Name "All contractors-Worldwide" -RecipientFilter "(RecipientType -eq 'UserMailbox') -and (Title -like '*contract*')" 

@jitensh same results:​

PS /home/azureuser> $Filter = "(RecipientType -eq 'UserMailbox') -and (Title -like '(*contract*)')"
PS /home/azureuser> Get-Recipient -RecipientPreviewFilter $Filter | Select-Object title
PS /home/azureuser> New-DynamicDistributionGroup  -Name "All contractors-Worldwide" -RecipientFilter "(RecipientType -eq 'UserMailbox') -and (Title -like '*contract*')"
1000: Wildcards cannot be used as the first character. Please revise the filter criteria.
PS /home/azureuser>

hmm

In cloud-based environments, you can’t use a wildcard as the first character. For example, Sales* is allowed, but *Sales isn’t allowed.

And I find feedback about this, you could vote it.
https://office365.uservoice.com/forums/273493-office-365-admin/suggestions/12875082-for-the-dynamic-distribution-list-allow-a-wild-car

Have you tried something like

$regex = "\(Contract\)"

$Filter = "(RecipientType -eq 'UserMailbox') -and (Title -match $regex)"

@dastafford

PS /home/azureuser> $regex = "\(Contract\)"
PS /home/azureuser> $Filter = "(RecipientType -eq 'UserMailbox') -and (Title -match $regex)"
PS /home/azureuser> Get-Recipient -RecipientPreviewFilter $Filter | Select-Object title
Get-Recipient: The recipient preview filter string "(RecipientType -eq 'UserMailbox') -and (Title -match \(Contract\))" is neither a valid OPathfilter nor a valid LDAP filter. Use the -RecipientPreviewFilter parameter with either a valid OPath filter string or a valid LDAP filter string.
PS /home/azureuser>

Oh!

-match not accepted in OPathfilter. That’s a problem.

So, if you can’t start with a wild card but you can end with a wild card, then perhaps if we reverse the string and look for the reverse of your data.

I know this is really ugly but …

 Get-Recipient -RecipientType UserMailbox | 
 Foreach-object { $TitleArray = $_.Title.ToCharArray(); Write-Output $_;  } | 
 Foreach-object { [array]::reverse($TitleArray); Write-Output $_;  } |
 Foreach-object { [String]$TitleStr = -join $TitleArray ; Write-Output $_;  } |
 
 select-object @{n='Reverse';e={$TitleStr}}, Name |
  where-object Reverse -like "tcartnoC*"
2 Spice ups

Instead of:

New-DynamicDistributionGroup  -Name "All contractors-Worldwide" -RecipientFilter "(RecipientType -eq 'UserMailbox') -and (Title -like '*contract*')"

What happens if you change the ‘-like’ to ‘-contains’?

New-DynamicDistributionGroup  -Name "All contractors-Worldwide" -RecipientFilter "(RecipientType -eq 'UserMailbox') -and (Title -Contains 'contract')"

@jimlong3

PS /home/azureuser> $Filter = "(RecipientType -eq 'UserMailbox') -and (Title -like '*contract*')"
PS /home/azureuser> Get-Recipient -RecipientPreviewFilter $Filter | Select-Object title

Title
-----
IT Project Manager (Contract)
Business Analyst (Contract)
Program Manager (Contract)
Project Manager (Contract)
Communications & Design Specialist (Contract)
NS5 Team - Bangalore (Contract)
Deloitte Contractor
Business Analyst (Contract)
Project Manager (Contract)
Project Management (Contract)
Business Analyst (Contract)
MACS Contractor
Enterprise Architect (Contract)
Financial Services Consultant (Contract)
Business Analyst (Contract)
Project Manager (Contract)
Business Analyst (Contract)
Project Manager (Contract)
IT Consultant (Contract)

PS /home/azureuser> New-DynamicDistributionGroup  -Name "Test_All contractors-Worldwide" -RecipientFilter "(RecipientType -eq 'UserMailbox') -and (Title -Contains 'contract')"
Exception: /tmp/tmp_5vw4ueej.cfz/tmp_5vw4ueej.cfz.psm1:42675
 Line |
42675 |          $steppablePipeline.End()
      |          ~~~~~~~~~~~~~~~~~~~~~~~~
      | Cannot bind parameter 'RecipientFilter' to the target. Exception setting "RecipientFilter": ""-Contains" is not a valid operator. For a list of supported operators see the command help. "(RecipientType -eq
      | 'UserMailbox') -and (Title -Contains 'contract')" at position 47."

Curses! Foiled again!

Because Microsoft.

If you’re just looking to deep-dive into PowerShell weirdness, you’re on the right track. Pack a lunch, this quest will take a long time.

If you have a job to do you may have to just suck up the Microsoft and hand-code your entire Filter:

$Filter = "((Title -eq 'IT Project Manager (Contract)') -or (Title -eq 'Business Analyst (Contract)') -or (Title -eq 'Program Manager (Contract)') -or (Title -eq 'Project Manager (Contract)') -and (ExchangeUserAccountControl -ne 'AccountDisabled'))"

Then you’d add your group by:

New-DynamicDistributionGroup -Name "All contractors-Worldwide" -RecipientFilter $Filter

The titles are dynamic so adding them manually isn’t a good option and that is why we wanted to use * instead.

1 Spice up

So, you wrap your command which gets all the group names into the script by applying it to a variable:

$Filter = "(RecipientType -eq 'UserMailbox') -and (Title -like '*contract*')"

[Array]$grpNames = (Get-Recipient -RecipientPreviewFilter $Filter | Select-Object -exp title)

 

At this point, $grpNames should be the list of groups you want.

1 Spice up

I think you might have to bite the bullet and use a custom attribute or other field to identify your contractors.

Gathering the names at runtime means you don’t have to edit your script. Beautiful!

Now how to make the list into a suitable OPath filter?

1 Spice up

@garygreenberg

The same question as @jimlong3 ​ asked:

“Now how to make the list into a suitable OPath filter?”

1 Spice up

I don’t believe you can, which is why I posted

“I think you might have to bite the bullet and use a custom attribute or other field to identify your contractors.”

The whole point with Dynamic Distribution Groups is that they are rules-based rather than data-based.

If you run a script to pick up all recipients with “(Contract)” in their title (which you can do with Get-Recipient) and pipe that through to update a custom attribute or maybe the Department field or Office field, then your DDG can use that field as a filter field.

You’d have to remember to update that field for any new contractors you created or, alternatively, run the script as a scheduled task periodically (once per night?)

1 Spice up