Monday, December 30, 2013

Process ActiveSync Enabled Mailboxes

As an email service provider for a large number of different companies, we need to be able to adapt to their needs. One of those needs was to have larger control over which of their employees can use an ActiveSync device. This meant that we had to lock down a large number of the mailboxes that do not get access. My solution was this script. To run this script you'll need: Exchange Management Tools and Quest ARS Powershell cmdlets.

What this script does: 
  1. Find all ActiveSync enabled mailboxes. I use an AD Directory Searcher method, so reading the values on 100,000 mailboxes only takes a few minutes, not hours.
  2. Reads an "Exchange ActiveSync Opt-in" group, containing groups and/or mailboxes. 
  3. Disables all mailboxes not in the Opt-In group. Enable all mailboxes in Opt-In group.
  4. Look at nested groups in Exchange ActiveSync Opt-in, compare names to ActiveSync Mailbox Policies in Organization, if matches, apply policy to all mailboxes in group. 

I run this script via a scheduled task hourly. The parent Exchange ActiveSync Opt-In is a security group and is not visible in the GAL. A few of my customers have opted to create distribution groups and modify them via OWA or Outlook. A few of them manage groups in their AD, and I sync the membership across to the appropriate linked mailboxes on my side. 

<#
.SYNOPSIS
   Enable/Disable mailboxes for ActiveSync
.DESCRIPTION
   Script will find any mailbox that has ActiveSync enabled, and compare membership to a specific group. 
    If in group, enable mailbox.
    If NOT in group, disable.
   When complete, compare groups with activesync policies. If names match, apply policy to group members.  
#>

function Get-ActiveSyncEnabledMailboxes {
 $strFilter = "(&(objectClass=User)(mail=*)(objectCategory=Person)(mailNickname=*)(!cn=SystemMailbox{*)(|(!msExchOmaAdminWirelessEnable=*)(&(msExchOmaAdminWirelessEnable=*)(!msExchOmaAdminWirelessEnable:1.2.840.113556.1.4.803:=4))))"
 $objDomain = New-Object System.DirectoryServices.DirectoryEntry
 $objSearcher = New-Object System.DirectoryServices.DirectorySearcher
 $objSearcher.SearchRoot = $objDomain
 $objSearcher.PageSize = 1000
 $objSearcher.Filter = $strFilter
 $objSearcher.SearchScope = "Subtree"
 $objSearcher.PropertiesToLoad.Add("distinguishedname") | out-Null
 $colResults = $objSearcher.FindAll()
 $mbxes = $colresults | select @{Name="DN";Expression={$_.properties.distinguishedname}}
 return $mbxes
 <# 
 .SYNOPSIS
  Return the DN for all objects that have ActiveSync enabled.

 .EXAMPLE
  Get-ActiveSyncEnabledMailboxes

 .NOTES

 .LINK
  http://social.technet.microsoft.com/forums/en-us/exchangesvradmin/thread/855A485F-A327-49C1-8184-9A9D6D1FE9DB
#>
}

#Enable Powershell addins for Exchange 2010 and Quest ARS tools. 
$Posh2010 = (get-pssnapin Microsoft.Exchange.Management.PowerShell.E2010 -ErrorAction SilentlyCOntinue) -ne $null
if (-not $posh2010) {
 get-pssnapin Microsoft.Exchange.Management.PowerShell.E2010 | Add-PSSnapin -PassThru 
}
$Quest = (get-pssnapin Quest.ActiveRoles.ADManagement -ErrorAction SilentlyCOntinue) -ne $null
if (-not $Quest) {
 if ((get-pssnapin Quest.ActiveRoles.ADManagement -ErrorAction SilentlyCOntinue -Registered) -ne $null) {
  get-pssnapin Quest.ActiveRoles.ADManagement | Add-PSSnapin -PassThru 
 } else {
  Write-Host "Error:Need Quest ARS Powershell cmdlets to get nested group membership" -ForegroundColor RED
  Break
 } 
}

