How to Set Custom User Mailbox Limits in Exchange 2003 using vbScript

If you inherited an Exchange Server(s) from another Administrator (who died or otherwise), you might find yourself scratching your head or just cussing because of the issues that might have been left behind for you to deal with :)

However, you must understand that they did not intend to leave you those problems (or maybe they did). One of which is that you may find that there are users who do not have mailbox quotas. Of course its bad enough that they don't have quotas, what more if there are hundreds of them? Some of you would say "why not just create a system policy for mailbox size limits?" --- Valid point, but what if these users must have custom mailbox limits and not follow the standard policy for the mail stores?

If there are just 10 of them, I guess modifying the storage limits manually is fine. But again, if there are hundreds or more of these rouge mailboxes it would be best to do the task via script. 




'==========================================================================
'
' NAME: SetCustomMailboxLimits.vbs
'
' AUTHOR: Tito Castillote , june.castillote@gmail.com, shaking-off-the-cobwebs.blogspot.com
' DATE  : 11/12/2012
'
'
' Usage instructions:
' 1. You must create a text file (MailboxLimits.txt) containing the list of user DN (distinguished names)
'     and the storage limits to apply.
'
'        Format: [Distinguished Name]    [Prohibit Send and Receive]    [Prohibit Send]    [Issue Warning]
'        example: CN=Administrator,CN=Users,DC=LabWorks,DC=local    500000    450000    400000
'
'        - the DN and each values must be seperated with a TAB.
'            This script is designed for TAB-delimited Input file.
'
' 2. This script and the Input file must be in the same location and then run this from the Command Prompt.
'     Step 1. Create a backup of existing limits.
'        cscript //nologo SetCustomMailboxLimits.vbs BACKUP
'     Step 2. Modify the limits as found in MailboxLimits.txt
'        cscript //nologo SetCustomMailboxLimits.vbs MODIFY
'    Step 3. Restore the limits from backup (IF NEEDED)
'        cscript //nologo SetCustomMailboxLimits.vbs RESTORE
'
' COMMENT: If you plan to modify a bulk of users, I'd suggest that you do it in batches and not all at once.
'
'========================================================================

'Declare Constants to avoid "Invalid Procedure Calls or Arguments" errors.
Const ADS_PROPERTY_CLEAR = 1, ADS_PROPERTY_UPDATE = 2, ADS_PROPERTY_APPEND = 3
Const ForReading = 1, ForWriting = 2, ForAppending = 8

If WScript.Arguments.Count < 1 Then
    WScript.Echo "Pleas supply the Action (BACKUP or MODIFY)"
ElseIf WScript.Arguments(0)="BACKUP" Then
    WScript.Echo "=================================================="
    WScript.Echo (Now & ": Begin backup of user mailbox limits listed in MailboxLimits.txt")
    CreateBackup
    WScript.Echo (Now & ": Backup is saved to Backup.txt")
    WScript.Echo "=================================================="
ElseIf WScript.Arguments(0)="MODIFY" Then
    WScript.Echo "=================================================="
    WScript.Echo (Now & ": Begin modification of user mailbox limits listed in MailboxLimits.txt")
    ModifyLimits("MailboxLimits.txt")
    WScript.Echo (Now & ": Complete!")
    WScript.Echo "=================================================="
ElseIf WScript.Arguments(0)="RESTORE" Then
    WScript.Echo "=================================================="
    WScript.Echo (Now & ": Begin restoration of user mailbox limits listed in Backup.txt")
    ModifyLimits("Backup.txt")
    WScript.Echo (Now & ": Complete!")
    WScript.Echo "=================================================="
End If

'-----------------Backup Original Values---------------
Sub CreateBackup()

'Create File System Object
Set objFSO = CreateObject("Scripting.FileSystemObject")
Set objFSO1 = CreateObject("Scripting.FileSystemObject")

