' This code safely modifies a bit-flag attribute ' ------ SCRIPT CONFIGURATION ------ strObject = "<ObjectDN>
" ' e.g. cn=jsmith,cn=users,dc=rallencorp,dc=com strAttr = "<AttrName>
" ' e.g. rallencorp-UserProperties boolEnableBit =<TRUEorFALSE>
' e.g. FALSE intBit =<BitValue>
' e.g. 16 ' ------ END CONFIGURATION --------- set objObject = GetObject("LDAP://" & strObject) intBitsOrig = objObject.Get(strAttr) intBitsCalc = CalcBit(intBitsOrig, intBit, boolEnableBit) if intBitsOrig <> intBitsCalc then objObject.Put strAttr, intBitsCalc objObject.SetInfo WScript.Echo "Changed " & strAttr & " from " & intBitsOrig & " to " & intBitsCalc else WScript.Echo "Did not need to change " & strAttr & " (" & intBitsOrig & ")" end if Function CalcBit(intValue, intBit, boolEnable) CalcBit = intValue if boolEnable = TRUE then CalcBit = intValue Or intBit else if intValue And intBit then CalcBit = intValue Xor intBit end if end if End Function
In Recipe 4.9, I described how to search
against attributes that contain a bit flag, which are used to encode
various settings about an object in a single attribute. As a quick
recap, you need to use a logical OR operation to match any bits being
searched against, and logical AND to match a specific set of bits. If
you want to set an attribute that is a bit flag, you need to take
special precautions to ensure you don’t overwrite an
existing bit. Let’s consider an example. RAllenCorp
wants to secretly store some non-politically correct information
about its users, including things like whether the user is really old
or has big feet. They don’t want to create
attributes such as rallencorp-UserHasBigFeet
so
they decide to encode the properties in a single bit flag attribute.
They decide to call the attribute
rallencorp-UserProperties
with the following
possible bit values:
- 1
User is overweight
- 2
User is very tall
- 4
User has big feet
- 8
User is very old
After they extend the schema to include the new attribute, they need
to initially populate the attribute for all their users. To do so
they can simply logically OR the values together that apply to each
user. So if settings 4 and 8 apply to the jsmith user, his
rallencorp-UserProperties
would be set to 12 (4 OR
8). No big deal so far. The issue comes in when they need to modify
the attribute in the future.
They later find out that the jsmith user was a former basketball
player and is 6’8”. They need to set the 2 bit (for being tall) in
his rallencorp-UserProperties
attribute. To set
the 2 bit they need to first determine if it has already been set. If
it has already been set, then there is nothing to do. If the 2 bit
hasn’t been set, they need to logical OR 2 with the
existing value of jsmith’s
rallencorp-UserProperties
attribute. If they
simply set the attribute to 2, it would overwrite the 4 and 8 bits
that had been set previously. In the VBScript solution, they could
use the CalcBit
function to determine the new
value:
intBitsCalc = CalcBit(intBitsOrig, 2, TRUE)
The result would be 14 (12 OR 2).
The same logic applies if they want to remove a bit, except the XOR logical operator is used.
Warning
Active Directory contains numerous bit-flag attributes, most notably
options
(which is used on several different object
classes) and userAccountControl
(which is used on
user
objects). I do not recommended blindly
setting those attributes unless you know what you are doing. It is
preferable to use a script from this recipe so that it calculates the
new value based on the
existing value.
Recipe 4.9 for searching with a bit-wise filter
Get Active Directory Cookbook now with the O’Reilly learning platform.
O’Reilly members experience books, live events, courses curated by job role, and more from O’Reilly and nearly 200 top publishers.