Link to home
Start Free TrialLog in
Avatar of feldmans
feldmans

asked on

How can I view the Mailbox Size of users across multiple Exchange Servers

How can I view the Mailbox Size of users across multiple Exchange Servers? I am trying to write a VBScript that will show me the mailbox size of a specific user based on his/her logon name. I have written the script to provide basic information, but I am having trouble getting the mailbox size to view properly. It currently shows the mailbox size as 0.00 MB. I am attaching the code of the current script. Any help would be very much appreciated. I am removing company specific information for security purposes.

-----------------------------

 On Error Resume Next

 Dim k, strExitOut, strStartThisThing
 Dim Rs, Conn, Com, objUser, objOU
 Dim strInputUserAccount, strIsThisTheRightAccount
 Dim strPulledDN, strPulledDisplayName, strPulledAccountName
 Dim strInfoToSetOnUserAccount
 
'************************
'*  Enter Logon ID
'************************
 
 Do Until strIsThisTheRightAccount = 7
 strInputUserAccount = ""
 strInputUserAccount = Inputbox("Enter the logon account name of the user you want to Mailbox information", "Enter User Name", "{Enter Logon ID Here}")
    If strInputUserAccount = "" or strInputUserAccount = " " or strInputUserAccount = "{Enter Logon ID Here}" Then
       strDoYouWantToQuit = MsgBox("You must enter a valid Logon ID to the domain." & vbCRLF & "Do you want to try again?", vbYesNo, "Try Again?")
       If strDoYouWantToQuit = 7 Then
          WScript.Quit
       End If
       strInputUserAccount = "NotSet"
    End If
   
'****************************
'*   Pull Account Info
'****************************  

Set Conn = CreateObject("ADODB.Connection")
   Set Com = CreateObject("ADODB.Command")
   Conn.Provider = "ADsDSOObject"
   Conn.Open "ADsDSOObject"
   Set Com.ActiveConnection = Conn
   Com.CommandText = "Select samAccountName,distinguishedName FROM 'LDAP://DC=%Path to Domain Controller%' WHERE objectClass = 'User' AND samAccountName ='" & strInputUserAccount & "'"
          Com.Properties("Page Size") = 5000
       Set Rs = Com.Execute
          Rs.MoveFirst
          Set objUser = GetObject("LDAP://" & Rs.Fields("distinguishedName"))
                strPulledDisplayName = objUser.Get("displayname")
                strPulledAccountName = objUser.Get("samAccountName")
          Set mbox = GetObject(strwmicon)
                mbsize = mbox.size
                        mbsize = formatnumber(mbsize/1024,2)
   
           
'***************************
'*  Query Exchange Info
'***************************

Select Case UCase(Left(objUser.sn,1))
  Case "A", "B", "C", "D"
    strMailServer = "%Mail Server 1%"
  Case "E", "F", "G", "H", "I"
    strMailServer = "%Mail Server 2%"
  Case "J", "K", "L", "M"
    strMailServer = "%Mail Server 3%"
  Case "N", "O", "P", "Q", "R"
    strMailServer = "%Mail Server 4%"
  Case "S", "T", "U", "V", "W", "X", "Y", "Z"
    strMailServer = "%Mail Server 5%"
  Case Else
    'Do Nothing
End Select

  strE2K3WMIQuery = "winmgmts://" & strMailServer &_
    "/root/MicrosoftExchangeV2"
           
'***************************
'*  Show Account Info
'***************************

    strIsThisTheRightAccount = MsgBox("Do you want to view another account?" & vbCRLF & vbCRLF & _
       "User Name" & vbTab & strPulledDisplayName & vbCRLF & _
       "Exchange Server" & vbTab &strMailServer & vbCRLF & _
       "Mailbox Size" & vbTab & mbsize & " MB", vbYesNo, "View Another Account?")
       
    If strIsThisTheRightAccount = 7 Then
       WScript.Quit
    End If
       