Set BackUpName = objFSO1.CreateTextFile("Backup.txt",True)
Set MbxName = objFSO.OpenTextFile("MailboxLimits.txt", ForReading)

Do Until MbxName.AtEndofStream
    'Read the current line
    nUser=MbxName.ReadLine
    nuser=Replace(nUser,"/","\/")
   
    'Split the current line into an array with TAB as delimiter
    userArray=Split(nUser, vbTAB)

On Error Resume Next
    'Get the Object with DN name stored in UserArray(0)
    Set objUser = GetObject ("LDAP://" & UserArray(0))
    If Err.Number=0 Then
        'Check if user mailbox exists
        If objUser.homeMDB<>"" then
            'Get information about the Object (User) and start modifying values.
            objUser.GetInfo
           
            'This is just to display which user is being processed.
            WScript.Echo Now & ": Backup limits for - " & objUser.DisplayName
           
            'Write to file
            BackUpName.WriteLine(objUser.DistinguishedName & vbTab & objUser.mDBOverHardQuotaLimit & vbTab & objUser.mDBOverQuotaLimit & vbTab & objUser.mDBStorageQuota)
        Else
            WScript.Echo Now & ": Not an Exchange user - " & objUser.DisplayName
        End If
    Else
        'Set uName = Split(userarray(0),",")
        WScript.Echo Now & ": NOT FOUND!!! - " & userArray(0) 'Replace(uName(0),"CN=","")
        Err.Clear
    End If   
Loop


BackUpName.Close
MbxName.Close
Set BackUpName = Nothing
Set MbxName = Nothing
Set nUser = Nothing
Set userArray = Nothing
Set objFSO = Nothing
Set objFSO1 = Nothing
End Sub
'-----------------End Backup---------------------------


'-----------------Start Modification-------------------

Sub ModifyLimits(strInputFile)
Set objFSO = CreateObject("Scripting.FileSystemObject")
'Open the Input file
Set MbxName = objFSO.OpenTextFile(strInputFile, ForReading)

'Read the inout file from beginning to end
Do Until MbxName.AtEndofStream

    'Read the current line
    nUser=MbxName.ReadLine
    nuser=Replace(nUser,"/","\/")
   
    'Split the current line into an array with TAB as delimiter
    userArray=Split(nUser, vbTAB)

On Error Resume Next
    'Get the Object with DN name stored in UserArray(0)
    Set objUser = GetObject ("LDAP://" & UserArray(0))

    If Err.Number=0 Then
        If objUser.homeMDB<>"" then
            'Get information about the Object (User) and start modifying values.
            objUser.GetInfo
           
            'This is just to display which user is being processed.
            WScript.Echo Now & ": Processing User - " & objUser.DisplayName
       
            'Disable the "User Mailbox Store Defaults"
            objUser.Put "mDBUseDefaults", "FALSE"
           
            If UserArray(3) = "" Then
                objUser.PutEx ADS_PROPERTY_CLEAR, "mDBStorageQuota", 0
            Else
                objUser.Put "mDBStorageQuota", UserArray(3)
            End If
           
            If userArray(2) = "" Then
                objUser.PutEx ADS_PROPERTY_CLEAR, "mDBOverQuotaLimit", 0
            Else
                objUser.Put "mDBOverQuotaLimit", UserArray(2)
            End If
           
            If userArray(1) = "" Then
                objUser.PutEx ADS_PROPERTY_CLEAR, "mDBOverHardQuotaLimit", 0
            Else
                objUser.Put "mDBOverHardQuotaLimit", UserArray(1)
            End If
               
            'Save
            objUser.SetInfo   
        Else
            WScript.Echo Now & ": Not an Exchange user - " & objUser.DisplayName
        End If
    Else
        WScript.Echo Now & ": Not found - " & UserArray(0)
        Err.Clear
    End If   
Loop

'Close the Input file
MbxName.Close

