Convert security groups to mail-enabled and universal for Office 365 with PowerShell

by Thomas Verwer, Technical Consultant @ Rapid Circle When carrying out projects for Enterprise clients I commonly face challenges with companies not meeting the system requirements for Office 365. One of the most commonly seen missing requirements are on the Identity and Access Management part of Office 365.

When migrating legacy Identity and Acces Management infrastructures to Office 365 you quickly bump in to Microsoft’s Active Directory Services (ADS). To migrate this service to Windows Azure Active Directory – which is part of every Office 365 license – you can use the Windows Azure Active Directory Sync tool. Or as most IT Professionals know it “DirSync”, this is a special edition in the history of FIM.

Now back to businness. To migrate legacy security groups to Windows Azure Active Directory, for products such as Exchange Online it is a requirement to have a GroupScope of Universal.(see image below)

Get-ADGroup-GroupScope
Get-ADGroup-GroupScope

Since most companies still use Global security groups these need to be converted. Therefore I use a PowerShell script which automates this proces. For this script to work, import the ActiveDirectory module in PowerShell or run the script with Active Directory Module for Windows PowerShell.

Clear-Host

if((Get-Module | where {$_.Name -eq “ActiveDirectory”}) -eq $null){Import-Module ActiveDirectory}$scriptPath = split-path -parent $MyInvocation.MyCommand.DefinitionSet-Location $scriptPathWrite-Output “Output will be stored in ” (Get-Location)

$SeaBase = “DC=corp,DC=local”$SeaVal = “CN=Mailbox_*”$SeaScope = “Subtree”$GrpList = “ADSecGrp.csv”$UniGrpList = “Uni_ADSecGrp.csv”$strLogFile = “ErrorLog.txt”$DomainAdmin = Get-Credential

#Search for all Groups that are of type Security and scope is Global and starts with “Mailbox_”$SecGrps = Get-ADGroup -SearchScope $SeaScope -SearchBase $SeaBase -Filter {GroupCategory -eq “Security” -and GroupScope -eq “Global”}

foreach ($secGrp in $SecGrps) {try {$DN = $secGrp | Where-Object {$_.DistinguishedName -like $SeaVal}$DN | Export-Csv $GrpList -Append } catch {throwBreak}}

(Get-Content $GrpList | Select-Object -Skip 1) | Set-Content $GrpList

Write-Output “Check $GrpList to verify all exported security Groups are of type Global”Write-Output “Press Y to continue”$selection = read-hostif ($selection -eq “y” -or $selection -eq “Y”){Write-Output “$GrpList CSV File Checked….”foreach($G in Import-Csv $GrpList){try {$D = $G.DistinguishedNameGet-ADGroup -Identity $G.SID Set-ADGroup -Identity $G.SID -GroupScope Universal -Credential $DomainAdmin} catch {$ErrorMessage = $_.Exception.MessageWrite-Output “Error converting for $D ..`n Error Message : $ErrorMessage” | Add-Content $strLogFileThrowBreak}$DN = Get-ADGroup -Identity $G.SID$DN | Export-Csv $UniGrpList -Append}(Get-Content $UniGrpList | Select-Object -Skip 1) | Set-Content $UniGrpListWrite-Output “Check $UniGrpList to verify all modified security Groups are of type Universal”}else{Write-Output “Script Stopped by User” | Add-Content $strLogFileBreak}

As you can see the script contains several variables. With these you can define the scope of OU’s or name convention for existing security groups. When running the PowerShell script it builds up a CSV-file called Uni_ADSecGrp.csv. When paused you can open and check the file to see if it contains the groups which you wish to convert. If so, you can insert “Y” to the script and it proceeds running.

After we have succesfully changed the GroupScopes to Universal we can carry on and use the second PowerShell script which mail-enables the security groups so they meet the requirements for Exchange Online. Besides the conversion to mail-enabled it also hides the groups from the Global Address List.

Run this script on one of the legacy Exchange servers with the use of the  Exchange Management Shell.

Clear-Host

#if((Get-Module | where {$_.Name -eq “ActiveDirectory”}) -eq $null){# Import-Module ActiveDirectory#}

#Add-PSSnapin Microsoft.Exchange.Management.PowerShell.E2010# $env:ExchangeInstallPathbinRemoteExchange.ps1#Connect-ExchangeServer -auto

Write-Output “Output will be stored in ” (Get-Location)

$GrpList = “Final_ADSecGrp.csv”$strLogFile = “enableErrorLog.txt”$log = “AfterLog.txt”$ErrorLog = “ErrorLog.txt”

foreach($G in Import-Csv “Uni_ADSecGrp.csv”){

try {Get-ADGroup -Identity $G.SID

Enable-DistributionGroup -Identity $G.DistinguishedName -Alias $G.NameSet-DistributionGroup -Identity $G.DistinguishedName -HiddenFromAddressListsEnabled $trueGet-DistributionGroup -Identity $G.DistinguishedName | Add-Content $Log$x = Get-DistributionGroup -Identity $G.DistinguishedNameif($x -ne $Null){Write-Output $G.DistinguishedName}else{Write-Output $G.DistinguishedName | Add-Content $ErrorLog}} catch {$ErrorMessage = $_.Exception.MessageWrite-Output “Error Enabl-DistributionGroup for $G.DistinguishedName …..`nError Message : $ErrorMessage” | Add-Content $strLogFilethrowBreak}

}

Once you have succesfully executed the second script you can add these objects to your Windows Azure Directory Sync cycle. Please be aware that when you convert the groups, the groups may not contain unsupported characters such as namespaces or & characters.

Best of luck to you all with carrying out succesfull Office 365 deployments. Before I publish the post, I have to share my respect to my colleague and teammate Dev Chaudhari for working on the scripting!

Original blog on: thomasverwer.com