I pick up interesting problems looking for solutions on various forums, such as this one.
Can I create an Outlook Rule that will keep me from sending an email to the wrong address? The reason: I have various email addresses. On occasion, I intend to send a message to my own address and use the wrong address instead, sending an email to the same wrong person more than once.
You can't use a rule to protect you from yourself but if you realize it as soon as you hit send, you can use a rule to delay mail by a minute or two, to give you time to recover the message and change the address. I have more information at Defer delivery in Outlook. You could also disable autocomplete, since it is the main cause of this problem, but because its a very good time saver most of the time, a macro is better.
Alternately, you can use macros to help get the address right. Since the problem is likely due to your selecting the wrong address as you type in the To field, using macros to create and address messages will reduce some, if not all of the problems. You can also use a macro to check outgoing messages for an address.
Forward selected message to specific address
This macro solves the user's immediate problem, forwarding a message to the wrong address.
Create a macro for your address and assign the macro to a toolbar or ribbon button. Place the button(s) next to the Forward button to help you remember. You'll need one macro & button for each address you forward messages to.
Public Sub ForwardtoMe() Dim oMail As Outlook.MailItem Set oMail = Application.ActiveExplorer.Selection(1).Forward oMail.Recipients.Add ("alias@domain.com") oMail.Display End Sub
Check messages you send
This macro checks messages for one specific display name and if it finds a match, allows you to cancel the send. On Error Resume Next allows it to work with meetings or task requests, otherwise it kicks up an error message. Note: other macros on this page check the SMTP address and are recommended over this one.
Private Sub Application_ItemSend(ByVal Item As Object, Cancel As Boolean) On Error Resume Next ' use lower case for the address ' LCase converts all addresses in the To field to lower case If InStr(LCase(Item.To), "bad@address.com") Then Prompt$ = "You sending this to " & Item.To & ". Are you sure you want to send it?" If MsgBox(Prompt$, vbYesNo + vbQuestion + vbMsgBoxSetForeground, "Check Address") = vbNo Then Cancel = True End If End If End Sub
A slightly different version of the above macro checks messages you send for one of several addresses. If the address on the message is not one in the list (or there are multiple addresses in the list), it will ask if you really want to send.
While not the best option in my opinion, because it basically asks for confirmation every time you send, it may be a good solution in some cases.
To use, add your addresses to the Case line. This macro needs to be added to ThisOutlookSession to work.
Private Sub Application_ItemSend(ByVal Item As Object, Cancel As Boolean) On Error Resume Next Select Case LCase(Item.To) Case "alias@domain.com", "alias2@domain3.com", "alias3@domain3.com" Item.Send Case Else Prompt$ = "You are not sending this to " & Item.To & ". Are you sure you want to send the Mail?" If MsgBox(Prompt$, vbYesNo + vbQuestion + vbMsgBoxSetForeground, "Check Address") = vbNo Then Cancel = True End If End Select End Sub
Check addresses in the To, CC, or BCC field using the Recipient Collection
This variation of the code checks all addresses in the recipient collection against the "bad address".
Private Sub Application_ItemSend(ByVal Item As Object, Cancel As Boolean) Dim Recipients As Outlook.Recipients Dim recip As Outlook.Recipient Dim i Dim prompt As String On Error Resume Next ' use lower case for the address ' LCase converts all addresses in the To field to lower case Set Recipients = Item.Recipients For i = Recipients.Count To 1 Step -1 Set recip = Recipients.Item(i) Debug.Print recip.Address If InStr(LCase(recip.Address), "bad@domain.com") Then prompt$ = "You sending this to this to " & Item.To & ". Are you sure you want to send it?" If MsgBox(prompt$, vbYesNo + vbQuestion + vbMsgBoxSetForeground, "Check Address") = vbNo Then Cancel = True End If End If Next i End Sub
Check for multiple domains
This is Keith's code sample . Use it to check if the message is being sent to specific domains. With the simple removal of Case Else line, you can convert it from warning for all but the listed domains to warning for only those domains.
In this example, I'm using InStrRev function to get the position of the @ symbol to use when determining the length of domain, which allows me to use the Right function and Select Case. InStrRev looks for the designated string beginning on the right, not left as Instr does.
Private Sub Application_ItemSend(ByVal Item As Object, Cancel As Boolean) Dim recips As Outlook.Recipients Dim recip As Outlook.Recipient Dim pa As Outlook.PropertyAccessor Dim prompt As String Dim strMsg As String Dim Address As String Dim lLen Const PR_SMTP_ADDRESS As String = "http://schemas.microsoft.com/mapi/proptag/0x39FE001E" Set recips = Item.Recipients For Each recip In recips Set pa = recip.PropertyAccessor Address = LCase(pa.GetProperty(PR_SMTP_ADDRESS)) lLen = Len(Address) - InStrRev(Address, "@") Select Case Right(Address, lLen) Case "cdolive.com", "slipstick.com", "outlookmvp.com" Case Else ' remove case else line to be warned when sending to the addresses strMsg = strMsg & " " & Address & vbNewLine End Select Next If strMsg <> "" Then prompt = "This email will be sent outside of the company to:" & vbNewLine & strMsg & vbNewLine & "Please check recipient address." & vbNewLine & vbNewLine & "Do you still wish to send?" If MsgBox(prompt, vbYesNo + vbExclamation + vbMsgBoxSetForeground, "Check Address") = vbNo Then Cancel = True End If End If End Sub
Check for different domains
Frank wanted to check to see if a message was being sent to two different domains and if so, trigger a warning. (This code skips addresses in the sending account's domain.)
To do this, we need to create a string containing the message recipients then split it into an array. We compare the members of the array and if any two don't match, trigger the warning message. If you say Yes the first time the warning comes up, the macro exits and the message is sent. If you want to continue checking addresses after clicking Yes, remove the Exit Sub after the prompt.
Private Sub Application_ItemSend(ByVal Item As Object, Cancel As Boolean) Dim recips As Outlook.Recipients Dim recip As Outlook.Recipient Dim pa As Outlook.propertyAccessor Dim prompt As String Dim strMsg As String Dim Address As String Dim lLen Dim arr Dim strMyDomain Dim userAddress Const PR_SMTP_ADDRESS As String = "http://schemas.microsoft.com/mapi/proptag/0x39FE001E" ' non-exchange ' userAddress = Session.CurrentUser.Address ' use for exchange accounts userAddress = Session.CurrentUser.AddressEntry.GetExchangeUser.PrimarySmtpAddress lLen = Len(userAddress) - InStrRev(userAddress , "@") strMyDomain = Right(userAddress, lLen) Set recips = Item.Recipients For Each recip In recips Set pa = recip.propertyAccessor Address = LCase(pa.GetProperty(PR_SMTP_ADDRESS)) lLen = Len(Address) - InStrRev(Address, "@") str1 = Right(Address, lLen) If str1 <> strMyDomain Then strRecip = str1 & "," & strRecip End If Next arr = Split(strRecip, ",") ' need to subtract one because string ends with a , For i = LBound(arr) To UBound(arr) - 1 For j = LBound(arr) To i If arr(i) <> arr(j) Then prompt = "This email is being sent to people at " & arr(i) & " and " & arr(j) & " Do you still wish to send?" If MsgBox(prompt, vbYesNo + vbExclamation + vbMsgBoxSetForeground, "Check Address") = vbNo Then Cancel = True End If Exit Sub ' stops checking for matches End If Next j Next End Sub
Check for messages to Internal and External addresses
This version of the code will check for the presence of Internal and External addresses and if both are found, the warning message comes up. If the message is sent only to internal addresses or only to external addresses, the message is sent.
If str1 = strMyDomain Then internal = 1
If str1 <> strMyDomain Then external = 1
If internal + external = 2 Then
Private Sub Application_ItemSend(ByVal Item As Object, Cancel As Boolean) Dim recips As Outlook.Recipients Dim recip As Outlook.Recipient Dim pa As Outlook.propertyAccessor Dim prompt As String Dim Address As String Dim lLen Dim strMyDomain Dim internal As Long Dim external As Long Const PR_SMTP_ADDRESS As String = "http://schemas.microsoft.com/mapi/proptag/0x39FE001E" ' non-exchange ' userAddress = Session.CurrentUser.Address ' use for exchange accounts userAddress = Session.CurrentUser.AddressEntry.GetExchangeUser.PrimarySmtpAddress lLen = Len(userAddress) - InStrRev(userAddress, "@") strMyDomain = Right(userAddress, lLen) Set recips = Item.Recipients For Each recip In recips Set pa = recip.propertyAccessor Address = LCase(pa.GetProperty(PR_SMTP_ADDRESS)) lLen = Len(Address) - InStrRev(Address, "@") str1 = Right(Address, lLen) If str1 = strMyDomain Then internal = 1 If str1 <> strMyDomain Then external = 1 Next If internal + external = 2 Then prompt = "This email is being sent to Internal and External addresses. Do you still wish to send?" If MsgBox(prompt, vbYesNo + vbExclamation + vbMsgBoxSetForeground, "Check Address") = vbNo Then Cancel = True End If End If End Sub
Check new messages you send
A user with three accounts in his profile wanted to be reminded which email account was sending the message, but because Outlook always sends replies and forwards using the account that downloaded the message, he only want to check new messages.
The result is this code sample which checks new messages on send while skipping replies and forwards. It looks for RE: or FW: as the first 3 characters in the subject and skips the dialog if they are found. By using LCase, it will pick up RE:, Re: or re:.
To check all messages sent from all accounts except your default email account, replace the IF line with this:
If Not Item.SendUsingAccount = "my-default-account@domain.com" Then
To check only for a specific email account, use this:
If Item.SendUsingAccount = "alias-I-don't-use@domain.com" Then
Private Sub Application_ItemSend(ByVal Item As Object, Cancel As Boolean) On Error Resume Next If Not Left(LCase(Item.Subject), 3) = "re:" And Not Left(LCase(Item.Subject), 3) = "fw:" Then prompt$ = "You sending this from " & Item.SendUsingAccount & ". Are you sure you want to send it?" If MsgBox(prompt$, vbYesNo + vbQuestion + vbMsgBoxSetForeground, "Check Sending Account") = vbNo Then Cancel = True End If End If End Sub
Video tutorial: How to use the ItemSend macros
How to use VBA code samples
To use either of these macros, open the VBA Editor using Alt+F11. Expand Project1.
The macro that checks addresses when you send messages needs to be in ThisOutlookSession.
The macro that forwards mail to a specific address can go into a separate Module. To add a module, right click on Project1 and choose Insert > Module.
Paste the code into the editor.
Change the addresses in the sample code to your own address.
The macro that checks address will run when you send messages.
To create buttons for the forward macro:
In Outlook 2010 and above:
- Go to File, Options, and choose Customize Ribbon.
- Add a New Group to the list on the right side then Add the macro to the new group.
- Select Macros in Choose Commands from.
In Outlook 2007 and older:
- Right click in the toolbar area, choose Customize.
- Switch to the Commands tab.
- Select Macros under Categories.
- Drag the macro to anywhere on the Toolbar.
If you would rather not use a macro, the following add-ins can check messages before sending.
Tools
janusSEAL for Outlook's SafeDomain Extension provides users with a security policy safety net when sending messages from Microsoft Outlook. Warn when sending sensitive messages to a large number of recipients; Prevent users from sending sensitive messages to a large number of recipients; Remove recipients from sensitive messages; Correct email addresses when the sender accidentally uses a recipient's public email address for a sensitive message when they should have used their private network address. | |
Prevent email mistakes with the updated Safeguard Send add-in for Outlook 2016. It checks outgoing emails after you click the Send button to make sure that you're sending to the right recipients, that you're not sending emails with sensitive or classified keywords, anytime you're sending emails outside the company domains, and 12 other outgoing email checks that Outlook doesn't do. It warns you before the email goes out plus it can take 4 other actions on the email before it goes out, even auto adding a BCC recipient. | |
SafeSend Outlook detects external recipients in outgoing emails and meeting invitations, requests users to confirm external emails recipients, expands Outlook distribution lists. Supports multiple domains within corporate structure and multiple email accounts per user. Allows custom safe-domains. Puts minimum load on your Exchange server. | |
Send Guard will detect and prompt you whenever you make any of these mistakes and more: forget to send an attachment you promised in a message, Reply-to-All or forget to Reply-to-All, send emails using the wrong email account, send emails with blank or incorrect subjects, said something you oh-so-knew-better than to say. |
Hi,
Really great guide but it'd be fantastic if you could write one for multiple email addresses as I have tried and failed to adapt the Check for Multiple Domains one to work and my feeble brain cannot manage.
I am not sure if the emails need to be case sensitive, or whether it needs to be the full email address or simply how the email appears in the line, i.e. the email name that Outlook loves to abbreviate.
I know you have said do this and move this bit of code here but honestly it is beyond me.
Tim
Hi Diane, First of all, I wanted to say that I appreciate what you created here! Here is my scenario. I am trying to use the code for "Check new messages you send" with the addition of 'SentOnBehalfOfName' for alias email addresses to trigger a different message when using 'SentOnBehalfOfName'. The below code is almost there but doesn't work when sending emails using an alias email address. Would appreciate your assistance with this :) This is my code so far: 'Always verify sending account and from address. 'Place in ThisOutlookSession Private Sub Application_ItemSend(ByVal Item As Object, Cancel As Boolean) On Error Resume Next If Not Left(LCase(Item.Subject), 3) = "re:" And Not Left(LCase(Item.Subject), 3) = "fw:" Then Dim strMsg As String 'Check whether it is sent From account address' If Item.SenderEmailAddress <> Item.SendUsingAccount Then strMsg = "You are sending this from: " & Item.SendUsingAccount & _ vbNewLine & vbNewLine & "Are you sure you want to send it?" 'Check whether it is sent with a different From address of the account' '=== CODE THAT DOESN'T WORK === ElseIf Item.SenderEmailAddress <> Item.SentOnBehalfOfName Then strMsg = "You are sending this from: " & Item.SentOnBehalfOfName & _ vbNewLine & vbNewLine & "Are you sure… Read more Âğ
Hello Diane,
Thanks so much for this code! I'm wondering if you can help me alter it just slightly. My goal is to check all recipient fields (To, CC, BCC) for a particular set of addresses (john.doe@gmail.com, jane.doe@gmail.com, etc.) warn if they are present, and list only those flagged addresses in the warning?
I think the Check for Multiple Domains gets me the closest, as it seems to trigger on all fields and I simply substitute your example domains listed after "Case" with the full addresses I want flagged, but the list in the warning seems to include both flagged and unflagged addresses. I think it'll be easier for the person I'm wanting to apply this to if it specifically called out the address(es) in question alone. Is that possible?
It is possible - I would probably try moving this from the case else to under the case line.
strMsg = strMsg & " " & Address & vbNewLine
Hi Diane, Great post - Thank you! In the pop up message, us there a way to add a carriage return between sentence? I have a long pop up message that I would like to format better and I cant seem to do that because everything is on one line. Thanks
Add & vbcrlf & at the end of the line, where you want it to break.
& vbNewLine & should work too.
Hi Diane,
I am looking for a code or rule that warns for following case:
If I am trying to send an email.
If To, CC, or BCC fields contains:
@clienta.xyz and @clientb.com or @clientc.gov the user should be warned by Outlook.
This is to prevent sensitive information from accidently being shared across clients and vendors.
Is there a VBA code or any readily available addin that does this?
Thanks,
Vahid
The code above for Check for multiple domains should do that.
Wow, thanks for the quick response. Yes, it works. I had tried it initially but it was not working. I restarted outlook and now it does.
Is there a way to make it foolproof for certain domains.
Example. Never allow emails to be sent to @client.com and @supplier.com
With the current code it still allows you to send the email if you click ok. We would prefer to have a way to completely block certain combinations of email address.
Thanks for your help
Vahid
Hi - Great post. Would it be possible to alter the "Check addresses in the To, CC, or BCC field using the Recipient Collection" to check a list of addresses vs. just one?
Thanks,
Amber
Check for multiple domains should do that.
Hi, I am using the "Check for messages to Internal and External addresses" code. It errors out when user defined contact group(s) are in any of the address fields. The error is in regards to
Const PR_SMTP_ADDRESS As String = "http://schemas.microsoft.com/mapi/proptag/0x39FE001E"
Adding "On Error Resume Next" to the code gets us out of the error condition but that doesn't check any of group contacts then.
We are running against Exchange Online.
Any thoughts on how to correct?
Hi,
what a great set of script pages. I'm trying to work out how I can run your warn before sending scripts against two 'lists' of email addresses . The lists being either groups or txt files or something else that warns if sending an email to anyone not one one list or on both to make sure senders know they're to the right recipients. The two lists are kind of "core developer team" and more widely "general project". I cant use domain as a discriminator unfortunately, hence the lists.