'Clean up
Set objUser = Nothing
Set MbxName = Nothing
Set nUser = Nothing
Set UserArray = Nothing
Set objFSO = Nothing
End Sub
'-----------------End Modification-------------------

Share:

How to Add New EMail Address and Set it as Default in Exchange 2003 using vbScript

Without boring you with the whole story why I had to write this script, it is just because I don't want to open each user account in Active Directory and add new email addresses manually.
I just can't stand that kind of a repetitive job.  With this, I can modify a bulk of users from a list.
The script is well commented so that it'd be easy to understand what each line will do.

'==========================================================================
'
' NAME: AddNewDefaultAddress.vbs
'
' AUTHOR: Tito Castillote , june.castillote@gmail.com, shaking-off-the-cobwebs.blogspot.com
' DATE  : 11/9/2012
'
'
' Usage instructions:
' 1. You must create a text file (Userlist.txt) containing the list of user DN (distinguished names) and the new email address that you want to add and set as default.
'  ex. CN=Administrator,CN=Users,DC=LabWorks,DC=local SMTP:Administrator@email.spam
'    - the DN and Email address must be seperated with a TAB. This script is designed for TAB-delimited Input file.
'
' 2. This script and the Input file must be in the same location and then run this from the Command Prompt.
'  cscript //nologo AddNewDefaultAddress.vbs
'
' COMMENT: If you plan to modify a bulk of users, I'd suggest that you do it in batches and not all at once.
'
'========================================================================

'Declare Constants to avoid "Invalid Procedure Calls or Arguments" errors.
Const ADS_PROPERTY_CLEAR = 1, ADS_PROPERTY_UPDATE = 2, ADS_PROPERTY_APPEND = 3
Const ForReading = 1, ForWriting = 2, ForAppending = 8

'Create File System Object
Set objFSO = CreateObject("Scripting.FileSystemObject") 
'Open the Input file
Set MbxName = objFSO.OpenTextFile("UserList.txt", ForReading) 

'Read the inout file from beginning to end
Do Until MbxName.AtEndofStream 

'Read the current line
nUser=MbxName.ReadLine

'Split the current line into an array with TAB as delimiter
userArray=Split(nUser, vbTab) 

'Get the Object with DN name stored in UserArray(0)
Set objUser = GetObject ("LDAP://" & UserArray(0))

'Get information about the Object (User) and start modifying values.
objUser.GetInfo 

'Assign the ProxyAddress (all email address of the current user) to variable strProxyAddress
strProxyAddress = objUser.GetEx("ProxyAddresses")

'Clear the ProxyAddress of the current user
objUser.PutEx ADS_PROPERTY_CLEAR, "proxyaddresses", 0

'Disable the "Automatically update the e-Mail addresses based on Policy"
objUser.PutEx ADS_PROPERTY_UPDATE, "msExchPoliciesExcluded", Array("{26491CFC-9E50-4857-861B-0CB8DF22B5D7}")

'Save
objUser.SetInfo

'This is just to display which user is being processed.
WScript.Echo "Processing User: " & objUser.DisplayName 

'Loop through the list of email addresses stored in variable strProxyAddress and assign to variable strAddress
For Each strAddress In strProxyAddress 

If strAddress<>UserArray(1) Then ' <--- This is a test to make sure that you are not adding an already existing email address.
'Append the current email address stored in variable strAddress and make sure that it is not set as Default. = Array(replace(strAddress,UCase("SMTP:"),LCase("smtp:"))
objUser.PutEx ADS_PROPERTY_APPEND, "proxyaddresses", Array(replace(strAddress,UCase("SMTP:"),LCase("smtp:")))
'Save
objUser.SetInfo 
End If      
Next

'Append the new email address from the Input File stored in UserArray(1) variable.
objUser.PutEx ADS_PROPERTY_APPEND, "proxyaddresses", Array(UserArray(1))
'Save
objUser.SetInfo
Loop

