none
Read Decimal Value of AD Attribute "msExchRecipientTypeDetails" RRS feed

  • Question

  • I was asked to add a check to our VB.net code to display the Type of Mailbox a user has. I found that the AD attribute "msExchRecipientTypeDetails" holds this information however it is a LargeInteger property type. 

    The code below is what I was attempting to use but it is not returning anything due to the property being a large integer.

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

          Using Root As New DirectoryEntry 'Establish connection to current loged 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

    '

    '

    Dim RecType = GetADProperty(user, "msExchRecipientTypeDetails")
    Searcher.PropertiesToLoad.Add("msExchRecipientTypeDetails") 'Users Recipient Type Status

                Try
                    If RecType = "1" Then
                        lblRecTD.Text = "User Mailbox"
                    End If
                    If RecType = "16" Then
                        lblRecTD.Text = "Room Mailbox"
                    End If
                    If RecType = "64" Then
                        lblRecTD.Text = "Mail Contact"
                    End If
                    If RecType = "128" Then
                        lblRecTD.Text = "Mail User"
                    End If
                    If RecType = "32768" Then
                        lblRecTD.Text = "Cross-Forest Mail Contact"
                    End If
                    If RecType = "2147483648" Then
                        lblRecTD.Text = "Remote Mailbox"
                    End If

    I have googled how to read the value and display the correct Type but so far nothing I have found works.

    Any help would greatly be appreciated.

    Friday, April 6, 2018 5:26 PM

Answers

  • I tested by assigning values to the maxStorage attribute of a test user. maxStorage, how many bytes of storage space the user is allowed, is one of the few Integer8 attributes that can be assigned values by admins. I used the Attribute Editor of ADUC. Using my VBScript code I found that the HighPart method returns 0 for all of the values Doug lists. The LowPart method returns the value specified, except in the case of 2,147,483,648 (without the commas). In the later case, HighPart is still 0, but LowPart is -2,147,483,648. Note that a positive value would exceed the range allowed for Int32. Since LowPart is negative, my code adds 1 to the HighPart, making it 1. Now 1 x 2^32 is 4,294,967,296. Subtract 2,147,483,648 (or add the negative) and you get 2,147,483,648. This is correct.

    So I believe now there are two problems with Paul's code, that only show up in this last case. I see now that the last line of Paul's code is not adding 1 to the HighPart. Instead, the term (UInt32.MaxValue, Int64) is simply 2^32-1, the largest 64-bit integer allowed. So (highPart * (CType(UInt32.MaxValue, Int64) + 1)) is HighPart x 2^32. Paul's code does not account for the case when LowPart is negative. In any case, the second problem is that 2,147,483,648 exceeds the maximum allowed for Int32.

    Edit: I suggest the following VB.

    Dim UserEntry As DirectoryEntry = ADSearchResult.GetDirectoryEntry
    
    Dim adsLargeInteger As Object = UserEntry.Properties("msExchRecipientTypeDetails").Value
    Dim highPart As Int32 = CType(adsLargeInteger.GetType.InvokeMember("HighPart", System.Reflection.BindingFlags.GetProperty, Nothing, adsLargeInteger, Nothing), Int32)
    Dim lowPart As Int32 = CType(adsLargeInteger.GetType.InvokeMember("LowPart", System.Reflection.BindingFlags.GetProperty, Nothing, adsLargeInteger, Nothing), Int32)
    If (lowPart < 0) Then
        highPart = highPart + 1
    End If
    Dim recipientType As Int64 = ((highPart * (CType(UInt32.MaxValue, Int64) + 1)) + lowPart)
    


    Richard Mueller - MVP Enterprise Mobility (Identity and Access)


    Saturday, April 7, 2018 12:49 AM