'***********************
'*  End of Loop
'***********************

   strPulledDisplayName = ""
   strPulledAccountName = ""
   strPulledMailboxSize = ""
   objUser = ""
   Loop
   
WScript.Quit

-----------------------------

Thanks for all the help you can provide.

Seth
Avatar of RobSampson
RobSampson
Flag of Australia image

There's a section on this page about retrieving a mailbox size:
http://www.msexchange.org/articles/Scripting-Exchange-VBScript-ADSI-Part3.html
and also various methods here:
http://support.microsoft.com/kb/320071

See if they give you any ideas.

Rob.
Avatar of feldmans
feldmans

ASKER

I got one of the scripts on the support.microsoft.com website to work, and provide me the info requested, but it has to be run from the command line with arguments (exchange server and logon name). I want to provide this to our companies helpdesk, and some of them are not too computer savvy. I was wondering how I might be able to have it prompt for a logon name, and it would query the exchange server that user is on, and then provide the mailbox size. Trying to make it understandable for all levels of helpdesk employees. Thanks for all the help.

The script on http://support.microsoft.com/kb/320071 that I found to work is:
--------------------
'This script logs on to a server that is running Exchange Server and
'displays the current number of bytes that are used in the user's
'mailbox and the number of messages.

' USAGE: cscript MailboxSize.vbs SERVERNAME MAILBOXNAME

' This requires that CDO 1.21 is installed on the computer.
' This script is provided AS IS. It is intended as a SAMPLE only.
' Microsoft offers no warranty or support for this script.  
' Use at your own risk.

' Get command line arguments.
Dim obArgs
Dim cArgs

Set obArgs = WScript.Arguments
cArgs = obArgs.Count

Main

Sub Main()
   Dim oSession
   Dim oInfoStores
   Dim oInfoStore
   Dim StorageUsed
   Dim NumMessages
   Dim strProfileInfo
   Dim sMsg

   On Error Resume Next

   If cArgs <> 2 Then
      WScript.Echo "Usage: cscript MailboxSize.vbs SERVERNAME MAILBOXNAME"
      Exit Sub
   End If

   'Create Session object.
   Set oSession = CreateObject("MAPI.Session")
   if Err.Number <> 0 Then
      sMsg = "Error creating MAPI.Session."
      sMsg = sMsg & "Make sure CDO 1.21 is installed. "
      sMsg = sMsg & Err.Number & " " & Err.Description
      WScript.Echo sMsg
      Exit Sub
   End If
   
   strProfileInfo = obArgs.Item(0) & vbLf & obArgs.Item(1)

   'Log on.
   oSession.Logon , , False, True, , True, strProfileInfo
   if Err.Number <> 0 Then
      sMsg = "Error logging on: "
      sMsg = sMsg & Err.Number & " " & Err.Description
      WScript.Echo sMsg
      WScript.Echo "Server: " & obArgs.Item(0)
      WScript.Echo "Mailbox: " & obArgs.Item(1)
      Set oSession = Nothing
      Exit Sub
   End If

   'Grab the information stores.
   Set oInfoStores = oSession.InfoStores
   if Err.Number <> 0 Then

      sMsg = "Error retrieving InfoStores Collection: "
      sMsg = sMsg & Err.Number & " " & Err.Description
      WScript.Echo sMsg
      WScript.Echo "Server: " & obArgs.Item(0)
      WScript.Echo "Mailbox: " & obArgs.Item(1)
      Set oInfoStores = Nothing
      Set oSession = Nothing
      Exit Sub
   End If
   
   'Loop through information stores to find the user's mailbox.
   For Each oInfoStore In oInfoStores
      If InStr(1, oInfoStore.Name, "Mailbox - ", 1) <> 0 Then
         '&HE080003 = PR_MESSAGE_SIZE
         StorageUsed = oInfoStore.Fields(&HE080003)
         if Err.Number <> 0 Then
            sMsg = "Error retrieving PR_MESSAGE_SIZE: "
            sMsg = sMsg & Err.Number & " " & Err.Description
            WScript.Echo sMsg
            WScript.Echo "Server: " & obArgs.Item(0)
            WScript.Echo "Mailbox: " & obArgs.Item(1)
            Set oInfoStore = Nothing
            Set oInfoStores = Nothing
            Set oSession = Nothing
            Exit Sub
         End If
         
         '&H33020003 = PR_CONTENT_COUNT
         NumMessages = oInfoStore.Fields(&H36020003)

         if Err.Number <> 0 Then

            sMsg = "Error Retrieving PR_CONTENT_COUNT: "
            sMsg = sMsg & Err.Number & " " & Err.Description
            WScript.Echo sMsg
            WScript.Echo "Server: " & obArgs.Item(0)
            WScript.Echo "Mailbox: " & obArgs.Item(1)
            Set oInfoStore = Nothing
            Set oInfoStores = Nothing
            Set oSession = Nothing
            Exit Sub
         End If
         
         StorageUsed = formatnumber(StorageUsed/1048576,2)

         sMsg = "Storage Used in " & oInfoStore.Name
         sMsg = sMsg & " (bytes): " & StorageUsed
         msgBox("User Name: " & vbTab & oInfoStore.Name & vbCRLF & _
                "Mailbox Size: " & vbTab & StorageUsed & " MB" & vbCRLF & _
                "# of Messages: " & vbTab & NumMessages)
         End If
   Next

   ' Log off.
   oSession.Logoff

   ' Clean up memory.
   Set oInfoStore = Nothing
   Set oInfoStores = Nothing
   Set oSession = Nothing
