I haven’t thought about email read receipts for years. It’s a very old email feature that goes back to the days when unreliable SMTP and X.400 connections linked organizations together and you never quite knew if email got through to its destination. The reliability of computer networks today means that read receipts are less important, or maybe it’s just that other communication methods have replaced some email traffic, like Teams. The introduction of read receipts for Teams in early 2020 doesn’t count because the read receipt for chats is more of a “seen” indicator than a message returned to a sender to confirm that an addressee has opened an email (Figure 1).
Figure 1: A read receipt comes back to confirm a recipient has read a message
Helping a Police Chief
Which brings me to a request from an Office 365 for IT Pros reader. Apparently, a police chief is sick and tired that their email sent to some recipients is not being responded to. They want to know when the addressees open the messages he sends. The request was to be able to turn on automatic read receipts for mailboxes and disable the ability of users to change the setting.
Read receipt is a message option, like delivery receipt (confirming the delivery of a message to a mailbox). When set, the read receipt shows up in the message properties as a Disposition-Notification-To header with the return address to receive the read receipt (Figure 2). A blast from the past EHLO blog post from 2011 explains more.
Figure 2: The Disposition-Notification-To message header holds the person to receive the read receipt
The presence of the Disposition-Notification-To header is what prompts clients to check if they should ignore the request, send the receipt automatically, or ask the user if they’d like to send the receipt. The immediate problem in satisfying the user request is that Exchange Online considers read receipts to be a client-side function. In other words, the action to respond to the sender is invoked when a recipient uses a client to open a message with a read receipt requested. Clients have different settings to control how to respond.
OWA Read Receipt Settings
Take OWA for example. It’s easy to configure the user settings for read receipts through the Message handling section in OWA settings (Figure 3).
Figure 3: Read receipt options in OWA settings
There’s also an Exchange Online PowerShell cmdlet to do the job. For instance, let’s assume that we want a set of users to always send read receipts when requested. This code uses the CustomAttribute12 property to hold the value “RR” to indicate that a mailbox should be in the set. We can use a server-side filter to find the mailboxes and call the Set-MailboxMessageConfiguration cmdlet to update the read receipts setting.
# Find mailboxes to update and then update their read receipt setting to always send read receipts
[array]$Mbx = Get-ExoMailbox -RecipientTypeDetails UserMailbox -ResultSize Unlimited -Filter {CustomAttribute12 -eq "RR"}
If ($Mbx.Count -eq 0) {Write-Host "No mailboxes found"; break}
ForEach ($M in $Mbx) {
Write-Host "Setting mailbox read receipt configuration for" $M.DisplayName
Set-MailboxMessageConfiguration -Identity $M.UserPrincipalName -ReadReceiptResponse AlwaysSend }
Using RBAC to Remove Read Receipt Settings from OWA
Although administrators can update user mailbox settings to control read receipts, it does nothing to stop users changing the read receipt options through OWA settings. To block that happening, we need to remove the read receipt options from the GUI. Exchange Online has a well-developed role-based access control (RBAC) system to control features available to users. RBAC works through the user role assignment policy set on user mailboxes. These policies enable or disable features by controlling the cmdlets available to users. For instance, I’ve written in the past about how to use RBAC to stop people updating their OWA autosignature.
To stop users changing the read receipt setting, we need to:
Create a new RBAC role based on the regular set of user options.
Remove the entry in the role for the cmdlet used to update read receipt settings (Set-MailboxMessageConfiguration).
Remove the entry in the role for the cmdlet used to fetch add display the read receipt settings (Get-MailboxMessageConfiguration).
Create a new user role assignment policy containing the roles usually granted to users with the exception that we replace the base options with the edited version which blocks the ability to update the read receipt settings.
All of this sounds complicated, but it’s a system that worked well since its introduction in Exchange 2010. Here’s the PowerShell code to do the work listed above:
Thirty minutes or so later, the new policy will take effect. You’ll know that it works if you go to OWA settings and don’t see the options to update the read receipt settings (Figure 4).
Figure 4: The read receipt option is removed from OWA settings by the user role assignment policy
To bring the solution together, you can add the Set-Mailbox command to the code described above to update the read receipt setting and assign the user role assignment policy for the set of target mailboxes.
Our problem is solved if OWA is the sole client in use. Unhappily, that’s probably not the case. Clients like Outlook for Windows, Outlook for Mac, and Outlook mobile might be in use, as might third-party clients. Every client has its own method to control the processing of read receipts. For instance, Figure 5 shows the settings in Outlook for Windows (click to run version).
Figure 5: Outlook for Windows settings to control read receipt processing
For historic reasons, most Outlook for Windows settings are stored in the system registry. A check of the settings available in the administrative templates for Outlook reveals that the read receipts are controlled by the receipt response DWORD value at HKCU\Software\Policies\Microsoft\Office\16.0\Outlook\Options\Mail. The values are:
0: Always send a response.
1: Never send a response.
2: Ask the user before sending a response.
You can update the value manually by editing the registry (Figure 6), which is fine for a test case. In production, you’re likely to use a group policy object (GPO) or other technique to deploy the policy setting to client workstations.
Figure 6: The system registry value to stop Outlook for Windows allowing users to choose a read receipt setting
Once the policy is in place, Outlook greys out the options to control read receipts.
Client-Side Feature Dependant on Client-Side Controls
In summary, read receipts are a client-side feature invoked by the presence of the Disposition-Notification-To message header. Because it’s a client-side feature, any attempt to force the client to process read receipts in a particular manner depends on the controls available in a client. We can satisfy the police chief’s request for OWA and Outlook for Windows. I see no way to do this for Outlook mobile and didn’t investigate Outlook for Mac or any of the many other email clients which can connect to Exchange Online using Exchange ActiveSync (EAS), IMAP4, or POP3 (hopefully without using basic authentication). Now you know what you should look for, checking how to deal with other clients is an exercise for the reader!
Learn more about how Office 365 really works on an ongoing basis by subscribing to the Office 365 for IT Pros eBook. Our monthly updates keep subscribers informed about what’s important across the Office 365 ecosystem.
{"id":null,"mode":"button","open_style":"in_modal","currency_code":"EUR","currency_symbol":"\u20ac","currency_type":"decimal","blank_flag_url":"https:\/\/office365itpros.com\/wp-content\/plugins\/tip-jar-wp\/\/assets\/images\/flags\/blank.gif","flag_sprite_url":"https:\/\/office365itpros.com\/wp-content\/plugins\/tip-jar-wp\/\/assets\/images\/flags\/flags.png","default_amount":100,"top_media_type":"featured_image","featured_image_url":"https:\/\/office365itpros.com\/wp-content\/uploads\/2022\/11\/cover-141x200.jpg","featured_embed":"","header_media":null,"file_download_attachment_data":null,"recurring_options_enabled":true,"recurring_options":{"never":{"selected":true,"after_output":"One time only"},"weekly":{"selected":false,"after_output":"Every week"},"monthly":{"selected":false,"after_output":"Every month"},"yearly":{"selected":false,"after_output":"Every year"}},"strings":{"current_user_email":"","current_user_name":"","link_text":"Virtual Tip Jar","complete_payment_button_error_text":"Check info and try again","payment_verb":"Pay","payment_request_label":"Office 365 for IT Pros","form_has_an_error":"Please check and fix the errors above","general_server_error":"Something isn't working right at the moment. Please try again.","form_title":"Office 365 for IT Pros","form_subtitle":null,"currency_search_text":"Country or Currency here","other_payment_option":"Other payment option","manage_payments_button_text":"Manage your payments","thank_you_message":"Thank you for supporting the work of Office 365 for IT Pros!","payment_confirmation_title":"Office 365 for IT Pros","receipt_title":"Your Receipt","print_receipt":"Print Receipt","email_receipt":"Email Receipt","email_receipt_sending":"Sending receipt...","email_receipt_success":"Email receipt successfully sent","email_receipt_failed":"Email receipt failed to send. Please try again.","receipt_payee":"Paid to","receipt_statement_descriptor":"This will show up on your statement as","receipt_date":"Date","receipt_transaction_id":"Transaction ID","receipt_transaction_amount":"Amount","refund_payer":"Refund from","login":"Log in to manage your payments","manage_payments":"Manage Payments","transactions_title":"Your Transactions","transaction_title":"Transaction Receipt","transaction_period":"Plan Period","arrangements_title":"Your Plans","arrangement_title":"Manage Plan","arrangement_details":"Plan Details","arrangement_id_title":"Plan ID","arrangement_payment_method_title":"Payment Method","arrangement_amount_title":"Plan Amount","arrangement_renewal_title":"Next renewal date","arrangement_action_cancel":"Cancel Plan","arrangement_action_cant_cancel":"Cancelling is currently not available.","arrangement_action_cancel_double":"Are you sure you'd like to cancel?","arrangement_cancelling":"Cancelling Plan...","arrangement_cancelled":"Plan Cancelled","arrangement_failed_to_cancel":"Failed to cancel plan","back_to_plans":"\u2190 Back to Plans","update_payment_method_verb":"Update","sca_auth_description":"Your have a pending renewal payment which requires authorization.","sca_auth_verb":"Authorize renewal payment","sca_authing_verb":"Authorizing payment","sca_authed_verb":"Payment successfully authorized!","sca_auth_failed":"Unable to authorize! Please try again.","login_button_text":"Log in","login_form_has_an_error":"Please check and fix the errors above","uppercase_search":"Search","lowercase_search":"search","uppercase_page":"Page","lowercase_page":"page","uppercase_items":"Items","lowercase_items":"items","uppercase_per":"Per","lowercase_per":"per","uppercase_of":"Of","lowercase_of":"of","back":"Back to plans","zip_code_placeholder":"Zip\/Postal Code","download_file_button_text":"Download File","input_field_instructions":{"tip_amount":{"placeholder_text":"How much would you like to tip?","initial":{"instruction_type":"normal","instruction_message":"How much would you like to tip? Choose any currency."},"empty":{"instruction_type":"error","instruction_message":"How much would you like to tip? Choose any currency."},"invalid_curency":{"instruction_type":"error","instruction_message":"Please choose a valid currency."}},"recurring":{"placeholder_text":"Recurring","initial":{"instruction_type":"normal","instruction_message":"How often would you like to give this?"},"success":{"instruction_type":"success","instruction_message":"How often would you like to give this?"},"empty":{"instruction_type":"error","instruction_message":"How often would you like to give this?"}},"name":{"placeholder_text":"Name on Credit Card","initial":{"instruction_type":"normal","instruction_message":"Enter the name on your card."},"success":{"instruction_type":"success","instruction_message":"Enter the name on your card."},"empty":{"instruction_type":"error","instruction_message":"Please enter the name on your card."}},"privacy_policy":{"terms_title":"Terms and conditions","terms_body":null,"terms_show_text":"View Terms","terms_hide_text":"Hide Terms","initial":{"instruction_type":"normal","instruction_message":"I agree to the terms."},"unchecked":{"instruction_type":"error","instruction_message":"Please agree to the terms."},"checked":{"instruction_type":"success","instruction_message":"I agree to the terms."}},"email":{"placeholder_text":"Your email address","initial":{"instruction_type":"normal","instruction_message":"Enter your email address"},"success":{"instruction_type":"success","instruction_message":"Enter your email address"},"blank":{"instruction_type":"error","instruction_message":"Enter your email address"},"not_an_email_address":{"instruction_type":"error","instruction_message":"Make sure you have entered a valid email address"}},"note_with_tip":{"placeholder_text":"Your note here...","initial":{"instruction_type":"normal","instruction_message":"Attach a note to your tip (optional)"},"empty":{"instruction_type":"normal","instruction_message":"Attach a note to your tip (optional)"},"not_empty_initial":{"instruction_type":"normal","instruction_message":"Attach a note to your tip (optional)"},"saving":{"instruction_type":"normal","instruction_message":"Saving note..."},"success":{"instruction_type":"success","instruction_message":"Note successfully saved!"},"error":{"instruction_type":"error","instruction_message":"Unable to save note note at this time. Please try again."}},"email_for_login_code":{"placeholder_text":"Your email address","initial":{"instruction_type":"normal","instruction_message":"Enter your email to log in."},"success":{"instruction_type":"success","instruction_message":"Enter your email to log in."},"blank":{"instruction_type":"error","instruction_message":"Enter your email to log in."},"empty":{"instruction_type":"error","instruction_message":"Enter your email to log in."}},"login_code":{"initial":{"instruction_type":"normal","instruction_message":"Check your email and enter the login code."},"success":{"instruction_type":"success","instruction_message":"Check your email and enter the login code."},"blank":{"instruction_type":"error","instruction_message":"Check your email and enter the login code."},"empty":{"instruction_type":"error","instruction_message":"Check your email and enter the login code."}},"stripe_all_in_one":{"initial":{"instruction_type":"normal","instruction_message":"Enter your credit card details here."},"empty":{"instruction_type":"error","instruction_message":"Enter your credit card details here."},"success":{"instruction_type":"normal","instruction_message":"Enter your credit card details here."},"invalid_number":{"instruction_type":"error","instruction_message":"The card number is not a valid credit card number."},"invalid_expiry_month":{"instruction_type":"error","instruction_message":"The card's expiration month is invalid."},"invalid_expiry_year":{"instruction_type":"error","instruction_message":"The card's expiration year is invalid."},"invalid_cvc":{"instruction_type":"error","instruction_message":"The card's security code is invalid."},"incorrect_number":{"instruction_type":"error","instruction_message":"The card number is incorrect."},"incomplete_number":{"instruction_type":"error","instruction_message":"The card number is incomplete."},"incomplete_cvc":{"instruction_type":"error","instruction_message":"The card's security code is incomplete."},"incomplete_expiry":{"instruction_type":"error","instruction_message":"The card's expiration date is incomplete."},"incomplete_zip":{"instruction_type":"error","instruction_message":"The card's zip code is incomplete."},"expired_card":{"instruction_type":"error","instruction_message":"The card has expired."},"incorrect_cvc":{"instruction_type":"error","instruction_message":"The card's security code is incorrect."},"incorrect_zip":{"instruction_type":"error","instruction_message":"The card's zip code failed validation."},"invalid_expiry_year_past":{"instruction_type":"error","instruction_message":"The card's expiration year is in the past"},"card_declined":{"instruction_type":"error","instruction_message":"The card was declined."},"missing":{"instruction_type":"error","instruction_message":"There is no card on a customer that is being charged."},"processing_error":{"instruction_type":"error","instruction_message":"An error occurred while processing the card."},"invalid_request_error":{"instruction_type":"error","instruction_message":"Unable to process this payment, please try again or use alternative method."},"invalid_sofort_country":{"instruction_type":"error","instruction_message":"The billing country is not accepted by SOFORT. Please try another country."}}}},"fetched_oembed_html":false}