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

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 Access 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 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

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.Definition
Set-Location $scriptPath
Write-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 {
throw
Break
}
}

(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-host
if ($selection -eq “y” -or $selection -eq “Y”){
Write-Output “$GrpList CSV File Checked….”
foreach($G in Import-Csv $GrpList){
try {
$D = $G.DistinguishedName
Get-ADGroup -Identity $G.SID
Set-ADGroup -Identity $G.SID -GroupScope Universal -Credential $DomainAdmin
} catch {
$ErrorMessage = $_.Exception.Message
Write-Output “Error converting for $D ..`n Error Message : $ErrorMessage” | Add-Content $strLogFile
Throw
Break
}
$DN = Get-ADGroup -Identity $G.SID
$DN | Export-Csv $UniGrpList -Append
}
(Get-Content $UniGrpList | Select-Object -Skip 1) | Set-Content $UniGrpList
Write-Output “Check $UniGrpList to verify all modified security Groups are of type Universal”
}else{
Write-Output “Script Stopped by User” | Add-Content $strLogFile
Break
}

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:ExchangeInstallPath\bin\RemoteExchange.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.Name
Set-DistributionGroup -Identity $G.DistinguishedName -HiddenFromAddressListsEnabled $true
Get-DistributionGroup -Identity $G.DistinguishedName | Add-Content $Log
$x = Get-DistributionGroup -Identity $G.DistinguishedName
if($x -ne $Null){
Write-Output $G.DistinguishedName
}else{
Write-Output $G.DistinguishedName | Add-Content $ErrorLog
}
} catch {
$ErrorMessage = $_.Exception.Message
Write-Output “Error Enabl-DistributionGroup for $G.DistinguishedName …..`nError Message : $ErrorMessage” | Add-Content $strLogFile
throw
Break
}

}

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 thank to my colleague and teammate Dev Chaudhari for working on the scripting!

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s