All replies

  • As you found, the msExchRecipientTypeDetails attribute is LargeInteger (64-bit, or Long in VB), but you are comparing the value to a string. The value "128" is a string, while 128 is integer.

    Richard Mueller - MVP Enterprise Mobility (Identity and Access)


    Friday, April 6, 2018 6:14 PM
  • Thanks Richard. I changed the code but being a newbie at this I am still having problems.

    The lblRecTD.Text is not being returned. Field is blank.

              Dim Value = GetADProperty(user, "msExchRecipientTypeDetails")
              Dim RecType As Int64 = Integer.Parse(Val(Value))

                Try
                    If RecType = 1 Then
                        lblRecTD.Text = "User Mailbox"
                    End If
                    If RecType = 16 Then
                        lblRecTD.Text = "Room Mailbox"
                    End If
                    If RecType = 64 Then
                        lblRecTD.Text = "Mail Contact"
                    End If
                    If RecType = 128 Then
                        lblRecTD.Text = "Mail User"
                    End If
                    If RecType = 32768 Then
                        lblRecTD.Text = "Cross-Forest Mail Contact"
                    End If
                    If RecType = 2147483648 Then
                        lblRecTD.Text = "Remote Mailbox"
                    End If

    Where am I going wrong?


    Friday, April 6, 2018 7:15 PM
  • I changed my code again but still no joy....to make things similar I am remove all but 2 user types until I can get the code working.

    Dim Value = GetADProperty(user, "msExchRecipientTypeDetails")
                Dim RecType As Int64 = Integer.Parse(Val(Value))

                Try

                    If (Integer.TryParse(Value, RecType)) = 1 Then
                        Result = "user Mailbox"
                    End If
                    If (Integer.TryParse(Value, RecType)) = 2147483648 Then
                        Result = "Remote Mailbox"
                    End If

                    lblRecTD.Text = Result

    If I enter a User Mailbox userid Result =64

    If I enter a Remote Mailbox userid Result =128

    Friday, April 6, 2018 9:07 PM
  • The 64-bit values (Integer8) can be a little nasty, but you basically need to split it into the high and low values. Never worked with this attribute before but I tested the following for three different types and it appears to work:

                Dim UserEntry As DirectoryEntry = ADSearchResult.GetDirectoryEntry
    
                Dim adsLargeInteger As Object = UserEntry.Properties("msExchRecipientTypeDetails").Value
                Dim highPart As Int32 = CType(adsLargeInteger.GetType.InvokeMember("HighPart", System.Reflection.BindingFlags.GetProperty, Nothing, adsLargeInteger, Nothing), Int32)
                Dim lowPart As Int32 = CType(adsLargeInteger.GetType.InvokeMember("LowPart", System.Reflection.BindingFlags.GetProperty, Nothing, adsLargeInteger, Nothing), Int32)
                Dim recipientType As Int32 = ((highPart * (CType(UInt32.MaxValue, Int64) + 1)) + lowPart)


    Paul ~~~~ Microsoft MVP (Visual Basic)

    Friday, April 6, 2018 9:20 PM
  • Thanks Paul...that worked with the exception of the "Remote Mailbox" - it is not finding it.

    The attribute is set as 2147483648 but nothing is displayed. Any idea why?

    Friday, April 6, 2018 9:57 PM
  • I have used the HighPart and LowPart methods with success in VBScript, but assumed declaring something Int64 (or Long) in VB would not require it. If it helps, here is how I did it VBScript:

    http://www.rlmueller.net/Integer8Attributes.htm

    The page is for converting AD Integer8 values into dates or intervals of time, but I link this because it handles a bug in the methods when the LowPart is negative. I think that is what Paul is doing in the last statement, but I only add 1 to the HighPart if the LowPart is less than 0. In my code example, my variable lngDuration is all you want, no need to convert into minutes.

    Let us know if Paul's solution doesn't work. It is also possible that the user is not found, or msExchRecipientTypeDetails has no value. You may need to troubleshoot for those possibilities. Maybe just outputting the user's name to be sure you have the user, then just output msExchRecipientTypeDetails to be sure it has a value.

    Also, instead of lots of If statements, you might use a Select Case statement with a Case statement for each possible condition. Then the Case Select finishes as soon as a condition is found, plus you can have a Case Else to handle when none of the conditions are met.

    Edit: Just saw your reply Doug. I believe the issue about adding one to the HighPart only when LowPart is negative might be the problem. Also, your value is 2^31+1, I believe, so Int32 won't work.

    Edit: OK, it's 2^31, but Int32 must be between -2^31 and 2^31-1.


    Richard Mueller - MVP Enterprise Mobility (Identity and Access)




    Friday, April 6, 2018 10:03 PM
  • Thanks Richard!

    my Remote Mailbox user it is valid. All the other data populates and the attribute is set so that is what baffles me. As for the If statements, Paul recommended that to me yesterday on a piece of the code that I was working on but I haven't implemented it yet. I am a newbie trying to update this application since the original coder is no longer with us. I really appreciate all the help and feedback from everyone though.

    Friday, April 6, 2018 10:10 PM
  • Thanks Paul...that worked with the exception of the "Remote Mailbox" - it is not finding it.

    The attribute is set as 2147483648 but nothing is displayed. Any idea why?


    I don't know if I have an object with a Remote Mailbox type  on my system, but based upon the value I may need to change the data types in order to get it to work. I will take a look when I connect back into my work environment.

    Paul ~~~~ Microsoft MVP (Visual Basic)

    Friday, April 6, 2018 10:35 PM
  • I tested by assigning values to the maxStorage attribute of a test user. maxStorage, how many bytes of storage space the user is allowed, is one of the few Integer8 attributes that can be assigned values by admins. I used the Attribute Editor of ADUC. Using my VBScript code I found that the HighPart method returns 0 for all of the values Doug lists. The LowPart method returns the value specified, except in the case of 2,147,483,648 (without the commas). In the later case, HighPart is still 0, but LowPart is -2,147,483,648. Note that a positive value would exceed the range allowed for Int32. Since LowPart is negative, my code adds 1 to the HighPart, making it 1. Now 1 x 2^32 is 4,294,967,296. Subtract 2,147,483,648 (or add the negative) and you get 2,147,483,648. This is correct.

    So I believe now there are two problems with Paul's code, that only show up in this last case. I see now that the last line of Paul's code is not adding 1 to the HighPart. Instead, the term (UInt32.MaxValue, Int64) is simply 2^32-1, the largest 64-bit integer allowed. So (highPart * (CType(UInt32.MaxValue, Int64) + 1)) is HighPart x 2^32. Paul's code does not account for the case when LowPart is negative. In any case, the second problem is that 2,147,483,648 exceeds the maximum allowed for Int32.

    Edit: I suggest the following VB.

    Dim UserEntry As DirectoryEntry = ADSearchResult.GetDirectoryEntry
    
    Dim adsLargeInteger As Object = UserEntry.Properties("msExchRecipientTypeDetails").Value
    Dim highPart As Int32 = CType(adsLargeInteger.GetType.InvokeMember("HighPart", System.Reflection.BindingFlags.GetProperty, Nothing, adsLargeInteger, Nothing), Int32)
    Dim lowPart As Int32 = CType(adsLargeInteger.GetType.InvokeMember("LowPart", System.Reflection.BindingFlags.GetProperty, Nothing, adsLargeInteger, Nothing), Int32)
    If (lowPart < 0) Then
        highPart = highPart + 1
    End If
    Dim recipientType As Int64 = ((highPart * (CType(UInt32.MaxValue, Int64) + 1)) + lowPart)
    


    Richard Mueller - MVP Enterprise Mobility (Identity and Access)


    Saturday, April 7, 2018 12:49 AM
  • Instead of conditions like ‘If RecType = …’ try ‘If RecType And …’, where RecType is Int64 or UInt64.

    For large numbers you can use the L suffix, for example: 2147483648L.

    Saturday, April 7, 2018 3:14 PM
  • Thanks everyone for the help. Richard that last code did the trick. I tested it on all the different accounts and it now shows the correct Mailbox Type.

    Again thank you to everyone for the help. It is very much appreciated!!

    Saturday, April 7, 2018 4:25 PM
  • I'm glad it worked.

    Richard Mueller - MVP Enterprise Mobility (Identity and Access)

    Saturday, April 7, 2018 6:30 PM