$enabledUsers = Get-ActiveSyncEnabledMailboxes | sort DN | ?{$_.dn -notlike "*test*" -and $_.dn -notlike "*service accounts*" -and $_.dn -notlike "*global admins*" -and $_.dn -notlike "*federatedemail*" -and $_.dn -notlike "*CAS_*"}
$OptIn = Get-QADGroupMember -Indirect "Exchange ActiveSync Opt-In" -SizeLimit 0 -Type user | select DN | sort dn | ?{$_.dn -notlike "*test*" -and $_.dn -notlike "*service accounts*" -and $_.dn -notlike "*global admins*" -and $_.dn -notlike "*federatedemail*" -and $_.dn -notlike "*CAS_*"}
$MissMatch = compare -ReferenceObject $enabledusers -DifferenceObject $optin -Property DN #-IncludeEqual
$index =0
$max = $missmatch.count
Get-Date | Out-File -FilePath ".\ASReport.txt"
foreach ($Overload in $MissMatch) {
 $index++
 if ($max -gt 0) {
  $statusStr = "in progress "+$index + " of "+$max
  write-progress -activity "Processing ActiveSync Opt-In List" -status $statusStr -percentcomplete (($index / $max)*100)
 }
 $mbxDN = $overload.DN 
 $mailtype = (Get-Recipient $mbxdn).recipienttype
 $ChangedAlias = $false
 if ($mailtype -ne "MailUser"){
  $casMBX = Get-CASMailbox $mbxdn
  $badMbx = Get-Mailbox $mbxdn 

  #Cleanup invalid SMTP email addresses if possible. 
  $m = $badMbx.primarysmtpaddress.isvalidaddress
  if (-not $m) { 
   $psmtp = $badmbx.primarysmtpaddress.tostring()
   $newSMTP = $psmtp.replace(".@","@").replace("..",".").replace(" ","_")
   if ($psmtp -ne $newSMTP) { 
    Set-Mailbox -identity $badmbx.identity -PrimarySmtpAddress $newSMTP 
    $badMbx = Get-Mailbox $mbxdn
    $m = $badMbx.primarysmtpaddress.isvalidaddress
   } 
  }

  if ($m ) {
   #Mailboxes enabled for activesync, but not in optin
   if ($overload.SideIndicator -eq "<=") {
    Write-Host "- disable user",$mbxDN
    "disabled: "+$mbxdn | Out-File -FilePath ".\ASReport.txt" -Append
    Set-CASMailbox -identity $mbxDN -ActiveSyncEnabled $false -erroraction silentlycontinue -wa Continue
   } 

   #Mailboxes in Optin, not enabled for ActiveSync
   if ($overload.SideIndicator -eq "=>") {
    Write-Host "+ enable user",$mbxDN
    "enabled: "+$mbxdn | Out-File -FilePath ".\ASReport.txt" -Append
    Set-CASMailbox -identity $mbxDN -ActiveSyncEnabled $true -erroraction silentlycontinue -wa Continue
   } 

   #Allowed ActiveSync Enabled mailboxes. Use to set policy? 
   if ($overload.SideIndicator -eq "==" ) {
    Write-Host "Already Enabled user",$mbxDN    
   } 
  }
 }
}
if ($max -gt 0) {
 write-progress -activity "Processing ActiveSync Opt-In List" -status "complete" -completed
}
Get-Date | Out-File -FilePath ".\ASReport.txt" -Append
#Read GROUPS nested inside the Opt-In group! 
#Looks for ActiveSync policies with identical names to sub Opt-in groups and applies policy to mailboxes in each group.
$ASEnabledgroups = Get-QADGroupMember -Type group -Identity "Exchange ActiveSync Opt-in"
foreach ($G in $ASEnabledgroups) {
 $AP = Get-ActiveSyncMailboxPolicy $g.name -ErrorAction SilentlyContinue 
 if ($ap -ne $null) {
  Write-Host "found $ap"
  $groupMembers = get-qadgroupmember -identity $g.dn -type user -indirect -sizelimit 0 -LdapFilter '(mail=*)' | ?{(get-casmailbox -identity $_.dn).ACtiveSyncMailboxPolicy -ne $AP.Name}
  if ($groupMembers -ne $null) {
   $groupMembers | %{set-casmailbox -identity $_.dn -ActiveSyncMailboxPolicy $ap.name}
  }
 }
}

No comments:

Post a Comment