Managing Exchange Federations with VBScript
Recently, I've been discussing a problem I am working with a federated customer that involves mailbox storage limits. I've described the problem in previous posts, as well as some potential ways to audit delegated administrations that have set overrides on mailbox size for their users. This post uses a similar mechanism, but does so with VBScript, instead of the standard administration tools.
This script will output all users that are in violation of the policy by checking to see whether the mDBUseDefaults attribute on a mail-enabled user has been set to TRUE. That indicates that they have cleared the Use Mailbox Store Defaults checkbox on the Storage Limits dialog box from the Exchange General tab of user properties.
By default, if we find a match, we output the actual override settings to the command line (please note that if you execute such a script from the windows shell, instead of the cScript command, you'll get a message box for each match). In addition, I added some code to look for a specific argument passed to the script ("/C"). If present, the script will actually clear the override values and reset the Use Mailbox Store Defaults checkbox to checked.
Of course, the script could be further modified with another override (such as checking an extensionAttribute) so that if you do have users approved by the central authority to have overrides set, you can put a value into one of those fields and use an IF/Then to exclude them from the change behavior.
Const ADS_PROPERTY_CLEAR = 1
Const ADS_PROPERTY_UPDATE = 2
Const ADS_PROPERTY_APPEND = 3
Const ADS_PROPERTY_DELETE = 4
DIM rootDSE '*** In a Generic Implementation, the RootDSE finds the current domain
DIM DomainContainer '*** Used to define the domain we attach to
DIM conn '*** connection object to attach to Active Directory
DIM ldapStr '*** specify the LDAP Query String
DIM rs '*** recordset object for looping through results
DIM users '*** Specifies a counter for users processed
DIM FoundObject '*** Variable used when iterating the recordset
DIM Args '*** Variable to Hold Arguments
DIM CFlag '*** Change Flag (Argument 1)
DIM ClearedFlag '*** Yes/No used to display Output to administrator
'*** Get the default naming context
Set rootDSE = GetObject("LDAP://RootDSE")
DomainContainer = rootDSE.Get("defaultNamingContext")
'*** Set Variable defaults and grab any arguments, if they exist
'/// DomainContainer = "DC=yourDomain,DC=com" '*** Change this if you need to hard-code the domain name
Users = 0
'*** Check for the /C Argument. That will determine if we reset the accounts to default
Set Args = wScript.Arguments
If Args.Count > 0 Then CFlag = Args(0)
'*** Create a connection to the Active Directory Database
Set conn = CreateObject("ADODB.Connection")
conn.Provider = "ADSDSOObject"
conn.Open "ADs Provider"
'*** Build a customized LDAP Query String
ldapStr = "<LDAP://" & DomainContainer & ">;(&(objectClass=user)(mDBUseDefaults=FALSE));adspath;subtree"
'*** Execute the LDAP Query
Set rs = conn.Execute(ldapStr)
'*** Loop through the recordset returned
While Not rs.EOF
Set FoundObject = GetObject (rs.Fields(0).Value)
Users = Users + 1
'*** Now, modify the settings
If CFlag = "/C" Then
FoundObject.mDBUseDefaults = TRUE
FoundObject.putEx ADS_PROPERTY_CLEAR, "mDBStorageQuota", 0
FoundObject.putEx ADS_PROPERTY_CLEAR, "mDBOverQuotaLimit", 0
FoundObject.putEx ADS_PROPERTY_CLEAR, "mDBOverHardQuotaLimit", 0
Wscript.Echo FoundObject.cn & chr(9) & ": Reset to Use Defaults"
Wscript.Echo FoundObject.cn & " (Warning/Send/Receive Limits): " & FoundObject.mDBStorageQuota & ", " & FoundObject.mDBOverQuotaLimit & ", " & FoundObject.mDBOverHardQuotaLimit
'*** Output total number of users processed
WScript.Echo "Total User Matches Found: " & Users