Someone on the /r/msp reddit, and a Slack that I frequent asked if it is possible to create an “all users” distribution group with PowerShell, and keep it up to date. I figured to spend some time on it.
To achieve a list that is always up to date, we can use Dynamic Distribution groups. Dynamic groups allow you to add specific users based on their properties. for example; if a user has a full mailbox, it will be added. You can make these queries as complex as you want.
Our script uses the Secure Application Model to create a couple of new dynamic distribution groups; a single one that contains all users called “AllCompanyUsers” and one per domain that the client has. The domain group only contains people that use that domain’s email address. For example; Cybedrain.com@cyberdrain.com contains John, Hank, and Bob. It does not contain Janet because she uses @Janetdrain.com as an e-mail.
The script
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
|
$ApplicationId = 'APPLICATIONID'
$ApplicationSecret = 'APPLICATIONSECRET' | Convertto-SecureString -AsPlainText -Force
$TenantID = 'YOUURTENANTID'
$RefreshToken = 'Freakishly long refreshtoken'
$ExchangeRefreshToken = 'Freakishly long refresh'
$UPN = "UPN-Of-User-Generating-Tokens"
$credential = New-Object System.Management.Automation.PSCredential($ApplicationId, $ApplicationSecret)
$aadGraphToken = New-PartnerAccessToken -ApplicationId $ApplicationId -Credential $credential -RefreshToken $refreshToken -Scopes 'https://graph.windows.net/.default' -ServicePrincipal -Tenant $tenantID
$graphToken = New-PartnerAccessToken -ApplicationId $ApplicationId -Credential $credential -RefreshToken $refreshToken -Scopes 'https://graph.microsoft.com/.default' -ServicePrincipal -Tenant $tenantID
Connect-MsolService -AdGraphAccessToken $aadGraphToken.AccessToken -MsGraphAccessToken $graphToken.AccessToken
$customers = Get-MsolPartnerContract -All
foreach ($customer in $customers) {
$token = New-PartnerAccessToken -ApplicationId 'a0c73c16-a7e3-4564-9a95-2bdf47383716'-RefreshToken $ExchangeRefreshToken -Scopes 'https://outlook.office365.com/.default' -Tenant $customer.TenantId
$tokenValue = ConvertTo-SecureString "Bearer $($token.AccessToken)" -AsPlainText -Force
$credential = New-Object System.Management.Automation.PSCredential($upn, $tokenValue)
$customerId = $customer.DefaultDomainName
$session = New-PSSession -ConfigurationName Microsoft.Exchange -ConnectionUri "https://ps.outlook.com/powershell-liveid?DelegatedOrg=$($customerId)&BasicAuthToOAuthConversion=true" -Credential $credential -Authentication Basic -AllowRedirection
Import-PSSession $session -AllowClobber -DisableNameChecking -CommandName "Get-DynamicDistributionGroup","New-DynamicDistributionGroup","Set-DynamicDistributionGroup"
write-host "Logged into tenant $($customer.defaultdomainname)" -ForegroundColor Green
write-host "Checking if all users list exist, if not, creating them." -ForegroundColor Green
$ExisitingAllUserList = Get-DynamicDistributionGroup -anr "AllCompanyUsers"
if (!$ExisitingAllUserList) {
write-host "Creating AllCompanyUsers group" -ForegroundColor Green
New-DynamicDistributionGroup -Name "AllCompanyUsers" -RecipientFilter "(RecipientType -eq 'UserMailbox')" | out-null
Get-DynamicDistributionGroup -anr "AllCompanyUsers" | Set-DynamicDistributionGroup -RequireSenderAuthenticationEnabled $False -HiddenFromAddressListsEnabled $true | out-null
}
write-host "Checking all domains, and creating a list for each domain." -ForegroundColor Green
$Domains = Get-MsolDomain -TenantId $customer.TenantId
foreach ($Domain in $domains.name) {
write-host "Checking domain $($Domain) creating if it does not exist." -ForegroundColor Green
$ExisitingDomainList = Get-DynamicDistributionGroup -anr $Domain
if (!$ExisitingDomainList) {
write-host " Creating $domain list" -ForegroundColor Green
New-DynamicDistributionGroup -Name "$domain" -RecipientFilter "(RecipientType -eq 'UserMailbox') -and (EmailAddresses -like '$Domain')" | out-null
Get-DynamicDistributionGroup -anr "$Domain" | Set-DynamicDistributionGroup -RequireSenderAuthenticationEnabled $False -HiddenFromAddressListsEnabled $true | out-null
}
}
Remove-PSSession $session
}
|
So, that’s it! as always, Happy PowerShelling!