[Webinar] Learn how to a build a cloud-first strategyRegister Now

x
  • Status: Solved
  • Priority: Medium
  • Security: Public
  • Views: 1107
  • Last Modified:

Count Mailboxes in Exchange 2000

Is there any way i can count how many mailboxes i have got and size if possible on my two exchange server 2000.

I have got 4 storage groups and one store in each storage group on both servers. Thanks
0
tech2010
Asked:
tech2010
  • 6
  • 4
1 Solution
 
Chris DentPowerShell DeveloperCommented:

Alas neither of those will work. The more useful parts of the WMI interface for Exchange were only introduced with Exchange 2003. For Exchange 2000 you would have to use MAPI to get sizes of individual mailboxes.

I have a script that does that here:

http://www.highorbit.co.uk/?p=618

It's been a long time since I had a chance to test it. I hope it still works!

Chris
0
 
tech2010Author Commented:
Hi florin_s, I had already seen the link. That script only works with Exchange 2003.

Chris-Dent, I am not intresting in Size. I want to know how many mailboxes i have on my exchange 2000.
0
Get your Conversational Ransomware Defense e‑book

This e-book gives you an insight into the ransomware threat and reviews the fundamentals of top-notch ransomware preparedness and recovery. To help you protect yourself and your organization. The initial infection may be inevitable, so the best protection is to be fully prepared.

 
Chris DentPowerShell DeveloperCommented:

That simplifies things. You're better using LDAP queries against Active Directory to find that.

Each user account which has a mailbox has a few attributes that can be used to identify it. If you're interested in "per store" then we want to arrange them by the homeMDB attribute.

I think PowerShell would still give us the quickest way to get this information without having to bother about lots of VbScript for searching AD. If you're happy with that, could you grab PowerShell from here:

http://www.microsoft.com/windowsserver2003/technologies/management/powershell/default.mspx

And the Quest Cmdlets from here (also free):

http://www.quest.com/activeroles-server/arms.aspx

Once we have those, we can start with:

$Users = Get-QADUser -IncludedProperties homeMDB -LdapFilter "(homeMDB=*)" | Select-Object Name, DistinguishedName, homeMDB

That means that all users across all stores (and all servers) is given by:

$Users.Count

Would you want a count per store or per server as well? It's pretty easy to pull out of the data we have in $Users.

Chris
0
 
tech2010Author Commented:
I would like count per store and per server. Thanks
0
 
Chris DentPowerShell DeveloperCommented:

Fair enough. Can we give this a try? See if it's what you're after.

It'll need to be run as an Exchange Admin, only admins have access to the parts of the Exchange tree it hooks into to grab the owning server for a store. There are other ways if that's not desirable, this just saves us trying to rip it out of the homeMDB string.

