Can not connect to a mailbox after reconnecting from disconnected state.

Scenario: After you reconnect a disconnected mailbox, you may receive the following error in Outlook Web App, ​ ‘Your mailbox has been disabled.’ You may also have trouble connecting to the mailbox in powershell or EMC saying the mailbox is not available.

Solution: Run the following command in Exchange Powershell: Update-StoreMailboxState -Database “db_name” -Identity “mailbox_guid”

Note: If you want to update the mailbox state for all mailboxes on a particular database

Get-MailboxStatistics -Database “db_name” | ForEach {Update-StoreMailboxState -Database $_.Database -Identity $_.MailboxGuid -Confirm:$False}

 

A mailbox sends out to more recipients than allowed by the recipient rate limit in their throttling policy

Scenario:  A mailbox has sent to more recipients than allowed by the recipient rate limit that is set in their throttling policy.  For example, a mailbox can only send out to  100 recipients within a 24 hour period, BUT that mailbox has managed to send out to 500 recipients. How can this be?

Whats happening:  A mailbox can send to more than 100 recipients if:

  1. The 24 hours have been completed for that mailbox. The will be able to send for up to another 100 recipients.
  2. The throttling service  has been restarted on the mailbox server where the mailbox is located.
  3. If a user sends to a distribution list, as the distribution list will only be counted as one recipient EVEN though there are 400 recipients in that distribution list.   

Here is the WorkFlow of the RecipientRateLimit in the throttling Policy.

Terminology:

Token: The token is the number of recipients which has already been processed

Token Bucket Map:  This is the table where the guids of the mailboxes are kept with the current RecipientRateLimit.

The token bucket map is held in memory when the Throttling service is started on the Mailbox Server. As new mailboxes send mail, they are added to the bucket map.  When the mailbox submits mail, the throttling service checks the bucket map to obtain the token for the sender.  In order for messages to be sent by the user, this must be true:

Obtain Token + Token Bucket Map <= RecipientRateLImit

Example: If the mailbox is trying to send 10 recipients ( Obtain Token) but the user has previously sent to 96 recipients (Token Bucket Map),  sending would fail:  96 + 10 <= 100

But if the mailbox is sending to 2 recipients (and not 10), sending would succeed:   96 + 2 <= 100

Distribution groups are counted as one sender  and further into the transport process of the sent message the  distribution groups is expanded into numerous recipients.  Sending a message from a mailbox always originates from the mailbox server where the mailbox is located on.  This is the mailbox server holds the Token Bucket Map.  The expansion of the distribution group can happen on any server during the transport process, thus its not logically possible to store the true number of recipients for that sender when a distribution group is used. This is why the Distribution Group is a loophole to the Recipient Rate Limit.

Script to Recreate Exchange Databases

Scenario:  You want to recreate an Exchange Database in order to reclaim the Windows space that the database was utilizing.  You have already moved all mailboxes off of the database.

 Script: This script performs the following:

  • Checks to make sure no mailboxes reside on the database
  • Removes All Database Copies
  • Removes the Databases from the folder directories ( You may have to edit this)
  • Creates the Database and sets the quotas to unlimited
  • Creates the Database Copies
  • Resolves any errors if the database copies are not healthy.
#Set DB Variable
$DB = "DB01"

#Sets ADServerSettings to see all Arbiratrion mailboxes
Set-ADServerSettings -ViewEntireForest $true

