vbscriptoutlooksecurity-warning

How to avoid Outlook Security Alert when sending Outlook message from VBScript?


I have this situation:

I thought there would be no way to send an email using Outlook in an automated-ish manner (on an unattended box logged in as a user with the screen locked). I tried many different approaches but would always get the security warning message. How can I fix this?

I've already tried everything at this helpful site and eliminated each option as follows:

Strategies
Ideally, applications that automate Outlook should avoid code that triggers these security prompts.

This is exactly what I ended up doing (see my answer below), which is why all of the other options on that page are irrelevant. Let's take them one by one:

Sending messages
It is not necessary to use Outlook objects at all if your goal is simply to create and send an email message. Microsoft provides the CDO for Windows library for creating and sending messages with SMTP. Using this library totally bypasses Outlook and MAPI and does not trigger security prompts. For code samples, see ...

SMTP. No-go. Disallowed by network policy.

Use Extended MAPI instead of Outlook objects, Simple MAPI, or CDO 1.21 for all code that potentially triggers security prompts.

Extended MAPI may work, but it is extremely cumbersome and verbose and involves lots of C/C++ code (which is not on topic for this question; see above), and seems to be impossible to use it without prompting the user for their password.

Use a third-party library -- Redemption or MAPI33 -- for all code that potentially triggers security prompts. This approach is easier than using Extended MAPI, which has a steep learning curve, and almost as secure. These libraries also offer additional features to help with Outlook code projects.

The problem with third-party libraries is four-fold: - They cost money; - They introduce licensing issues even if they're free (some organizations require extensive vetting from lawyers before allowing the software into the ecosystem); - Most environments where this entire problem is even a concern are those where the user cannot disable programmatic access warnings in Outlook options. Hmm, what possible cases would those be? Could it be... corporate environments? Procurement of software in a corporate environment takes an excessively long time, to the point of being impractical unless the cost savings of using it will exceed several million dollars. But there are many practical process improvements that can be made which do not yield as high of a cost savings, but would cost more money and labor to procure the third-party software than the total savings, if software procurement is necessary. - Network administrators may not trust the software to reside on a system, since it could be used for malicious purposes.

Deploy with your application a tool to suppress the security prompts.

This assumes that suppression of the OMG prompts is necessary, which, in my case, it is not, just to send a simple email (see my answer).

For Outlook 2007, make sure the machine is running an up-to-date anti-virus application and do all coding with Outlook objects, avoiding CDO 1.21 and Simple MAPI code.

The virus scanner is up to date, but it is completely out of my control to change its version or vendor, and Outlook doesn't recognize it. It says: "Antivirus status: Invalid. This version of Windows supports antivirus detection, but no antivirus was found."

In Outlook custom form code, Outlook VBA code, and COM add-ins, derive all objects from the Outlook.Application object provided by VBA or the add-in architecture. For example, see the sample VBA "run a script" rule procedure below.

Interesting, and possibly useful, but not necessary. This creates an unnecessary dependency on setting up a rule in Outlook in order to deploy the software, which complicates deployment.

Deploy Outlook security settings that "trust" certain COM add-ins or that allow all applications to have unrestricted access to certain features, such as accessing addresses. In versions before Outlook 2007, this requires Microsoft Exchange Server. For Outlook 2007, see the section on version-specific considerations below.

Cumbersome: administrative access would be needed to install a COM add-in, and it can be hard to come by administrative access in some organizations.

In a corporate environment where Exchange is the email server, direct access to the data on the server is available through the WebDAV API beginning with Exchange 2000 and, starting with Exchange 2007, through Exchange Web Services.

Disabled in my environment, and likely others.

In a corporate environment, the administrator may choose to loosen Outlook security for some or all users.

Sure, but this requires communication/coordination/cooperation with the network team. If administrative access is not available for installing a COM addin, it probably is not available for loosening group policy, either.


Solution

  • This code works on my system with Outlook 2010 to send an email with no user interaction. It's slightly brittle, in that, if the user happens to be actively working on the system (typing, clicking) when the mail is composed, it could occur that user input makes its way into the window that pops up for a split second, and either interfere with the sending of the mail, or add extra unknown characters into the body of the mail.

    As long as the user on whose system this is running is aware of this, and the potential consequences of spurious keystroke interference are not business-critical, this function is acceptable.

    Important to note: the key to this solution is that we do not call the MailItem.Send method. This is the method that triggers the programmatic access protection. Instead, we trigger the ALT+s shortcut, which by default, when a mail window has focus in Outlook, presses the "Send" button. If you have the default spell checking prompt enabled, this will pop up a further prompt for spellchecking. Our solution was to disable the spellchecking prompt, although I'm sure you could add some more SendKeys to click through it, since the spellchecking prompt is not a security-related dialog.

    A note about UIPI (User Interface Privilege Isolation):

    Outlook 2010 runs as the user who logged into the system, with a Medium integrity level. Programs which are launched by Windows Explorer, or started as a child or descendant of a program which was launched in a similar way, will also be launched with a Medium integrity level. UIPI is not effective at preventing "SendKeys" type input, as long as the user and session ID match, and the integrity level is the same or higher. In my particular environment, the user and session ID are identical, and the integrity level is the same for the VBScript host process and the Outlook process. In your environment, if any of these conditions are false, this code will not work. It is also untested on earlier or later versions of Office than version 2010.

    Sub SendEmail_Outlook()
        Set WshShell = WScript.CreateObject("WScript.Shell")
        Set ol=CreateObject("Outlook.Application") 
        Set Mail=ol.CreateItem(0) 
        Mail.to= "you@example.com"
        Mail.Subject = "test"
        Mail.HTMLBody = "test"
        Mail.Display    
        WshShell.SendKeys "%s"
        Set Mail = Nothing 
        Set ol = Nothing 
    End Sub
    
    SendEmail_Outlook
    

    Also, here is how to make this work when running the VBScript from Windows Task Scheduler. Just tick the box depicted by the red oval, "Run With Highest Privileges", to make it run with the highest possible integrity level without UAC elevation ("Medium" if you are not an administrator account).

    windows task scheduler properties