End Sub
--------------------
Looking at this script, I cant really tell where it gets the information from the exchange server. Any ideas on how I can use this general idea to prompt me for the logon name, and it would query the server?

Thanks,
Seth
You could write a vbs that prompts for these details, and then runs the
cscript MailboxSize.vbs SERVERNAME MAILBOXNAME
command.
'=====================
' GetMailboxSize.vbs
strServer = InputBox("Server", "What is the server name?")
strMailboxName = InputBox("Mailbox Name", "What is the Mailbox name?")
It IsNull(strServer) = False And IsNull(strMailboxName) = False Then
   Set wshShell = CreateObject("Wscript.Shell")
   wshShell.Exec "CScript MailboxSize.vbs " & strServer & " " & strMailboxName
Else
   MsgBox "You didn't enter a server name or mailbox name"
End If
'====================

That way, you can leave the MS script as is, and just use this script as an "interface" to it, and then this script calls the CScript.  The programs output would still be from the MailboxSize.vbs file, so you'd have to modify that to suit, but at least you've got the functionality.

Regards,

Rob.
That may work. Our users have to provide secondary credentials when accessing AD and Exchange. Would it work the same way? I was going to put the script into an executable and have them perform an 'Run As' on the .exe file to login with their privileged accounts. Would this work with the  privileged accounts as well? If not, I need to come up with something else.
You could incorporate Run As into this to run cscript with alternate credentials, if I understand you correctly.
'=====================
' GetMailboxSize.vbs
strAltUsername = InputBox("Alternate Username", "What is the alternate username to run under?")
strServer = InputBox("Server", "What is the server name?")
strMailboxName = InputBox("Mailbox Name", "What is the Mailbox name?")
It IsNull(strServer) = False And IsNull(strMailboxName) = False And IsNull(strAltUsername) = FalseThen
   Set wshShell = CreateObject("Wscript.Shell")
   wshShell.Run "runas /user:" & strAltUsername & " CScript MailboxSize.vbs " & strServer & " " & strMailboxName, 1, True
Else
   MsgBox "You didn't enter a server name or mailbox name or alternate username."
End If
'====================