#Check for any mailboxes on the database
$1 = (get-mailbox -database $DB).count
$1 += (get-mailbox -database $DB -arbitration).count
$1 += (Get-mailbox -database $DB -archive).count
$1 += (Get-mailbox -database $DB -publicfolder).count
If ($1 -gt 0){
"Mailboxes still exist on this database. Please remove all mailboxes and run this script again."
}
Else
{
"Starting the Database Recreation Process"
"Determining Activation Preference"

#Gathers the Copies
$AP = Get-MailboxDatabaseCopyStatus $DB  | Sort ActivationPreference | Select -expandproperty Mailboxserver
$firstServer = $AP | Select -first 1
$OthServers = Get-MailboxDatabaseCopyStatus $DB | Where ActivationPreference -ne 1 | Sort ActivationPreference | Select -ExpandProperty MailboxServer
Write-Host "The Database is hosted on these 4 copies:  $AP"

#Remove all Mailbox Database copies from each server
Write-Host "Removing Database Copies"
get-mailboxdatabasecopystatus $DB | Where status -notlike *Mount* | Remove-mailboxdatabasecopy -confirm:$false 
remove-mailboxdatabase $DB -confirm:$false 

Write-Host "Sleeping 10 minutes for all processes to become unlocked"
Sleep 600
Write-Host "Deleting Folder structure on all copies"

#Delete Folder Structure
$AP | %{Remove-Item \$_c$$DBDB -force -recurse }
$AP | %{Remove-Item \$_c$$DBLogs -force -recurse }

#Create the DB
Write-Host "Creating $db"
New-MailboxDatabase $db -EDBFilePath C:$dbDB$db.edb -LogFolderPath C:$dbLogs -Server $firstserver 

#Wait for replication
Write-Host "Sleeping 3 minutes for replication"
Sleep 180

#Mount the Database
Write-Host "Mounting $db"
Mount-Database $db

#Wait for additional replication
Write-Host "Sleeping 3 minutes for replication"
Sleep 180

#Setting the DB Quotas
Write-Host "Setting DB Quotas to unlimited"
Set-MailboxDatabase $db -ProhibitSendReceiveQuota Unlimited -ProhibitSendQuota Unlimited -IssueWarningQuota Unlimited

#Create the additional Database Copies
$OthServers | %{
Write-Host "Creating DB copy for $DB on $_"
Add-MailboxDatabaseCopy $db -MailboxServer $_ 
}
#Resumes the DB Copies if they are not currently healthy
get-mailboxdatabasecopystatus $DB | Where status -notlike "Mounted" | Resume-mailboxdatabasecopy
}

 

Checking Digital Signatures of a specific file against multiple servers

Scenario:  The other day an article was written by ARS Technica on a mail server attack that steals massive number of passwords. One of the symptoms is finding an unsigned OWAAuth.DLL and in some cases the file was located in a different directory.

Solution: Here is a quick way to check all of your Exchange servers to make sure all of your OWAAUTH.DLL files are signed and in the correct path:

#Build your Servers Variable
$Servers = Get-exchangeserver
#Build your Auth Variable
$Auth = $Servers |  %{Get-childitem -path "\$_c$program filesMicrosoftExchange Serverv15" -filter owaauth.dll -recurse | Get-authenticodeSignature}
#Export your Auth Variable to read it in Excel
$Auth | Export-csv C:tempAuth.csv

 

Some internal recipients are not receiving messages when sent to Distribution Groups

Scenario:  Users are complaining that they sporadically miss email communications when the emails were sent to a specific distribution groups.  Upon further investigation of the distribution groups, the recipients that did not receive the email were members of other distribution groups that were nested two,three, and/or four times of that distribution group that was originally sent to.

Troubleshooting:  After pulling the message tracking log against all exchange servers, we noticed that the distribution groups were not expanding by seeing a 0 recipient count:

get-transportserver | Get-messagetrackinglog -subject “Testing” -resultsize unlimited -eventID Expand | Select RecipientCount,RelatedRecipientAddress

After investigating the distribution groups that were not expanding, we found that these distribution groups were mail enabled security groups AND they were set to Global and not Universal.  Apparently these groups were changed back to Global after the mail enabled security groups were created so they could be members of other global distribution groups. Thus we were experiencing ‘Black Hole’ distribution groups.

Solution:  After the user changed all the groups from Global to Universal, mail flow returned to normal.

