none
Checking if Active Directory User has OWA Enabled via VB.Net RRS feed

  • Question

  • I am a 'newbie" trying to update vb.net code to read the "ProtocolSettings" (Multi-Value) attribute for a user and return whether OWA  is "Enabled" or "Disabled" but so far I haven't been able to figure it out. Hoping someone can help. The below code is what the previous programmer was using. We are trying to update the code as many things have changed and the original programmer has since left. Thanks in Advance!

                Try
    Dim Desc As Object
                    Dim OWAStatus As String
                    Dim DescList As Object
                    Dim I As Object

                    DescList = GetADProperty(user, "protocolsettings")

                    OWAStatus = Enabled

                    For Each Desc In DescList

                        I = InStr(1, Desc, "§", vbTextCompare)
                        If I <> 0 Then
                            If Microsoft.VisualBasic.Left(Desc, I - 1) = "OWA" Then
                                Desc = Microsoft.VisualBasic.Right(Desc, Len(Desc) - I)
                                If Microsoft.VisualBasic.Left(Desc, 1) = "0" Then
                                    OWAStatus = "Disabled"

                                End If
                            End If
                            If Microsoft.VisualBasic.Left(Desc, I - 1) = "HTTP" Then
                                Desc = Microsoft.VisualBasic.Right(Desc, Len(Desc) - I)
                                If Microsoft.VisualBasic.Left(Desc, 1) = "0" Then
                                    OWAStatus = "Disabled"

                                End If
                            End If
                        End If
                        tbOWAEnabled.Text = OWAStatus
                    Next
                 Catch
                End Try



    Wednesday, April 4, 2018 3:21 PM

Answers

  • Here is the code snippet for parsing the OWA setting to see if it is enabled:

            Dim OWAEnabled As Boolean = False
            ADSearchResult = ADSearch.FindOne()
            If Not IsNothing(ADSearchResult) Then
                Dim UserEntry As DirectoryEntry = ADSearchResult.GetDirectoryEntry
    
                For Each protocolSetting As Object In UserEntry.Properties("protocolSettings")
                    If protocolSetting.ToString.IndexOf("OWA") <> -1 Then
                        If protocolSetting.ToString.Substring(4) = "1" Then
                            OWAEnabled = True
                        End If
                    End If
                Next
            End If


    Paul ~~~~ Microsoft MVP (Visual Basic)

    • Marked as answer by Doug Brewer Thursday, April 5, 2018 2:29 PM
    Thursday, April 5, 2018 11:48 AM