Then the Dos prompt would appear prompting for the password (that's the way Run As works) and it would then run the cscript command.

Regards,

Rob.
I have modified it a little bit so that they can right-click and select 'Run As...' and enter their priveliged account. The script works, but it takes like 20 seconds to run properly. While this does work, I am trying to make something that works a little quicker. If you have any ideas on how I can speed up the process a little bit, it would be very much appreciated. Otherwise, I will provide points accordingly.

'=====================
' GetMailboxSize.vbs
strServer = "%domain%"
strMailboxName = InputBox("Mailbox Name", "What is the Mailbox name?")
If IsNull(strServer) = False And IsNull(strMailboxName) = False Then
   Set wshShell = CreateObject("Wscript.Shell")
   wshShell.Exec "CScript \\%computername%\Stuff\Scripts\MBSize.vbs " & strServer & " " & strMailboxName
Else
   MsgBox "You didn't enter a server name or mailbox name"
End If
'====================

This is what I have so far. If there is any way to create the script without requiring it to locate another file, but to run it all from the single file?

Thanks,
Seth
You should be able to incorporate the code you have above into the top of the original MBSize.vbs script, and still use run as on that script.  If you have trouble with this, I'll look at it tomorrow and help you.

Regards,

Rob.
If there were a way to manipulate the script from MS to incorporate specifically defined variables as the arguments, then that would be all I need. Thanks for all the help.

Seth
Seth,

Here it is, all in one script....hopefully that runs faster fo you:
'======================
'This script logs on to a server that is running Exchange Server and
'displays the current number of bytes that are used in the user's
'mailbox and the number of messages.

' USAGE: cscript MailboxSize.vbs SERVERNAME MAILBOXNAME

' This requires that CDO 1.21 is installed on the computer.
' This script is provided AS IS. It is intended as a SAMPLE only.
' Microsoft offers no warranty or support for this script.  
' Use at your own risk.

' Get command line arguments.
'Dim obArgs
'Dim cArgs

'Set obArgs = WScript.Arguments
'cArgs = obArgs.Count

'=====================
' Used to be in GetMailboxSize.vbs
strServer = "DOMAINNAME"
strMailboxName = InputBox("Mailbox Name", "What is the Mailbox name?")
If IsNull(strServer) = True And IsNull(strMailboxName) = True Then
   MsgBox "You didn't enter a server name or mailbox name"
   WScript.Quit
End If
'====================

Main

Sub Main()
   Dim oSession
   Dim oInfoStores
   Dim oInfoStore
   Dim StorageUsed
   Dim NumMessages
   Dim strProfileInfo
   Dim sMsg

   On Error Resume Next

   'If cArgs <> 2 Then
   '   WScript.Echo "Usage: cscript MailboxSize.vbs SERVERNAME MAILBOXNAME"
   '   Exit Sub
   'End If

   'Create Session object.
   Set oSession = CreateObject("MAPI.Session")
   if Err.Number <> 0 Then
      sMsg = "Error creating MAPI.Session."
      sMsg = sMsg & "Make sure CDO 1.21 is installed. "
      sMsg = sMsg & Err.Number & " " & Err.Description
      WScript.Echo sMsg
      Exit Sub
   End If
   
   strProfileInfo = strServer & vbLf & strMailboxName

   'Log on.
   oSession.Logon , , False, True, , True, strProfileInfo
   if Err.Number <> 0 Then
      sMsg = "Error logging on: "
      sMsg = sMsg & Err.Number & " " & Err.Description
      WScript.Echo sMsg
      WScript.Echo "Server: " & strServer
      WScript.Echo "Mailbox: " & strMailboxName
      Set oSession = Nothing
      Exit Sub
   End If

   'Grab the information stores.
   Set oInfoStores = oSession.InfoStores
   if Err.Number <> 0 Then

      sMsg = "Error retrieving InfoStores Collection: "
      sMsg = sMsg & Err.Number & " " & Err.Description
      WScript.Echo sMsg
      WScript.Echo "Server: " & strServer
      WScript.Echo "Mailbox: " & strMailboxName
      Set oInfoStores = Nothing
      Set oSession = Nothing
      Exit Sub
   End If
   
   'Loop through information stores to find the user's mailbox.
   For Each oInfoStore In oInfoStores
      If InStr(1, oInfoStore.Name, "Mailbox - ", 1) <> 0 Then
         '&HE080003 = PR_MESSAGE_SIZE
         StorageUsed = oInfoStore.Fields(&HE080003)
         if Err.Number <> 0 Then
            sMsg = "Error retrieving PR_MESSAGE_SIZE: "
            sMsg = sMsg & Err.Number & " " & Err.Description
            WScript.Echo sMsg
            WScript.Echo "Server: " & strServer
            WScript.Echo "Mailbox: " & strMailboxName
            Set oInfoStore = Nothing
            Set oInfoStores = Nothing
            Set oSession = Nothing
            Exit Sub
         End If
         
         '&H33020003 = PR_CONTENT_COUNT
         NumMessages = oInfoStore.Fields(&H36020003)

         if Err.Number <> 0 Then

            sMsg = "Error Retrieving PR_CONTENT_COUNT: "
            sMsg = sMsg & Err.Number & " " & Err.Description
            WScript.Echo sMsg
            WScript.Echo "Server: " & strServer
            WScript.Echo "Mailbox: " & strMailboxName
            Set oInfoStore = Nothing
            Set oInfoStores = Nothing
            Set oSession = Nothing
            Exit Sub
         End If
         
         StorageUsed = formatnumber(StorageUsed/1048576,2)

         sMsg = "Storage Used in " & oInfoStore.Name
         sMsg = sMsg & " (bytes): " & StorageUsed
         msgBox("User Name: " & vbTab & oInfoStore.Name & vbCRLF & _
                "Mailbox Size: " & vbTab & StorageUsed & " MB" & vbCRLF & _
                "# of Messages: " & vbTab & NumMessages)
         End If
   Next

   ' Log off.
   oSession.Logoff

   ' Clean up memory.
   Set oInfoStore = Nothing
   Set oInfoStores = Nothing
   Set oSession = Nothing
   
   MsgBox "Finished"
End Sub
'======================

Regards,

Rob.
Thanks, that worked perfectly for what I was going for. One last final question. I am now looking to get it to not close the script when it completes, but rather ask if they want to view another account, and if they select Yes, go back to the top and ask them for the mailbox name again, but if they select No, it closes the script. I was thinking something kinda like this.

'=====================
' Used to be in GetMailboxSize.vbs
Do Until strViewAccount = 7
strServer = "DOMAINNAME"
strMailboxName = InputBox("Mailbox Name", "What is the Mailbox name?")
If IsNull(strServer) = True And IsNull(strMailboxName) = True Then
   MsgBox "You didn't enter a server name or mailbox name"
   WScript.Quit
End If
'====================

Code logging into mailbox and checking sizes of mailboxes.

sMsg = "Storage Used in " & oInfoStore.Name
         sMsg = sMsg & " (bytes): " & StorageUsed
         strViewAccount = MsgBox("Do You Want To View Another Account?" & vbCRLF & vbCRLF & _
                "User Name: " & vbTab & oInfoStore.Name & vbCRLF & _
                "Mailbox Size: " & vbTab & StorageUsed & " MB" & vbCRLF & _
                "# of Messages: " & vbTab & NumMessages, vbYesNo, "View Another Account?")

      If strViewAccount = 7 Then
              WScript.Quit
      End If
         End If

Something like that. Let me know if you think that would work. I have tried it out, and I get a syntax error on Sub Main(). Any ideas?
ASKER CERTIFIED SOLUTION
Avatar of RobSampson
RobSampson
Flag of Australia image

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
Thats perfect. Thanks for all the help, you really saved me here.

Seth
No problem.  Glad I could help. Thanks for your patience.

Rob.