EWS Script to Export Calendar Items to a CSV file via PowerShell

Scenario:  You need a script to export the calendar items of a mailbox into a CSV file.

Solution: Use the script below to export the calendar items of a mailbox into a CSV file.  Please note that the date range has a 2 year/1000 appointment max.  Depending on the number of items in the calendar between your date range, you may have to adjust the date range to accommodate the 1000 item limit. Also, give yourself full access to the mailbox you are querying. I used a section of Glen’s script because he nailed the attendee’s query. Props to Glen!

#Declare Variables
$EWSDLL = "C:Program FilesMicrosoftExchange ServerV15BinMicrosoft.Exchange.WebServices.dll"
$MBX = "teststeve@domain.com"
$EWSURL = "https://Ex2013Svr1.domain.com/EWS/Exchange.asmx"
$StartDate = (Get-Date).AddDays(-60)
$EndDate = (Get-Date)  

#Binding of the calendar of the Mailbox and EWS
Import-Module -Name $EWSDLL
$mailboxname = $MBX
$service = new-object Microsoft.Exchange.WebServices.Data.ExchangeService([Microsoft.Exchange.WebServices.Data.Exchangeversion]::exchange2013)
$service.Url = new-object System.Uri($EWSURL)
$folderid= new-object Microsoft.Exchange.WebServices.Data.FolderId([Microsoft.Exchange.WebServices.Data.WellKnownFolderName]::Calendar,$MailboxName) 
$Calendar = [Microsoft.Exchange.WebServices.Data.Folder]::Bind($service,$folderid)  
$Recurring = new-object Microsoft.Exchange.WebServices.Data.ExtendedPropertyDefinition([Microsoft.Exchange.WebServices.Data.DefaultExtendedPropertySet]::Appointment, 0x8223,[Microsoft.Exchange.WebServices.Data.MapiPropertyType]::Boolean); 
$psPropset= new-object Microsoft.Exchange.WebServices.Data.PropertySet([Microsoft.Exchange.WebServices.Data.BasePropertySet]::FirstClassProperties)  
$psPropset.Add($Recurring)
$psPropset.RequestedBodyType = [Microsoft.Exchange.WebServices.Data.BodyType]::Text;

$RptCollection = @()

$AppointmentState = @{0 = "None" ; 1 = "Meeting" ; 2 = "Received" ;4 = "Canceled" ; }

#Define the calendar view  
$CalendarView = New-Object Microsoft.Exchange.WebServices.Data.CalendarView($StartDate,$EndDate,1000)    
$fiItems = $service.FindAppointments($Calendar.Id,$CalendarView)
if($fiItems.Items.Count -gt 0){
 $type = ("System.Collections.Generic.List"+'`'+"1") -as "Type"
 $type = $type.MakeGenericType("Microsoft.Exchange.WebServices.Data.Item" -as "Type")
 $ItemColl = [Activator]::CreateInstance($type)
 foreach($Item in $fiItems.Items){
  $ItemColl.Add($Item)
 } 
 [Void]$service.LoadPropertiesForItems($ItemColl,$psPropset)  
}
foreach($Item in $fiItems.Items){      
 $rptObj = "" | Select StartTime,EndTime,Duration,Type,Subject,Location,Organizer,Attendees,AppointmentState,Notes,HasAttachments,IsReminderSet
 $rptObj.StartTime = $Item.Start  
 $rptObj.EndTime = $Item.End  
 $rptObj.Duration = $Item.Duration
 $rptObj.Subject  = $Item.Subject   
 $rptObj.Type = $Item.AppointmentType
 $rptObj.Location = $Item.Location
 $rptObj.Organizer = $Item.Organizer.Address
 $rptObj.HasAttachments = $Item.HasAttachments
 $rptObj.IsReminderSet = $Item.IsReminderSet
 $aptStat = "";
 $AppointmentState.Keys | where { $_ -band $Item.AppointmentState } | foreach { $aptStat += $AppointmentState.Get_Item($_) + " "}
 $rptObj.AppointmentState = $aptStat 
 $RptCollection += $rptObj
 foreach($attendee in $Item.RequiredAttendees){
  $atn = $attendee.Address + "; "  
  $rptObj.Attendees += $atn
  }
 foreach($attendee in $Item.OptionalAttendees){
  $atn = $attendee.Address + "; "  
  $rptObj.Attendees += $atn
 }
 foreach($attendee in $Item.Resources){
  $atn = $attendee.Address + "; "  
  $rptObj.Resources += $atn
 }
 $rptObj.Notes = $Item.Body.Text
#Display on the screen
 "Start:   " + $Item.Start  
 "Subject: " + $Item.Subject 
}   
#Export to a CSVFile
$RptCollection |  Export-Csv -NoTypeInformation -Path "c:temp$MailboxName-CalendarCSV.csv"

