1

My ultimate goal is to give any piece of information on contacts in Outlook or MS Exchange and get their name and email address without encountering any warning message.

I have developed a function that works well except for the part that I am getting a pop up warning message from Outlook Object Model Guard (OMG) and I need to skirt around it without using any paid add-in,CDP, Redemption or changing the setting in Programmatic access in Outlook application (Trust Center) etc.

My code is in Excel VBA and I am not doing an early binding to the Outlook library.

I know accessing some objects or methods will trigger the OMG to popup a warning and wait for a confirmation from the user. I was wondering there is a way to pro grammatically in VBA disable OMG and then enable it afterwards?

Warning Message

Excel VBA Function:

Public Function GetContactObject2(strInput As String) As Object
    Dim chk As Boolean
    Dim sEmailAddress As String
    Dim olApp As Object
    Dim olNS As Object 'NameSpcase OL identifiers
    Dim olAL As Object 'AddressList An OL address list
    Dim olRecip As Object 'Outlook Recipient Object
    Dim olAddrEntry As Object 'AdressEntry An Address List entry
    Dim olCont As Object 'ContactItem An Outlook contact item
    Dim olExchUser As Object 'outlook Exchange User Object
    Dim obj As Object
    Dim oPA As Object

    chk = True 'assume everything is running fine
    Err.Clear

    'On Error GoTo Handler
    Set olApp = GetObject(, "Outlook.Application")

    'If an instance of an existing Outlook object is not available, an error will occur (Err.Number = 0 means no error):
    If Err.Number <> 0 Then
        Set olApp = CreateObject("Outlook.Application")
    End If

    Set olNS = olApp.GetNamespace("MAPI")
    'Set olAL = olNS.AddressLists("Global Address List")
    Set olRecip = olNS.createrecipient(strInput)
    olRecip.Resolve 'this line will cause Outlook Security Manager to pop up a message to allow or deny access to email

    'Check if the entry was resolved
    If olRecip.Resolved Then
        Set olAddrEntry = olRecip.AddressEntry
        Set olCont = olAddrEntry.GetContact

        If Not (olCont Is Nothing) Then
            'this is a contact
            'olCont is ContactItem object
            MsgBox olCont.FullName
        Else
            Set olExchUser = olAddrEntry.GetExchangeUser
            If Not (olExchUser Is Nothing) Then
                'olExchUser is ExchangeUser object
                'MsgBox olExchUser.PrimarySmtpAddress
                Set obj = olExchUser
            Else
                Set obj = Nothing
            End If
        End If
    Else 'Recipient was not found at all in the Global Address List
        Set obj = Nothing
    End If
    On Error GoTo 0

    Set GetContactObject2 = obj
    Exit Function
Handler:
    MsgBox "Err #: " & Err.Number & vbNewLine & Err.Description
End Function

Excel VBA Function 2 that calls the first function:

    '=========================================
    ' Get Current User Email Address Function
    '=========================================
    ' Gets current user's email address using outlook MAPI namespace
    ' RETURNS: user email if found, otherwise a zero-length string
    Public Function GetCurrentUserEmailAddress2() As String
        Dim chk As Boolean
        Dim strInput As String 'any string that can be resolved by outlook to retrieve contact item
        Dim sEmailAddress As String
        Dim olApp As Object
        Dim olNS As Object
        Dim obj As Object 'object for contact

        chk = True 'assume everything is running fine
        Err.Clear

        On Error Resume Next
        Set olApp = GetObject(, "Outlook.Application")

        'if an instance of an existing Outlook object is not available, an error will occur (Err.Number = 0 means no error):
        If Err.Number <> 0 Then
            Set olApp = CreateObject("Outlook.Application")
        End If


        '''' Set olNS = olApp.GetNamespace("MAPI")
        'This line will cause Outlook to pop a warning window that a program wants to have access your email address
        '''' sEmailAddress = olNS.Accounts.Item(1).SmtpAddress


        'Get a contact object and then extract the email from there
        'NOTE: some users' alias is their windows login, but some have different alias so it may fail. The best bet is finding the
        'email address using some other way and using it as the input which will almost never fail


        strInput = olApp.Session.CurrentUser.Address
        Set obj = GetContactObject2(strInput)

        If obj Is Nothing Then
            'Try one more time with windows login
            strInput = Environ("UserName")
            Set obj = GetContactObject2(strInput)
            If obj Is Nothing Then
                chk = False
            Else
                sEmailAddress = obj.PrimarySmtpAddress
            End If
        Else
            sEmailAddress = obj.PrimarySmtpAddress
        End If

        'Return a zero length string if by any chance email could not be retrieved, else validate it
        If chk = True Then
            chk = ValidateEmailAddress(sEmailAddress, bShowMessage:=False)
        Else
            sEmailAddress = ""
        End If

        On Error GoTo 0

        'Assign string to function
        GetCurrentUserEmailAddress2 = sEmailAddress

    End Function
