A question came up on powershellcommunity.org:
”Hi guys,
I’ve been blindsided by the General Manager and need to get a list of all our Mailboxes, as well as the smtp addresses attached to them.
I need these to be pumped out per OU (we have a lot) so that I can do costings per OU.
So basically, I need to get a list of mailboxes (with all smtp addresses) per OU, exported to a csv file
I don’t mind running the same command multiple times, just changing the OU name. But not sure how to do this!
Can anyone help?”
As the original poster did not provide information on his Exchange version, I created a script for Exchange 2007 and one for Exchange 2010.
Exchange 2010 has the shiny new “Get-OrganizationalUnit” cmdlet, which works pretty much as implied.
With Exchange 2007, and no fancy AD cmdlets from Quest or Microsoft, you have to roll your own in an ADSI call
So, for Exchange 2007, I did this:
001
002 003 004 005 006 007 008 009 010 011 012 013 014 015 016 017 |
function Get-OU
{ $search = [System.DirectoryServices.DirectorySearcher]([adsi]“”) $search.Filter = “(objectClass=organizationalUnit)” $ounames = $search.Findall() return $ounames } $AllMailboxes = @() foreach ($ou in Get-OU) { $AllMailboxes += Get-Mailbox -OrganizationalUnit $ou.Properties.distinguishedname[0]` -ResultSize Unlimited |Select-Object OrganizationalUnit,` DisplayName,PrimarySmtpAddress, @{Name=“EmailAddresses”` ;Expression={$_.EmailAddresses |Where-Object ` {$_.PrefixString -eq “smtp”} | ForEach-Object {$_.SmtpAddress}}} } $AllMailboxes |Export-Csv c:\test.csv -NoTypeInformation |
For Exchange 2010:
001
002 003 004 005 006 007 008 009 010 |
$AllMailboxes = @()
foreach ($ou in Get-OrganizationalUnit) { $AllMailboxes += Get-Mailbox -OrganizationalUnit $ou.DistinguishedName` -ResultSize Unlimited |Select-Object OrganizationalUnit,` DisplayName,PrimarySmtpAddress, @{Name=“EmailAddresses”` ;Expression={$_.EmailAddresses |Where-Object ` {$_.PrefixString -ceq “smtp”} | ForEach-Object {$_.SmtpAddress}}} } $AllMailboxes |Export-Csv c:\test.csv -NoTypeInformation |
#1 by Jim on October 17, 2010 - 17:06
Just a note because many miss how these guys are designed amd defaulted:
This:
$search = [System.DirectoryServices.DirectorySearcher]([adsi]“”)
$search.Filter = “(objectClass=organizationalUnit)”
$ounames = $search.Findall()
Can be done easier like this:
$ounames =([adsisearcher]“objectClass=organizationalUnit").Findall()
The type accellerator defaults to teh current domain and if only one string is persent it assumes that it is the filter string. We can paren this and use it to eliminate any temporary variables. Remembering how this works makes it very typable and eliminates the need for a function to be loaded in advance.
Very nice suggestion on teh mainboxes by OU.
#2 by karlmitschke on October 18, 2010 - 13:55
Thanks, Jim!
I did not know of the [adsisearcher] type accelerator until now.
#3 by Raymond Dales on December 31, 2010 - 08:41
I tried running the script for Exchange 2007 to get the OUs and got the following error.
Any ideas?
At :line:12 char:2
+ -R <<<< esultSize Unlimited |Select-Object OrganizationalUnit,`
Missing expression after unary operator '-'.
At :line:12 char:2
+ -R <<<< esultSize Unlimited |Select-Object OrganizationalUnit,`
#4 by Karl Mitschke on December 31, 2010 - 18:58
Hello;
Lines 11, 12, 13, 14, and 15 are one long line.
#5 by Ed Wilkinson on February 8, 2011 - 19:07
Hi,
Is it possible to add the Size of the mailbox for each user to this?
Thanks
Ed
#6 by Karl Mitschke on February 9, 2011 - 08:48
Ed;
This should work for 2007 (Replace lines 11.12.13.14.15)
$AllMailboxes += Get-Mailbox -OrganizationalUnit $ou.Properties.distinguishedname[0] `
-ResultSize Unlimited |Select-Object OrganizationalUnit, DisplayName,PrimarySmtpAddress, `
@{Name=”EmailAddresses”Expression={$_.EmailAddresses `
|Where-Object {$_.PrefixString -eq “smtp”} `
| ForEach-Object {$_.SmtpAddress}}}},@{Name=”Total Size” ;Expression=`
{(Get-MailboxStatistics $_.DistinguishedName |Select-Object TotalItemSize).TotalItemSize}}
For 2010 (replace line 4,5,6,7,8)
$AllMailboxes += Get-Mailbox -OrganizationalUnit $ou.DistinguishedName -ResultSize Unlimited `
|Select-Object OrganizationalUnit,DisplayName,PrimarySmtpAddress, `
@{Name=”EmailAddresses”;Expression={$_.EmailAddresses `
|Where-Object {$_.PrefixString -ceq “smtp”} `
| ForEach-Object {$_.SmtpAddress}}},@{Name=”Total Size” ;Expression=`
{(Get-MailboxStatistics $_.DistinguishedName |Select-Object TotalItemSize).TotalItemSize}}
}
#7 by Rod on August 22, 2012 - 05:29
Sorry but I don’t get it to work on 2010
I just copy paste the code, saved it to a .ps1 file and executed it in EMS and get this
Missing expression after unary operator ‘-‘.
At D:\scripts\distinguishedname.ps1:5 char:2
+ – <<<< ResultSize Unlimited |Select-Object OrganizationalUnit,`
+ CategoryInfo : ParserError: (-:String) [], ParseException
+ FullyQualifiedErrorId : MissingExpressionAfterOperator
What am I doing wrong?
Thanks
#8 by Karl Mitschke on August 22, 2012 - 09:03
There is an unfortunate space at the end of each line of the pasted code.
If you remove the trailing space from each line, the code should work.
Karl
#9 by Bob Wang on November 8, 2012 - 20:56
Hi Karl,
the script didn’t seem to be working with exchange 2010 sp2, wonder if any code need to be changed.
thanks in advance,
Bob
#10 by Karl Mitschke on November 19, 2012 - 11:15
Try changing lines 4, 5,6,7,and 8 as follows:
4) $AllMailboxes += Get-Mailbox -OrganizationalUnit $ou.DistinguishedName -ResultSize Unlimited |
5) Select-Object OrganizationalUnit,
6) DisplayName,PrimarySmtpAddress, @{Name=“EmailAddresses”
7) ;Expression={$_.EmailAddresses |Where-Object `
8) {$_.PrefixString -ceq “smtp”} | ForEach-Object {$_.SmtpAddress}}}
Or, make it one line (remove the ` characters)
Karl