Sympa: Who can send messages

When a Sympa list is……. You should / It means…
Closed Use this mode if you do not want anyone to send a message to the email list. Any messages sent will be rejected.
Restricted to subscribers Use this mode if you want only subscribers, list owners, and moderators to be able to send messages to the email list. Any messages sent by others will be rejected.
Moderated Use this mode if you want any messages sent to the email list to be moderated (approved by the moderator), except for messages from moderators. Moderators receive an email notification when a message that needs to be moderated is sent to the email list.
Moderated, even for moderators Use this mode if you want any messages sent to the email list to be moderated (approved by the moderator), including messages from moderators. Moderators receive an email notification when a message that needs to be moderated is sent to the email list.
Moderated, with editor confirmation Use this mode if you want any messages sent to the email list to be moderated, except for messages sent by moderators. When a moderator sends a message, they receive a confirmation email asking them to confirm their email (involves following a link or sending an email to Sympa with a certain authentication code) in order to have their message sent to the list.
Restricted to local domain Only users on the domain can post.
Restricted to local domain and subscribers Use this mode if you want only subscribers, list owners, moderators, and people on the local network to be able to send messages to the email list. Any messages sent by others will be rejected.
Newsletter, restricted to moderators Use this mode if you only want moderators to be able to send messages to the email list. Any messages sent by others will be rejected.
Newsletter, restricted to moderators after confirmation Use this mode if you only want moderators to be able to send messages to the email list, and messages from moderators must be moderated. Any messages sent by others will be rejected.
Restricted to subscribers check S/MIME signature Use this mode if you want only subscribers, list owners, and moderators with S/MIME signatures to be able to send messages to the email list. Any messages sent by others will be rejected.
Moderated, restricted to subscribers Use this mode if you want only subscribers and moderators to be able to send moderated messages to the email list. Any messages sent by others will be rejected. All posts are moderated except for posts from the moderator. Any messages sent by others will be rejected.
Moderated, for non subscribers sending multipart messages Use this mode if you want only subscribers, list owners, and moderators to be able to send messages to the email list. Any messages sent by others, and messages with attachments will be moderated.
Restricted to subscribers with previous md5 authentication Use this mode if you want only subscribers to be able to send messages to the email list after their email is confirmed. Upon sending a message, the subscriber receives a confirmation email asking them to confirm their email (involves following a link or sending an email to Sympa with a certain authentication code).
Moderated, for subscribers and moderators Use this mode if you want only subscribers, list owners, and moderators to be able to send messages to the email list after their email is confirmed. Upon sending a message, the subscriber receives a confirmation email asking them to confirm their email (involves following a link or sending an email to Sympa with a certain authentication code).
Private, moderated for non subscribers Use this mode if you want only subscribers, list owners, and moderators to be able to send messages to the email list without moderation. Any messages sent by others will be moderated.
Private, confirmation for non subscribers Use this mode if you want only subscribers, list owners, and moderators to be able to send messages to the email list without confirmed. When an non-subscriber sends a message, he or she receives a confirmation email asking them to confirm their email (involves following a link or sending an email to Sympa with a certain authentication code).
Public list Use this mode if you want anyone to be able to send a message to the email list.
Public list, Bcc rejected (anti spam) Use this mode if you want anyone to be able to send a message to the email list, except for message using bcc, which are rejected.
Anyone with previous md5 confirmation Use this mode if you want anyone to be able to send messages to the email list after their email is confirmed. Upon sending a message, the subscriber receives a confirmation email asking them to confirm their email (involves following a link or sending an email to Sympa with a certain authentication code).
Public list multipart / mixed messages are forwarded to moderator Use this mode if you want anyone to be able to send a message to the email list, except for messages with attachments, which are moderated.
Public list multipart messages are rejected Use this mode if you want anyone to be able to send a message to the email list, except for messages with attachments, which are rejected.

 

