{"id":245,"date":"2015-06-17T14:34:13","date_gmt":"2015-06-17T13:34:13","guid":{"rendered":"http:\/\/blogs.kent.ac.uk\/unseenit\/?p=245"},"modified":"2015-06-17T14:34:13","modified_gmt":"2015-06-17T13:34:13","slug":"managing-ad-boolean-in-integer-flagsets-with-fim","status":"publish","type":"post","link":"https:\/\/blogs.kent.ac.uk\/unseenit\/managing-ad-boolean-in-integer-flagsets-with-fim\/","title":{"rendered":"Managing AD boolean-in-integer flagsets with FIM"},"content":{"rendered":"<p>Active Directory, for reasons best known to itself, stores many boolean attributes (such as <a href=\"https:\/\/support.microsoft.com\/en-us\/kb\/305144\">userAccountControl<\/a>\u00a0or <a href=\"https:\/\/justtinkering.wordpress.com\/2011\/07\/14\/active-directory-user-msexchelcmailboxflags-attributes-shows-if-in-exchange-2010-retention-hold-is-enabled\/\">msExchELCMailboxFlags<\/a>) together in an aggregate integer rather than separating them into individual attributes.<\/p>\n<p>This presents a problem when manipulating only\u00a0part of that data while preserving the rest.<\/p>\n<p>For example, to\u00a0disable a user&#8217;s account, you must set the userAccountControl<b>\u00a0<\/b>attribute to 0x0202 (0x002 + 0x0200). Which, in decimal, is 514 (2 + 512).<\/p>\n<p>Doing this sort of arithmetic is fine if you know what all the flags should be. If, however, you only want to flip one of them (for example to activate an\u00a0Archive Mailbox\u00a0on a user while preserving the Litigation Hold flag), you need to be a bit more subtle.<\/p>\n<p>I&#8217;m going to start with a little helper function which we use in FIM to manage the msExchELCMailboxFlags attribute:<\/p>\n<pre>Private Function BitwiseSet(flagset As Integer, pos As Integer, value As Boolean) As Integer\r\n   pos = 2 ^ (pos - 1)\r\n   If value Then\r\n      Return flagset Or pos\r\n   Else\r\n      Return flagset And Not pos\r\n   End If\r\nEnd Function<\/pre>\n<p>This function takes an existing integer to work on, an offset for the flag (least significant bit is 1 rather than 0) and a boolean (true\/false) of what that bit should be set to. For example, to set\u00a0ElcV2 (2) and\u00a0ValidArchiveDatabase and (32) both to true, enabling the archive mailbox) we&#8217;d call:<\/p>\n<pre>    BitwiseSet(msExchELCMailboxFlags, 2, True)\r\n    BitwiseSet(msExchELCMailboxFlags, 6, True)<\/pre>\n<p>Tying that in to FIM&#8217;s export attribute flow API (MapAttributesForExport), this ends up looking like:<\/p>\n<pre>Public Sub MapAttributesForExport _\r\n   (ByVal FlowRuleName As String, ByVal mventry As MVEntry, ByVal csentry As CSEntry) _\r\n   Implements IMASynchronization.MapAttributesForExport\r\n Select Case FlowRuleName\r\n Case \"export:msExchELCMailboxFlags\"\r\n    'Const ExpirationSuspended As Integer = 1\r\n    Const ElcV2 As Integer = 2\r\n    'Const DisableCalendarLogging As Integer = 3\r\n    'Const LitigationHold As Integer = 4\r\n    'Const SingleItemRecovert As Integer = 5\r\n    Const ValidArchiveDatabase As Integer = 6\r\n\r\n    Dim msExchELCMailboxFlags As Integer\r\n    If csentry(\"msExchELCMailboxFlags\").IsPresent Then\r\n       msExchELCMailboxFlags = csObject._msExchELCMailboxFlags.Value\r\n    Else\r\n       msExchELCMailboxFlags = 0 ' Nothing\r\n    End If\r\n\r\n    If isMailboxUser(mvObject) Then\r\n       msExchELCMailboxFlags = _\r\n           BitwiseSet(msExchELCMailboxFlags, ElcV2, True)\r\n       msExchELCMailboxFlags = _\r\n           BitwiseSet(msExchELCMailboxFlags, ValidArchiveDatabase, True)\r\n    Else\r\n       msExchELCMailboxFlags = _\r\n           BitwiseSet(msExchELCMailboxFlags, ElcV2, False)\r\n       msExchELCMailboxFlags = _\r\n           BitwiseSet(msExchELCMailboxFlags, ValidArchiveDatabase, False)\r\n    End If\r\n\r\n    If msExchELCMailboxFlags = 0 Then\r\n       If csentry(\"msExchELCMailboxFlags\").IsPresent Then\r\n          csentry(\"msExchELCMailboxFlags\").Delete()\r\n       End If\r\n    Else\r\n       csentry(\"msExchELCMailboxFlags\").Value = msExchELCMailboxFlags\r\n    End If\r\n Case Else\r\n    Throw New UnexpectedDataException(String.Format(\"MapAttributesForExport: Unknown flow rule '{0}'\", FlowRuleName))\r\n End Select\r\nEnd Sub\r\n<\/pre>\n","protected":false},"excerpt":{"rendered":"<p>Active Directory, for reasons best known to itself, stores many boolean attributes (such as userAccountControl\u00a0or msExchELCMailboxFlags) together in an aggregate integer rather than separating them &hellip; <a href=\"https:\/\/blogs.kent.ac.uk\/unseenit\/managing-ad-boolean-in-integer-flagsets-with-fim\/\">Read&nbsp;more<\/a><\/p>\n","protected":false},"author":13,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":[],"categories":[28943],"tags":[28975,28976,28968,28969,28970,28944,28945,28972,28973,28974,28971],"_links":{"self":[{"href":"https:\/\/blogs.kent.ac.uk\/unseenit\/wp-json\/wp\/v2\/posts\/245"}],"collection":[{"href":"https:\/\/blogs.kent.ac.uk\/unseenit\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/blogs.kent.ac.uk\/unseenit\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/blogs.kent.ac.uk\/unseenit\/wp-json\/wp\/v2\/users\/13"}],"replies":[{"embeddable":true,"href":"https:\/\/blogs.kent.ac.uk\/unseenit\/wp-json\/wp\/v2\/comments?post=245"}],"version-history":[{"count":6,"href":"https:\/\/blogs.kent.ac.uk\/unseenit\/wp-json\/wp\/v2\/posts\/245\/revisions"}],"predecessor-version":[{"id":251,"href":"https:\/\/blogs.kent.ac.uk\/unseenit\/wp-json\/wp\/v2\/posts\/245\/revisions\/251"}],"wp:attachment":[{"href":"https:\/\/blogs.kent.ac.uk\/unseenit\/wp-json\/wp\/v2\/media?parent=245"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/blogs.kent.ac.uk\/unseenit\/wp-json\/wp\/v2\/categories?post=245"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/blogs.kent.ac.uk\/unseenit\/wp-json\/wp\/v2\/tags?post=245"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}