'Close the Input file
MbxName.Close

'Clean up
Set objUser = Nothing
Set strProxyAddress = Nothing
Set MbxName = Nothing
Set nUser = Nothing
Set UserArray = Nothing



Share:

Export List of User Mailbox with Size information in Lotus Domino

One would think that there is a function in Domino Admin client to export a list of database with their corresponding size information. Well, as simple as the concept might be, there is no built in tool to do just that. If the mailbox quota/size statistics is crucial for your organization for capacity planning or just for record purposes, you can always leverage the LotusScript to export these information.

Note that in this example, it is expected that you are already familiar with using Lotus Notes Designer and LotusScript.

Create the Appplication
1. Create a blank application and place it in your "data" folder.
2. Create a Form and add a Button.







3. Add your code to the Button's click event.

================================
 Sub Click(Source As Button)
    On Error Resume Next
  
    Dim oQuota As Integer
    Dim oWarning As Integer
    Dim oTotal As Integer
    Dim oTotalSize As Double
  
    Dim db As NotesDatabase
    Dim f As Integer
    f = Freefile
    Open "c:\DBlist.txt" For Output As #f
  
    Dim dbdir As New NotesDbDirectory("RSBDOM01/RSBPH")
    Set db = dbdir.GetFirstDatabase(DATABASE)
    Print #f, "Title" & Chr$(9) & "FileName" & Chr$(9) & "Size" & Chr$(9) & "Quota" & Chr$(9) & "Warning"
    While Not(db Is Nothing)
        If Instr(1,db.FilePath,"mail\",5)>0 Then
            Print "Getting Info: " & db.Title
            Print #f, db.Title & Chr$(9) & db.FileName & Chr$(9) & db.Size & Chr$(9) & db.SizeQuota & Chr$(9) & db.SizeWarning
          
            oTotal=oTotal+1
            oTotalSize=oTotalSize+db.size
          
            If db.size/1024 > db.SizeQuota  Then
                oQuota=oQuota+1              
            Elseif db.Size/1024 > db.SizeWarning Then
                oWarning=oWarning+1              
            End If  
        End If  
        Set db = dbdir.GetNextDatabase      
    Wend
    Print "Export Complete"
    Messagebox("Overquota: " & oQuota & Chr$(13) & Chr$(10) & "Warning: " & oWarning & Chr$(13) & Chr$(10) & "Normal: " & oTotal-oQuota-oWarning & Chr$(13) & Chr$(10) &  "Total Mail Files: " & oTotal  & Chr$(13) & Chr$(10) & "Total Size: " & Format(oTotalSize/1024,"Standard") & " KB")
    Close #f
End Sub


================================
4. Create a Frameset and add the Form to one of the Frames.
5. Set the Frameset to show once the Database is opened.
6. Save the Application and name it whatever you want.

Output

It shows the summary in a Message Box:
 

And it saves a text file of the raw data in tabular form which you can use for data manipulation in Excel


Just a simple demonstration of reading database properties using LotusScript
Share:

Camera App/Function is missing after connecting mobile device to Exchange 2010 mailbox

If you connect an iPad, iPhone or any mobile device that supports Exchange ActiveSync to your Exchange 2010 account; you might find that the Camera app/function becomes missing. You're not alone :)

This is because the new Exchange server versions have device-specific restrictions available for ActiveSync. If the email administrator did not change the default Exchange ActiveSync policy, then this will be a familiar scenario.

I will not waste time trying to explain why this particular restriction is enabled with Exchange, let me just tell you how it can be enabled so that everyone can be happy.


  1. Open Exchange Management Console
  2. Go to "Organization Configuration > Client Access"
  3. Select the "Exchange ActiveSync Mailbox Policies" Tab
  4. Select the Policy you wish to edit, in this example it is the "Default".  
  5. Select the "Device" tab and make sure that the "Allow Camera" box is checked.    
  6. Go to the "General" tab and check the "Refresh Interval (hours)" box and put the value of 1.
  7. Click OK.
  8. Restart the "Microsoft Exchange RPC Client Access" service in each Client Access Server.

After all that, recreate the Exchange Account setup in the mobile device to apply the new policy settings.

Good luck!
Share:

Add User or Group as Member of Local Group During User Logon

These two little people at work asked me if I could help them with this script to automatically add a domain user or group to the local administrators group. Just thinking about how they've been trying to do it for weeks already with no success was enough challenge for me; so without really thinking if it would fit in my workload, I agreed to help these little guys.

The assumptions:
  1. Script will run during computer startup.
  2. GPO will be applied to specific computers
I whipped up this script and added it to the Computer Startup section. After testing and verifying that it worked, they suddenly changed their minds.

New requirements:
  1. GPO will NOT be restrictive to any specific computer but;
  2. GPO will NOT be applied to ALL computers. (Should only be applied to a computer if the member user logged on to it)
So I didn't have a choice but to implement the GPO on User Logon which posed another challenge; user logon scripts run under the credentials of the user who logged on.. and if the user don't have local administrator privileges the script will just fail with "access denied" error.

Hitting that wall, the obvious workaround was to use impersonation inside the script which means using an account that have Domain Admin privilege to run the WMI code in the script. That however, is a very bad idea because doing that requires to have the username and password incorporated in the code, the code which is in plain text.

So the new challenge now:
  1. Run the Logon Script with Domain Admin privileges.
  2. The end-product of the code must NOT be in plain-readable-text to protect the account from being compromised.
Encrypting the VBS to VBE is not a very considerable option. Why? Because ever since I started learning VBS, I have decrypted lots of VBE's so that I can study them.. and the Decryption mechanism is always the same.

The only way to go for me is to compile the vbScript into an EXE binary.
This is where PrimalScript came in handy.

THE CODE

'==========================================================================
'
' NAME: AddToLocal.vbs
'
' AUTHOR: June Castillote, june.castillote@gmail.com
' DATE  : 3/22/2012
'
' USAGE: AddToLocal.vbs [Domain Group/User] [Local Group]
'
'==========================================================================
Set objArgs = WScript.Arguments

If objArgs.Length=0 Then WScript.Quit '<--------- font="font" if="if" not="not" run="run" script="script" size="2" will="will">no arguments specific


Const strComputer = "."
Dim objNetwork, objGroup, objUser, strUsername, strGroupName
Set objNetwork = WScript.CreateObject("WScript.Network")
strGroupName = CStr(objArgs(0))
Set objGroup = GetObject("WinNT://" & strComputer & "/" & cstr(objArgs(1)))
Set objUser = GetObject("WinNT://" & strGroupName)
If (objGroup.IsMember(objUser.ADsPath) = False) Then
    objGroup.Add(objUser.ADsPath)
    MsgBox    "Your account/group " & CStr(objArgs(0)) & " has been added to the Local " & cstr(objArgs(1)) & " Group. Please logout and log back in for the privileges to take effect"
Else
    MsgBox    "Your account/group " & CStr(objArgs(0)) & " is already a member of the Local " & cstr(objArgs(1)) & " Group. No further actions needed."
End If 

'========================================================================== 


COMPILE USING PRIMALSCRIPT

  



Enter the account that is already a member of the Local Administrator (usually a domain admin account) the the script will use as "Run As" credential



APPLY TO GPO

You should know how to do that!

OUTPUT








If the user logged in on that computer is not a member of the local group yet, the script will trigger and will see the message box below.



If the Account/Group is already added to the local group, the message box below will appear.


PrimalScript is a commercial software however, if you do not want to use this option of compiling to EXE, you can just modify the script to include the Username and Password in the WMI string - which exposes your the credentials in plain text.




 
Share:

Popular Posts

Powered by Blogger.