Replace A Mailbox’s Explicit Full Access Permission With A Mail Enabled Security Group To Allow Non-Admins To Manage Access.

Scenario:  Currently you have mailboxes that have explicit full access to a shared mailbox. Instead of giving full access permission at the root mailbox level, you want an automated way to define the full access permission to a mail enabled security group. You would like the distribution group populated with those mailboxes who had the explicit full access permission at the root mailbox level and then to remove those users explicit permission at the root mailbox level.  What you will be left with is a populated mail enabled security group with full permissions to a shared mailbox.

One of the biggest benefits for this is that you can assign a user as a  manager/owner of the distribution group who does not need Exchange permission.  They can then modify the membership of the group, thus giving or taking away full permission to other users for the shared mailbox without a call to the help desk.

Solution:  The script below will create a mail enabled security group which will be prefixed with ‘grp-‘, add the membership of the group for those users explicitly defined with full access to the shared mailbox and send-as permissions, add the group as having full control to the shared mailbox, and then remove the users explicit full access permission from the shared mailbox.

All you need is to either query, or import from a csv file, a list of shared mailboxes. If you use a csv file, make sure the column header is labeled Name.

#This script replaces a users explicit full access permission to a mailbox with a Mail Enabled Security Group that will have full access permission.

#This script will automatically gather those explicit users with full access permissions and put them into the mail enabled security group.

#This script give also make a specific user managedby permissions for the group.

#Import service accounts from CSV
$SvcMbx = Import-csv C:tempsvcmbx.csv

#Loop through each Service Mailbox
$SvcMbx | %{

#Define Variables
$N = $_.Name
$g = "GRP-"+$N
Write-Host "Now starting this service mailbox:$N"

#Gather FullMailbox permission with Explicit Access
$explicitmembers = (Get-MailboxPermission $N | Where {($_.IsInherited -eq $false) -and ($_.User -notlike '*Authority*') -and ($_.AccessRights -like "FullAccess")}).user

#Create the Mail Enabled Security Group and add the manager(s) of the group. Then lock the group down so it cannot accept messages except from the manager.
Write-Host "Creating the AD Universal Security Group"
New-ADGroup -name $g -GroupScope Universal -Path "OU=TestGroups,DC=domain,DC=com" -DisplayName $g 
Write-Host "Waiting for Replication"
Sleep 30
Write-Host "Provision the AD group as a Mail enabled Security Group"
Enable-DistributionGroup $g 
Write-Host "Waiting for Replication"
Sleep 30
Write-Host "Configuring the Mail Enabled Security Group:$g"
Set-distributionGroup $g -managedby "jdoe1" -bypasssecuritygroupmanagercheck -acceptmessagesonlyfrom "jdoe1" 

#Populate the explicit mailboxes that have permission to the service mailbox to the new mail enabled distribution group

Write-Host "Populating the Mail Enabled Security Group: Group:$g"
$explicitmembers | %{
Add-DistributionGroupMember $g -member $_.RawIdentity -bypasssecuritygroupmanagercheck 
}

#Add the mail enabled security group to the service mailbox with full permission and automapping set to false
Write-Host "Adding $g with Full Permission and Send As permission to $n" 
Add-mailboxpermission $n -user $g -accessrights fullaccess -automapping $false 
Add-ADPermission $n -user $g -extendedRights 'Send-As'

#Remove the users explicit access to the service mailbox
Write-host "Removing the users Explicit access to $n"
$explicitmembers | %{
Remove-mailboxPermission $n -user $_.RawIdentity -accessrights FullAccess -confirm:$false 
}
}

 

 