Chris
$Users = Get-QADUser -IncludedProperties homeMDB -LdapFilter "(homeMDB=*)" | Select-Object Name, DN, homeMDB
$homeMDBValues = $Users | Select-Object homeMDB -Unique
$Stores = @(); $homeMDBValues | %{ 
  $Stores += Get-QADObject $_.homemdb -IncludedProperties msExchOwningServer | `
    Select-Object Name, @{n='Server';e={ (Get-QADObject $_.msExchOwningServer).Name }}, `
      @{n='homeMDB';e={ $_.distinguishedName }}
}
$Temp = @()
ForEach ($User in $Users) {
  $Store = $Stores | ?{ $_.homeMDB -eq $User.homeMDB }
  $Temp += $Store | Select-Object @{n='UserName';e={ $User.Name }}, @{n='UserDN';e={ $User.DN }}, `
    Name, Server
}
$Users = $Temp
 
# Total User Count
Write-Host "Total: $($Users.Count)"
 
# Count per server
ForEach ($Server in ($Users | Select-Object Server -Unique)) {
  Write-Host "$($Server.Server): $(($Users | ?{ $_.Server -eq $Server.Server }).Count)" }
 
# Count per store
ForEach ($Store in ($Users | Select-Object Name -Unique)) {
  Write-Host "$($Store.Name): $(($Users | ?{ $_.Name -eq $Store.Name }).Count)" }

Open in new window

0
 
tech2010Author Commented:
I am bit carefull to use this script on my production exchange.
0
 
Chris DentPowerShell DeveloperCommented:

It only reads information, no writing in there. It only actually needs read access to the Exchange configuration tree, a View Only Admin is likely to be enough if that makes it a bit more comfortable.

Chris
0
 
Chris DentPowerShell DeveloperCommented:

Here you go, a modification that rips apart the homeMDB string to return the same thing. Can be run with a regular user account, only needs read access to AD (which a regular user will have).

Chris
$Users = Get-QADUser -IncludedProperties homeMDB -LdapFilter "(homeMDB=*)" | Select-Object Name, DN, homeMDB
$Temp = @()
$Users | %{
  $HomeMDB = ($_.HomeMDB).Split("=")
  $Store = $HomeMDB[1].SubString(0, $HomeMDB[1].LastIndexOf(","))
  $Server = $HomeMDB[4].SubString(0, $HomeMDB[4].LastIndexOf(","))
  $Temp += $_ | Select-Object Name, DN, @{n='Store';e={ $Store }}, @{n='Server';e={ $Server }}
}
$Users = $Temp
 
# Total User Count
Write-Host "Total: $($Users.Count)"
 
# Count per server
ForEach ($Server in ($Users | Select-Object Server -Unique)) {
  Write-Host "$($Server.Server): $(($Users | ?{ $_.Server -eq $Server.Server }).Count)" }
 
# Count per store
ForEach ($Store in ($Users | Select-Object Store -Unique)) {
  Write-Host "$($Store.Store): $(($Users | ?{ $_.Store -eq $Store.Store }).Count)" }

Open in new window

0
 
tech2010Author Commented:
what exactly this script will do?
0
 
Chris DentPowerShell DeveloperCommented:

Probably easiest if I explain it with the code in-line.

First, it asks Active Directory for a list of users that have homeMDB (a microsoft exchange store value) set. We also need to get Get-QADUser to return the homeMDB attribute along with everything else (using the -IncludedProperties option), it doesn't include that one by default.

This step requires read access to Active Directory. All domain users have that because "Authenticated Users" can read the from AD by default.

$Users = Get-QADUser -IncludedProperties homeMDB -LdapFilter "(homeMDB=*)"

Once it has the users, it sorts through them pulling only information that I considered interesting for the processing of this script. That includes the users Name, their Distinguished Name (because Name is not Unique) and the store they have a mailbox in (homeMDB).

 | Select-Object Name, DN, homeMDB

We're done with AD now, we have the information we need, everything else is just about sorting through it. This is what our list looks like so far:

Name             DN                                                      homeMDB
Chris Dent     CN=Chris Dent,OU=somewhere ...     CN=MailboxDB Name,CN=SG4,CN=InformationStore ....

This command simply creates a new empty array, we're going to store information in it.

$Temp = @()

Now we take the information we returned about the users (held in the computers memory as $Users), and loop through it (% is an Alias for ForEach-Object, that's where it starts the loop).

$Users | %{

For each of the users it grabs the value of HomeMDB, splits it into an array based on the = symbol.

  $HomeMDB = ($_.HomeMDB).Split("=")

If you were to look at the string, and start counting through (from 0) you would find that the Store Name is right after the first =, and that the server name is right after the 4th. We want that value, and because we start from 0 we want the 1st and 4th elements in the array.

  $Store = $HomeMDB[1].SubString(0, $HomeMDB[1].LastIndexOf(","))
  $Server = $HomeMDB[4].SubString(0, $HomeMDB[4].LastIndexOf(","))

For example, this is a homeMDB string:

CN=MailboxDB Name,CN=SG4,CN=InformationStore,CN=ExchangeServer01,CN=Servers,CN=Exchange Administrative Group (LKJFDS98234),CN=Administrative Groups,CN=Org Name,CN=Microsoft Exchange,CN=Services,CN=Configuration,DC=domain,DC=com

It just picks out "MailboxDB Name" and "ExchangeServer01" from that long string.

Next it adds to the $Temp array with the new, more friendly values we've found.

  $Temp += $_ | Select-Object Name, DN, @{n='Store';e={ $Store }}, @{n='Server';e={ $Server }}
}

Finally, it overwrites the original user list (in memory) with the updated on.

$Users = $Temp

Now our list looks like this:

Name             DN                                                      Store                       Server
Chris Dent     CN=Chris Dent,OU=somewhere ...     MailboxDB Name      ExchangeServer01

You can write the entire list out to a CSV file and open it in Excel if you like with:

$Users | Export-CSV "SomeFile.csv"

Moving on with the script. This writes out the total number of users we found when we searched AD. That number will be all mail enabled users in the Exchange System.

Write-Host "Total: $($Users.Count)"

The per server count is a bit different. Fist it pulls a list of unique server names from the user list.

ForEach ($Server in ($Users | Select-Object Server -Unique)) {

For each of the servers, it makes a list of the users who have that Server set, and returns a count (Write-Host writes to the screen).

  Write-Host "$($Server.Server): $(($Users | ?{ $_.Server -eq $Server.Server }).Count)" }

Now it does the same for the stores. Gets a list of stores from our $Users list.

ForEach ($Store in ($Users | Select-Object Store -Unique)) {

Then for each of the stores in the list it returns a list of users in that store and counts them.

  Write-Host "$($Store.Store): $(($Users | ?{ $_.Store -eq $Store.Store }).Count)" }

The shorter version is that it will read a few things from AD (requiring no special permissions) and write a few things out to the screen. It does not need to run on the Exchange server, you can run it on any PC that can access AD (any member of the domain). Personally I suggest installing PowerShell and running it from your own machine.

Chris
0

Featured Post

 [eBook] Windows Nano Server

Download this FREE eBook and learn all you need to get started with Windows Nano Server, including deployment options, remote management
and troubleshooting tips and tricks

  • 6
  • 4
Tackle projects and never again get stuck behind a technical roadblock.
Join Now