Martijn Pieters
  • 1,048,767
  • 296
  • 4,058
  • 3,343
Ibo
  • 4,081
  • 6
  • 45
  • 65
  • Let's hope there is no way around that warning, or hackers will have a field day! Why don't you work the other way - have your code in Outlook and write the output to Excel via an "Excel.Application". – YowE3K May 22 '17 at 21:58
  • @YowE3K I have too many users and I cannot do that. There are tricks with Sendkeys etc, but none of them looked good to me. There are ways to disable it with manipulating the registry so it is not really a problem for a hacker. OMG is good for some basic viruses that are caught these days easily with even free anti-viruses so I guess there should have been some option to let OMG recognize which application is in-house and should be trusted. MicroSoft stopped further development on a lot of things including these ones! – Ibo May 22 '17 at 22:12
  • Which Office are you on? – 0m3r May 22 '17 at 22:29
  • @0m3r office 2010 – Ibo May 22 '17 at 22:45
  • Can you share/show how are you calling the function? – 0m3r May 23 '17 at 01:07
  • This https://msdn.microsoft.com/en-us/library/office/ff866986.aspx mentions an 'untrusted application'. A few more google searches later I found these: https://support.office.com/en-us/article/Add-remove-or-view-a-trusted-publisher-1c7c871c-632c-408c-8233-c7dd47289a00?ui=en-US&rs=en-US&ad=US&fromAR=1 https://stackoverflow.com/questions/5990150/how-to-make-application-trusted-to-outlook – Nick.Mc May 23 '17 at 01:07
  • Make sure your antivirus is up to date too, when it is you shouldn't receive that popup. – Ryan Wildry May 23 '17 at 18:10
  • @0m3r I just added a second function that calls the first function – Ibo May 23 '17 at 18:51
  • This is the list if protected methods and properties. I wonder there is any unprotected method or property that can be used to extract the current user's email address? https://msdn.microsoft.com/en-us/library/office/ff867291.aspx – Ibo May 23 '17 at 18:59
  • if you need the current active users email, why not query AD? https://stackoverflow.com/questions/21110232/getting-ad-details-based-on-username – interesting-name-here May 23 '17 at 19:04
  • @GibralterTop I just tried this function, it gives you the some info but email address was not there. – Ibo May 23 '17 at 19:27
  • 1
    Note that the name of the `email` attribute is `mail`, https://stackoverflow.com/questions/785527/get-mail-address-from-activedirectory#785617. Also, you have to change the code in the link where `attr = "mail"` and `WScript.Echo rs.Fields("mail").Value`. I don't know what you tried, so you may have already tried it. – interesting-name-here May 24 '17 at 14:28
  • @GibralterTop it did work! Thanks! – Ibo May 24 '17 at 16:20
  • Awesome! Glad it helped. – interesting-name-here May 24 '17 at 16:32

2 Answers2

1

You need to either make sure an up-to-date AV app is installed, or (if you cannot control the environment), a utility like ClickYes to simulate a mouse click on the security prompt or a library like Redemption (I am its author) to bypass the prompt programmatically.

See http://www.outlookcode.com/article.aspx?id=52 for the detailed list of your options.

Dmitry Streblechenko
  • 62,942
  • 4
  • 53
  • 78
  • as I mentioned in my question, I don't want to use 3rd party toos etc. AV would be good, but I cannot control it for all of the users and every time there is a new version, AV will fire the guard, so I want to solve this once for all – Ibo May 23 '17 at 21:30
  • Then your only option is Extended MAPI (C++ or Delphi only) - it is not accessible from VBA. – Dmitry Streblechenko May 23 '17 at 21:34
1

If all you need is the current users email address, I would use Active Directory. All your users should be able to at least read the values from AD.

See this post as to how to query AD in VBA code.

Note: the name of the email attribute is mail, documentation. So, you have to change the code in the link to attr = "mail" and WScript.Echo rs.Fields("mail").Value

Side note: I highly suggest any developer install RSAT so that they can verify values in AD by using MMC.

interesting-name-here
  • 1,851
  • 1
  • 20
  • 33
  • One caveat is that the users must be in the same network. I can retrieve the email of employees in in the same AD network, whole there are others in other countries using different AD and I could not get their info, while it is possible to get all of the from MS Exchange. It looks like that I have to build my own database for users information. – Ibo May 24 '17 at 16:47