Script to Create Database and Database Copies

Scenario:  You would like to create Databases and Database Copies via a script. For each database, you want to set the Quotas for Send, Send/Receive, and Warning to unlimited as well.

Solution:

Create a db.csv file with the following column headers: DB,1,2,3,4.  In that CSV File, put the name of the DB in the DB column, and each server in its numerical location based on Activation Preference:

db,1,2,3,4
DB1,Ex2013Srv1,Ex2013Srv2,Ex2013Srv3,Ex2013Srv4
DB2,Ex2013Srv2,Ex2013Srv3,Ex2013Srv4,Ex2013Srv1
DB3,Ex2013Srv3,Ex2013Srv4,Ex2013Srv1,Ex2013Srv2
DB4,Ex2013Srv4,Ex2013Srv1,Ex2013Srv2,Ex2013Srv3

Then run the script:

#Import the CSV File into a Variable
$DBs = Import-CSV C:tempDb.csv

#Loop the Variable
$DBs | %{
#Declare variables for each column
$n = $_.DB
$1 = $_.1
$2 = $_.2
$3 = $_.3
$4 = $_.4

#Create the DB
Write-Host "Creating $n"
New-MailboxDatabase $n -EDBFilePath C:$nDB$n.edb -LogFolderPath C:$nLogs -Server $1 

#Wait for replication
Write-Host "Sleeping 3 minutes for replication"
Sleep 180

#Mount the Database
Write-Host "Mounting $n"
Mount-Database $n

#Wait for additional replication
Write-Host "Sleeping 3 minutes for replication"
Sleep 180

#Setting the DB Quotas
Write-Host "Setting DB Quotas to unlimited"
Set-MailboxDatabase $n -ProhibitSendReceiveQuota Unlimited -ProhibitSendQuota Unlimited -IssueWarningQuota Unlimited

#Create the additional Database Copies
Write-Host "Creating ActivationPreference2 for $n"
Add-MailboxDatabaseCopy $n -MailboxServer $2 -ActivationPreference 2
Write-Host "Creating ActivationPreference3 for $n"
Add-MailboxDatabaseCopy $n -MailboxServer $3 -ActivationPreference 3
Write-Host "Creating ActivationPreference4 for $n"
Add-MailboxDatabaseCopy $n -MailboxServer $4 -ActivationPreference 4
}

 

 

 

 

Configuring UploadReadAheadSize for Certificate Based Authentication for ActiveSync

Scenario: When configuring Certificate Based Authentication, you will have to configure the UploadReadAheadSize property in IIS to  allow message content greater than 48K.  Without the UploadReadAheadSize properly set, some symptoms you may experience are HTTP Status codes of 413 for ActiveSync Requests in the IIS logs  and mobile devices may experience size errors when attempting to send email.

Solution:

How to set the uploadReadAheadSize in IIS 7.5

  1. Launch “Internet Information Services (IIS) Manager”
  2. Expand the Server field
  3. Expand Sites
  4. Expand Default Web Site
  5. Click on Microsoft-Server-ActiveSync
  6. In the Features section, double click “Configuration Editor”
  7. Under “Section” select: system.webServer>serverRuntime
  8. Modify the “uploadReadAheadSize” section to 36700160 for 35MB.
  9. Click Apply