In my last job, I was responsible for our exchange-environment (Exchange
2007), where we've had a lot of users with HUGE mailboxes. They kept
requesting new/adjusted limits all the time, so instead of 'wasting' our
'engineers-time' for all the requests, we've came up with a pretty nice
solution; we've handed this task over to our 1st level support, but
without giving them access to the exchange-environment. I instead wrote
a script, that applies predefined limits according to the
'Customattribute15' (CA15) in Activedirectory.
The Script
[cc lang="powershell" lines="-1"]
#########################################################
# Author: Raphael Hoegger
# Source: http://pfuender.net/?p=156
# License: This file is licensed under the GPL v2.
# Latest change: 2010.01.12 09:10:58 CEST
# Version: 1.05
#########################################################
## VARIABLES
\$logfile="log.txt"
## empty logfile
remove-item \$logfile
new-item -itemtype file -path \$logfile >\$null
\$Error.Clear()
## FUNCTION -- Apply pre-defined limits
Function apply_limits (\$mailbox){
switch (\$mailbox.Customattribute15) {
## 1.5GB limit
10 {
\$lim_warn = "1350MB"
\$lim_noS = "1500MB"
\$lim_noSR = "1650MB"
\$lim_dbdef= \$false
}
## 3.0GB limit
20 {
\$lim_warn = "2700MB"
\$lim_noS = "3000MB"
\$lim_noSR = "3300MB"
\$lim_dbdef= \$false
}
## 4.5GB limit
30 {
\$lim_warn = "4500MB"
\$lim_noS = "5000MB"
\$lim_noSR = "5500MB"
\$lim_dbdef= \$false
}
## 5.5GB limit
40 {
\$lim_warn = "5000MB"
\$lim_noS = "5500MB"
\$lim_noSR = "6000MB"
\$lim_dbdef= \$false
}
## DB default limit -- for those who don't have the CA15 set
default {
\$lim_warn = "unlimited"
\$lim_noS = "unlimited"
\$lim_noSR = "unlimited"
\$lim_dbdef= \$true
}
}
## Check for inconsistencies between ADS/Exchange and the proposed
values of the CA15
## log-changes + adjust accordingly
## Adjust issuewarningquota
if (\$mailbox.issuewarningquota -ne \$lim_warn)
{
\$temp = \$mailbox.issuewarningquota.value
echo "\$mailbox --- Adjusting-Warning: \$temp --new \$lim_warn"
>> \$logfile
\$mailbox | Set-Mailbox -IssueWarningQuota \$lim_warn
}
## Adjust Prohibitsend
if (\$mailbox.ProhibitsendQuota -ne \$lim_noS)
{
\$temp = \$mailbox.Prohibitsendquota.value
echo "\$mailbox --- Adjusting-NoSend: \$temp --new \$lim_noS" >>
\$logfile
\$mailbox | Set-Mailbox -Prohibitsendquota \$lim_noS
}
## Adjust Prohibitsendreceivee
if (\$mailbox.ProhibitsendReceiveQuota -ne \$lim_noSR)
{
\$temp = \$mailbox.prohibitsendreceivequota.value
echo "\$mailbox --- Adjusting-NoSendReceive: \$temp --new \$lim_noSR"
>> \$logfile
\$mailbox | Set-Mailbox -ProhibitsendReceivequota \$lim_noSR
}
## Adjust the 'usedatabasequotadefaults'
if (\$mailbox.usedatabasequotadefaults.tostring() -ne
\$lim_dbdef.tostring())
{
\$temp = \$mailbox.usedatabasequotadefaults.tostring()
echo "\$mailbox --- Adjusting-usedbdefaults: \$temp --new \$lim_dbdef"
>> \$logfile
\$mailbox | Set-Mailbox -UseDatabaseQuotaDefaults \$lim_dbdef
}
}
\$databases = Get-Mailboxdatabase | select identity
foreach (\$database in \$databases) {
switch -regex (\$database.Identity) {
## Process all databases of Switzerland
"Switzerland [a-z]" {
## cache mailboxes
\$mailboxes = Get-Mailbox -resultsize unlimited -database
\$database.identity
## Apply the limits
foreach (\$mailbox in \$mailboxes) { apply_limits(\$mailbox) }
}
## Process all Swedish databases
"Sweden [a-z]" {
## cache mailboxes
\$mailboxes = Get-Mailbox -resultsize unlimited -database
\$database.identity
## Apply the limits
foreach (\$mailbox in \$mailboxes) { apply_limits(\$mailbox) }
}
}
}
## Check for errors and append them to the log if there are some
if (\$Error.Count -gt 0)
{
echo "" >> \$logfile
echo "Errors occurred, please check below:" >> \$logfile
\$error.tostring() >> \$logfile
}
else
{
echo "" >> \$logfile
echo "No Errors occurred." >> \$logfile
}
## Generate a mail with the LOG
\$date = Get-Date -uFormat %Y.%m.%d
\$FromAddress = "admin@domain.com"
\$ToAddress = "admin@domain.com"
\$MessageSubject = "Exchange Limit Adjustments - \$date"
## generate mail-body
\$MessageBody = "Hello Exchange-Admins,`r`n`r`nFind below the
adjustments that have been made to the
Mailboxes:`r`n------------------------`r`n"
foreach (\$line in (cat log.txt)) { \$Messagebody += "\$line`r`n" }
\$MessageBody += "`r`n------------------------`r`nPlease note, this
script runs daily on server XXX at 23:00 CET"
\$SendingServer = "smtp.domain.com"
\$SMTPMessage = New-Object System.Net.Mail.MailMessage \$FromAddress,
\$ToAddress, \$MessageSubject, \$MessageBody
\$SMTPMessage.to.add("user_1@domain.com") ## Add extra recipients
\$SMTPMessage.to.add("user_2@domain.com") ## Add extra recipients
##Send the message
\$SMTPClient = New-Object System.Net.Mail.SMTPClient \$SendingServer
\$SMTPClient.Send(\$SMTPMessage)
[/cc]
Explanation
If you're in a rush, skip this part and continue reading on the next
chapter...
There's no magic in the script, so don't be afraid to play with it!
...but please do so in your lab, and not your prod-environment :-p
The lines 17 - 59, define the limits, which will get applied. You can
simply copy one of these blocks and adjust it to your limits. I've used
here increments of 10, so I can always insert a new limit between the
existing ones, without renumbering the existing ones. From line 20 to 26
is such a block, so if you want to create a new limit, copy it, and
change your three warning-levels to whatever fits in your environment.
Lines 52-57 is a bit special. It's setting the default limit, that every
user should have (empty CA15 field). This will reset the three
warning-levels, but enable the use of the 'database quota defaults',
which of course must be set, else they won't have a limit at all.
The block from 61 until 94 is checking the current mailbox-limit and the proposed value (according to CA15). If the values are different, log it, and do the neccessary changes.
From line 96 until 118, it's gathering the neccessary information about your mailbox-dataabases. Once this is done, it'll check if there are rules for each one of them and apply the limits as discussed previously. I've used Switzerland and Sweden as examples. As you can see on both of them (line 101/110), it's using regular expressiosn, so you a db called 'switzerland a' will be processed, as well as a 'switzerland f'. To add a new db, just copy and modify lines 100-107.
And finally 121-150 is generating the email. No further comment, should be selfexplaining (else just ask).
How to run?
So to quickly sum it up, you need the following to get this script to work:
- Some modified CustomAttribute15 in ADS
- A modified script - Create your own limits (lines 17-59) - Adjust it according to your db-naming conventions (lines 96-118) - Modify the from/to/subject/smtp-server for the logs (lines 121-150)
- A machine with Powershell installed to run it (can also be an exchange server)
- optional; a scheduled task to run it on a daily base
Further notes
If you've just made some modifications, and you want to do a 'dry-run', just comment-out the lines containing 'set-mailbox' (lines 68, 76, 84, 92) as well as the final mail (line 150).
Thanks for reading! Questions..? use the comments below.. ;-)
Cheers,
Raphi