All replies

  • Hi Doug,

    This appears to be either VB6 code which was upgraded at some point to VB.Net, or code which was written by a VB6 developer who wasn't familiar with everything VB.Net can do.

    This code is using late-binding without the Active Directory object model, along with a lot of throw-back VB6 compatibility code so I'm afraid it may be very difficult to assist you without reviewing the entire project (and likely running it in debug mode).

    How much are you willing to modify this code?  Is starting fresh an option?

    You should look into the System.DirectoryServices namespace to perform all of your AD interaction.  It should be relatively easy to retrieve the desired information through the managed objects.

    With what you have now we really don't know what the "GetADProperty()" method is doing or what kind of object it is returning.  We can't tell if the problem is in the comparison or in retrieving the information in the first place (or some combination thereof).


    Reed Kimble - "When you do things right, people won't be sure you've done anything at all"


    Wednesday, April 4, 2018 3:55 PM
    Moderator
  • Thanks Reed for the reply. I agree that it was originally created in VB6. I am using Visual Studio 2017. 

    The code uses the below if it helps. 

    Imports System.DirectoryServices
    Imports System.IO
    Imports System.DirectoryServices.AccountManagement

    Using Root As New DirectoryEntry 'Establish connection to current logged on users Active Directory
    Using Searcher As New DirectorySearcher(Root) 'Start at the top

    Searcher.SearchScope = SearchScope.Subtree 'Start at the top and keep drilling down
    Searcher.PropertiesToLoad.Add("sAMAccountName") 'Load User ID
    Searcher.PropertiesToLoad.Add("displayName") 'Load Display Name
    Searcher.PropertiesToLoad.Add("givenName") 'Load Users first name
    Searcher.PropertiesToLoad.Add("sn")   'Load Users last name
    Searcher.PropertiesToLoad.Add("distinguishedName")   'Users Distinguished 
    Searcher.PropertiesToLoad.Add("ProtocolSettings")   'Users OWA Settings -> I added this.


    etc

    Getting the users OWA status is all that is lacking. Everything else is working so I would really hate having to start fresh being that I am really don't know what coding. I have googled the protocol settings but not finding anything that has helped so that is why I went back to the original code. Again thank you for the reply.

    Wednesday, April 4, 2018 4:12 PM
  • You might want to take a look at the below link. It isn't clear to me whether you are having difficulty parsing the value or if the attribute isn't being found.

    http://arnoutvandervorst.blogspot.com/2008/03/ldap-protocolsettings.html#!/2008/03/ldap-protocolsettings.html


    Paul ~~~~ Microsoft MVP (Visual Basic)

    Wednesday, April 4, 2018 5:13 PM
  • OK, so it is using DirectoryServices.

    It would appear that "Protocol Settings" is not the correct attribute.  In fact, I can't find any attribute that hold the status of OWA activation.  I checked my account on a corporate network with OWA enabled and there is no data set in the ProtocolSettings and none of the other attributes have anything that relates to OWA.

    This information must be stored within Exchange somewhere (or somewhere else in AD), it doesn't appear to be stored in the AD user object.


    Reed Kimble - "When you do things right, people won't be sure you've done anything at all"

    Wednesday, April 4, 2018 5:43 PM
    Moderator
  • Hi Reed

    per this page activedirectoryfaq.com/2015/08/migration-manager-for-exchange-dirsync-protocolsettings/ it is stored in the Active Directory attribute “protocolSettings” of the user account.
    Like Paul said above I don't know if the code is parsing the value or if the attribute isn't being found.

    It is strange that you don't show any value in your corp account though.


    Wednesday, April 4, 2018 5:58 PM
  • Hi Reed

    per this page activedirectoryfaq.com/2015/08/migration-manager-for-exchange-dirsync-protocolsettings/ it is stored in the Active Directory attribute “protocolSettings” of the user account.
    Like Paul said above I don't know if the code is parsing the value or if the attribute isn't being found.

    It is strange that you don't show any value in your corp account though.


    That may be something that 3rd party software (Dell/Quest) put in place, or it may be a legacy value that is no longer used.  I checked on a 2010 sever that has been upgraded since version 2003 and there were no values in that attribute, yet OWA is configured and active.  We did all of the best-practice AD prep work though before each upgrade so it may be that those values were removed during those preparation steps.

    All I can find relating to this is from archived documentation for Exchange 2003: https://msdn.microsoft.com/en-us/library/ms982453(v=exchg.65).aspx

    So perhaps this attribute did at one time hold the information, but it doesn't look like it is used anymore.


    Reed Kimble - "When you do things right, people won't be sure you've done anything at all"

    Wednesday, April 4, 2018 6:22 PM
    Moderator
  • For what its worth, here's a little test routine that you can drop into a new project with one button on a form.  Edit the code as the comments indicate to include your proper domain and user information, then test and see if there are any values at all for the attribute.

    Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
        Dim username As String 'TODO: (set to your username)
        Dim ldap As String = "LDAP://{domain}.{com}/DC={domain},DC={com}" 'TODO: replace all {} with actual values
        Using rootEntry As New DirectoryEntry(ldap, "{DOMAIN}\{adminUsername}", "{adminPassword}") 'TODO: replace all {} with actual values
            Using searcher As New DirectorySearcher(rootEntry)
                searcher.PropertiesToLoad.Add("protocolSettings")
                searcher.Filter = String.Format("(&(samaccountname={0})(objectCategory=person))", username)
                Dim result As SearchResult = searcher.FindOne
                If result IsNot Nothing Then
                    Dim user As DirectoryEntry = result.GetDirectoryEntry
                    Dim protocolProperties = result.Properties("protocolSettings")
                    If protocolProperties.Count > 0 Then
                        MessageBox.Show(String.Join(vbCrLf, From ps In protocolProperties Let s = ps.ToString Select s))
                    Else
                        MessageBox.Show("No Protocol Settings Found")
                    End If
    
                Else
                    Label1.Text = "No Result"
                End If
            End Using
        End Using
    End Sub
    


    Reed Kimble - "When you do things right, people won't be sure you've done anything at all"

    Wednesday, April 4, 2018 6:24 PM
    Moderator
  • Thanks Reed. I guess we are still behind. We are on a hybrid configuration right now O365 Cloud and Exchange 2010. So far looking at the Exchange side settings for OWA and the AD side they are matching up for me. I bet these settings are carried over from an earlier version of Exchange.

    I will try the code you supplied above and let you know what I found.

    Again thank you.

    Wednesday, April 4, 2018 6:44 PM
  • OK, if the values exist in your environment then you should be able to get it going with the proper string comparisons.

    If relevant, I found this blog post which states that "...a lot of OWA configuration settings are stored in FAI items (folder associated items) in a users mailbox using the Configuration Information Protocol Specification documented in http://msdn.microsoft.com/en-us/library/cc463899(EXCHG.80).aspx."


    Reed Kimble - "When you do things right, people won't be sure you've done anything at all"

    Wednesday, April 4, 2018 6:59 PM
    Moderator
  • So working from your .NET example, when I dump out the values to the Output window using the following:

    Console.WriteLine(Searcher.GetDirectoryEntry().Properties.Item("protocolSettings")(0).ToString)
    Console.WriteLine(Searcher.GetDirectoryEntry().Properties.Item("protocolSettings")(1).ToString)

    I see the following (I just see two parts in our configuration):

    HTTP§1§1§§§§§§
    OWA§1

    Which would mean that OWA is enabled. Based upon the previous link can you figure out how to check for that in code or do you still need assistance?


    Paul ~~~~ Microsoft MVP (Visual Basic)

    Wednesday, April 4, 2018 8:19 PM
  • Thanks Paul.

    Yeah I am still having a problem getting the code to return the status for Enabled (True) or Disabled (False). I still can't tell if the code is parsing the value or if the attribute isn't being found. My user has OWA enabled and the AD Attribute shows what you have posted for Enabled but the code in the script is not returning the True/False status.

    I basically need it to read the "ProtocolSettings" attribute, Parse it for HTTP§1 and OWA§1, if it equals §1 the OWAStatus = True Else OWAStatus = False

    I know it is probably something simple that I am missing but I just can't figure it out.

    Any help would greatly be appreciated.

    Wednesday, April 4, 2018 10:53 PM
  • I have got a little closer but no joy...using the below code I get the wrong OWAEnabled status of True for a user that does not have OWA enabled. It reports True always.

    ' Determine if the user has Outlook Webmail Access (OWA)
                Try

                    Dim ATRBList 'Check character next to OWA§ and HTTP§ for 'zero' value 
                    Dim PSettings As String
                    Dim I As Integer
                    Dim OWAEnabled  'Should be True or False status
                    OWAEnabled = True

                    ATRBList = GetADProperty(user, "ProtocolSettings")

                    For Each PSettings In ATRBList

                        I = (PSettings.IndexOf("§", 0, StringComparison.OrdinalIgnoreCase) + 1)
                        If (I <> 0) Then
                            If (PSettings.Substring(0, (I - 1)) = "OWA") Then
                                PSettings = PSettings.Substring((PSettings.Length - (PSettings.Length - I)))
                                If (PSettings.Substring(0, 1) = "0") Then
                                    OWAEnabled = False
                                End If
                            End If

                            If (PSettings.Substring(0, (I - 1)) = "HTTP") Then
                                PSettings = PSettings.Substring((PSettings.Length - (PSettings.Length - I)))
                                If (PSettings.Substring(0, 1) = "0") Then
                                    OWAEnabled = False
                                End If
                            End If
                        End If

                    Next
                    tbOWAEnabled.Text = OWAEnabled
                Catch
                End Try


    Thursday, April 5, 2018 2:25 AM
  • I would just use IndexOf to look for the "OWA" entry and if it is found then get the value of attribute, which would be the fifth character (index of 4) in the string. You can fetch that using Substring if you want.

    There is no need to check for HTTP, but that appears to be one of the conditions you are using to set the OWAEnabled variable. Also, you should initialize the OWAEnabled Boolean variable to False and then set it to True if the OWA entry is found and the fifth character is "1". 

    If you're still having a problem with this I will code an example for you tomorrow morning (CST).


    Paul ~~~~ Microsoft MVP (Visual Basic)

    Thursday, April 5, 2018 3:02 AM
  • Here is the code snippet for parsing the OWA setting to see if it is enabled:

            Dim OWAEnabled As Boolean = False
            ADSearchResult = ADSearch.FindOne()
            If Not IsNothing(ADSearchResult) Then
                Dim UserEntry As DirectoryEntry = ADSearchResult.GetDirectoryEntry
    
                For Each protocolSetting As Object In UserEntry.Properties("protocolSettings")
                    If protocolSetting.ToString.IndexOf("OWA") <> -1 Then
                        If protocolSetting.ToString.Substring(4) = "1" Then
                            OWAEnabled = True
                        End If
                    End If
                Next
            End If


    Paul ~~~~ Microsoft MVP (Visual Basic)

    • Marked as answer by Doug Brewer Thursday, April 5, 2018 2:29 PM
    Thursday, April 5, 2018 11:48 AM
  • Thanks Paul that code snippet did the trick.

    I have a question. If I wanted to check for other ProcotolSettings would I just add the below?

                          If protocolSetting.ToString.IndexOf("IMAP") <> -1 Then
                                If protocolSetting.ToString.Substring(5) = "1" Then
                                    IMAPEnabled = True
                                End If
                            End If
                            If protocolSetting.ToString.IndexOf("POP3") <> -1 Then
                                If protocolSetting.ToString.Substring(5) = "1" Then
                                    POPEnabled = True
                                End If
    Thursday, April 5, 2018 2:29 PM
  • Yes, you can check for each entry in the loop. I think I would use a Select Case statement for that instead of the Ifs and then for each case check to see if the value is 1.

    Select Case True
       Case protocolSetting.ToString.IndexOf("IMAP") <> -1
            '...
       Case protocolSetting.ToString.IndexOf("POP3") <> -1
            '...
       Case protocolSetting.ToString.IndexOf("OWA") <> -1
            '...
    End Select



    Paul ~~~~ Microsoft MVP (Visual Basic)

    Thursday, April 5, 2018 3:20 PM
  • Thanks everyone for all the helpful information. Very much appreciated. I have another question related to this project I am working on but I will post it separately to avoid confusion.

    Friday, April 6, 2018 5:15 PM