Applying custom attributes to filtered groups

Be gentle, first time poster and i’m a PS newbie.

I need to bulk apply a custom attribute to a bunch of M365 Groups that have a certian UPN.

This is what i have:

Set-UnifiedGroup | Where-Object {$_.PrimarySMTPAddress -like “*”} -CustomAttribute1 “Company Name”

But i’m getting the following error:
Where-Object : A parameter cannot be found that matches parameter name ‘CustomAttribute1’.

I can apply the attribute, manually, one at a time using:

Set-UnifiedGroup “Name of a M365 Group” -CustomAttribute1 “Company Name”

Any help would be appreciated.

Welcome to the forum and community. We’ll attempt to be gentle. Do not have anywhere to test, but generally that is not how a filter is applied how the pipeline is leveraged. Normally, a GET is performed to filter the results and that is passed or pipelined into a SET (or Remove). Looking at the documentation for Get-UnifiedGroup:

Get-UnifiedGroup (ExchangePowerShell) | Microsoft Learn

First, the goal is ensure the filter is working as expected:

Get-UnifiedGroup -Filter {PrimarySMTPAddress  -like ""}

That is being filtered BEFORE results are returned, this is called filtering left, essentially filtered at the source. Some commands have limitations that do not allow like or only certain properties can be filtered (e.g. ResourceProvisioningOptions like in example 3 of the doc). If filtering cannot occur there, then you return ALL results and then filter in Powershell, like this:

Get-UnifiedGroup |  Where-Object {$_.PrimarySMTPAddress -like '*'}

Once you know you have only the objects returned that you want to change, then you can use the pipeline that is sending that data to Set-UnifiedGroup. Make sure you are ONLY sending objects you want to change to the Set command. If you did a Get-UnifiedGroup | Set-UnifiedGroup, that would set ALL objects, which isn’t the goal in this case.

Get-UnifiedGroup -Filter {PrimarySMTPAddress  -like ""} | 
     Set-UnifiedGroup -CustomAttribute1 “Company Name”

Set commands usually want an Identifier (Id). All that you are doing is passing the ID from the returned GET to the SET command. Take a look at these if you want to understand a bit more of how this works in Powershell:

about Pipelines - PowerShell | Microsoft Learn
PowerShell Pipeline Concept Explained With Awesome Examples – Improve Scripting

Since you are new to PS let me save some trouble and hopefully allow you to focus on writing your script vs figuring out something that isn’t very clear in the documentation.

First, let’s look at filtering with get-aduser.

I can search for users with a specific email domain. Works great.
Note the wildcard is on the left of the search string.

PS C:\PSS> get-aduser -Filter {mail -like "*"} -Properties mail | select name,mail

name                                                          mail
----                                                               ----
Yogi Bear                                           

Ok, so we seem to know how to use the -filter option right? Well not so fast, if you try and apply what you just learned to get-mailbox, it fails.

PS C:\> Get-Mailbox -Filter {PrimarySmtpAddress -like "*"}
PS C:\>

On the other hand, if I say give me all the email address that start with Yogi, I do get a return.

PS C:\> Get-Mailbox -Filter {PrimarySmtpAddress -like "yogi*"}

Name                      Alias                ServerName       ProhibitSendQuota
----                      -----                ----------       -----------------
Yogi Bear                 yogi.bear            exchange01       Unlimited

If I say give me all the mailboxes with the last name of bear, I also get a return.

PS C:\> Get-Mailbox -Filter {Name -like "*bear"}

Name                      Alias                ServerName       ProhibitSendQuota
----                      -----                ----------       -----------------
Yogi Bear                 yogi.bear            exchange01       Unlimited

Same problem for groups

PS C:\> Get-DistributionGroup -Filter {name -like "*group"}

Name       DisplayName GroupType PrimarySmtpAddress
----       ----------- --------- ------------------
Test Group Test Group  Universal

PS C:\> Get-DistributionGroup -Filter {primarysmtpaddress -like "*"}
PS C:\> Get-DistributionGroup -Filter {primarysmtpaddress -like "test*"}

Name       DisplayName GroupType PrimarySmtpAddress
----       ----------- --------- ------------------
Test Group Test Group  Universal

Same issue happens with get-unifiedgroup

PS C:\PSS> Get-UnifiedGroup -Filter {PrimarySMTPAddress  -like "*"}
PS C:\PSS> Get-UnifiedGroup -Filter {PrimarySMTPAddress  -like "c*"}

Name                                                             DisplayName                       GroupType PrimarySmtpAddress
----                                                             -----------                       --------- ------------------
CoolCatDirectReports-Privat_a7a1d50d-2796-4887-a677-6733d75ac404 Cool Cat Direct Reports - Private Universal CoolCatDirectRepo...

We unfortunately cannot apply the wild card on the left of the search with primarysmtpaddress attribute. Only wildcards to the right of the search string. which means

“mydomain” and “*mydomain” will not work for filtering on primarysmtpaddress.

If you need the wildcard to be on the left, you will need to use this option. It does work.

Get-UnifiedGroup | Where-Object {$_.PrimarySMTPAddress -like '*'}

Thank you both for taking the time to not only provide an answer but to also give a clear explanation. Its really appreciated. That would have took me hours/days to figure out. The bits of ps i know are what i’ve picked up from over the years (Googling). I need to put some time aside to learn the basics and fill in the gaps.

As per your recommendations, i used the following which worked a treat.

Get-UnifiedGroup | Where-Object {$_.PrimarySMTPAddress -like ‘*’} |
Set-UnifiedGroup -CustomAttribute1 “My Company”

Get-DistributionGroup | Where-Object {$_.PrimarySMTPAddress -like ‘*’} |
Set-DistributionGroup -CustomAttribute1 “My Company”

Final question, if you don’t mind.

The purpose of the above was to create separation within the company. To that end, I have created two new address lists, offline address books, global address lists and address book policies. With your help above, this is all in place and working nicely, however, the two new GALs current only include user mailboxes and rooms (ie: the objects which have the ‘company attribute’).

I used the following to create the new GALss:

New-GlobalAddressList -Name “Company A GAL” -IncludedRecipients AllRecipients -ConditionalCompany “Company A”

Could i ask, how would i got about adding "-or CustomAttribute1 -eq “Compnay A” so that the new GAL include all objects which have either attribute ‘Company’ -eq CompanyA or ‘CustomAttribute1’ -eq CompanyA?

Again, thanks for your help

Have not administered Exchange for quite a while, so difficult to provide guidance. May want to post that on an Exchange forum as someone might know the correct commands or feasibility of the request. :man_shrugging:

I was poking around the docs, I think some of your answer is in the documentation for the cmdlets you are trying to use.

What have you tried other than the one cmdlet you shared?

Thanks again both for your help. Managed to put some time aside today and finally figured it out with some help from a colleage.

Set-GlobalAddressList -Identity ‘ComapnyA GAL’ -RecipientFilter “( ( (Company -eq ‘CompanyA’) -or (CustomAttribute1 -eq ‘CompanyA’) ) )” )"