#MSExchange
So SteveM showed me this a while back, and yeah I know I am at the back of the queue, but boy is this a pain in the butt!
So I want to set some standard stuff when you run New-MailboxDatabase. Standard properties are kinda simple, but i discovered that AD Replication, even in a small environment can break the scripting agent, especially when you want to set AD Permissions on a mailbox. Powershell rocks, but it runs so fast that AD just doesn’t update quick enough!. [So when is Exchange going to break out from the AD and go back to it’s own directory like the good olde days?]
So, the resolution was to add a function that checks to see if the cmdlet value was actually set. It checks 60 times (60 seconds) then exits the loop.
So here is my current ScriptingAgentConfig.xml
<?xml version="1.0" encoding="utf-8" ?>
<Configuration version="1.0">
<!--
NAME: ScriptingAgentConfig.xml
AUTHOR: Paul Flaherty
Last Edit: v1.0 [24 July 2012]
ScriptingAgentConfig.xml uses the Exchange Server 2010 Scritpting Agent Cmdlet Extension.
It allows additional configuration to take place when certain Exchange 2010 cmdlets are executed.
Feature: NewMailboxDatabase
The portion of code runs after New-MailboxDatabase and sets a number of things:
- Removes all the database limits
- Sets deleted items and mailbox retention limits to 31 days
- Assigned Send-As, Receive-As and ms-Exch-Store-Admin rights
The Function Check-AdReplications is used to ensure the AD object changes have taken place
OUTPUT from the script is stored in C:PSScriptingAgent_New-MailboxDatabase_<datetime>.txt
-->
<Feature Name="NewMailboxDatabase" Cmdlets="New-MailboxDatabase">
<ApiCall Name="OnComplete">
If ($Succeeded) {
$xNow = Get-Date -format "yyyy-MM-dd_HH_mm_ss"
$tmpOutFile = "C:PSScriptingAgent_" + $provisioningHandler.TaskName + "_" + $xNow + ".txt"
$NewDatabase = $provisioningHandler.UserSpecifiedParameters["Name"]
$OriginatingDC = "abc123"
Function Check-ADReplication([String]$incmdlet){
#This functions takes an cmdlet string as a parameter and uses it to check if the result of the cmdlet
#is not NULL. However, after 60 attempts (Approx 60 seconds) the function with exit.
"Check-ADReplication" >> $tmpOutFile
$incmdlet = $incmdlet.replace("##","_.")
$incmdlet >> $tmpoutfile
#Loop round 30 times
For($i=0; $i -le 60; $i++ ){
$now = Get-Date
"Check $i" >> $tmpOutFile
$now >> $tmpOutFile
#Invoke the incoming cmdlet
$tmpExpression = Invoke-Expression $incmdlet #get-MailboxDatabase $NewDatabase -DomainController $OriginatingDC
If ($tmpExpression -eq $null){
#if the result is null, sleep for 1 second and loop
"Null" >> $tmpOutFile; Start-Sleep 1
}ELSE{
#If the result is NOT null, set the look to exit
#On first run, extect the Domain Controller for later use
"OK" >> $tmpOutFile;
IF($script:OriginatingDC -eq "abc123"){$script:OriginatingDC = $tmpExpression.originatingserver}
$i=99;
}#IF
}#For
} #Function
#Write stuff out
$now = Get-Date
$now >> $tmpOutFile
"ScriptingAgent[NewMailboxDatabase]" >> $tmpOutFile
$provisioningHandler >> $tmpOutFile
$provisioningHandler.Userscope | fl >> $tmpOutFile
$readOnlyIConfigurable >> $tmpoutfile
"Mailbox Database: $NewDatabase" >> $tmpOutFile
#Check if the database has replicated to the AD yet
$cmdlet2Check = "get-MailboxDatabase " + $NewDatabase
Check-ADReplication $cmdlet2Check
$OriginatingDC >> $tmpOutFile
#Remove database limits
"-Remove database limits" >> $tmpOutFile
Get-MailboxDatabase $NewDatabase | Set-MailboxDatabase -ProhibitSendReceiveQuota 'unlimited' -ProhibitSendQuota 'unlimited' -IssueWarningQuota 'unlimited' -RecoverableItemsQuota 'unlimited' -RecoverableItemsWarningQuota 'unlimited' -DomainController $OriginatingDC
$cmdlet2Check = "get-MailboxDatabase " + $NewDatabase + " -DomainController " + $OriginatingDC + " | Where{$##ProhibitSendReceiveQuota -eq 'unlimited'}"
Check-ADReplication $cmdlet2Check
#Set Deleted items retention
"-Set Deleted items retention" >> $tmpOutFile
Get-MailboxDatabase $NewDatabase | Set-MailboxDatabase -DeletedItemRetention 31 -MailboxRetention 31 -DomainController $OriginatingDC
$cmdlet2Check = "get-MailboxDatabase " + $NewDatabase + " -DomainController " + $OriginatingDC + " | Where{$##DeletedItemRetention -eq 31}"
Check-ADReplication $cmdlet2Check
"-Set AD Permissions" >> $tmpOutFile
$cmdlet2Check = "get-MailboxDatabase " + $NewDatabase + " -DomainController " + $OriginatingDC + " | Get-AdPermission | Where{$##User -like '*Organization Management'}"
Check-ADReplication $cmdlet2Check
#Groups Names for the permissions
$SendAs = "UG_MGT_msExchSendAs"
$ReceiveAs = "UG_MGT_msExchReceiveAs"
$StoreAdmin = "UG_MGT_msExchStoreAdmin"
#Grant the above groups the required rights
Get-MailboxDatabase $NewDatabase | Add-ADPermission -user $SendAs -AccessRights extendedright -ExtendedRight Send-As -DomainController $OriginatingDC
Get-MailboxDatabase $NewDatabase | Add-ADPermission -user $ReceiveAs -AccessRights extendedright -ExtendedRight Receive-As -DomainController $OriginatingDC
Get-MailboxDatabase $NewDatabase | Add-ADPermission -user $StoreAdmin -AccessRights extendedright -ExtendedRight ms-Exch-Store-Admin -DomainController $OriginatingDC
}
</ApiCall>
</Feature>
</Configuration>
.csharpcode, .csharpcode pre { font-size: small; color: black; font-family: consolas, “Courier New”, courier, monospace; background-color: #ffffff; /*white-space: pre;*/ } .csharpcode pre { margin: 0em; } .csharpcode .rem { color: #008000; } .csharpcode .kwrd { color: #0000ff; } .csharpcode .str { color: #006080; } .csharpcode .op { color: #0000c0; } .csharpcode .preproc { color: #cc6633; } .csharpcode .asp { background-color: #ffff00; } .csharpcode .html { color: #800000; } .csharpcode .attr { color: #ff0000; } .csharpcode .alt { background-color: #f4f4f4; width: 100%; margin: 0em; } .csharpcode .lnum { color: #606060; }
if you want more then check these out:
- http://technet.microsoft.com/en-us/library/dd335067
- http://technet.microsoft.com/en-us/library/dd297951
- http://technet.microsoft.com/en-us/library/dd298143
- http://www.proexchange.be/blogs/exchange2010/archive/2011/08/31/using-the-scripting-agent-to-automate-some-basic-housekeeping-tasks.aspx
- http://eightwone.com/2011/08/24/automatic-archive-provisioning-with-cmdlet-extension-agents/
- http://eightwone.com/2012/06/19/postconfiguring-mailboxes-cmdlet-extension-agents-part-2/
- http://www.howexchangeworks.com/2011/06/automating-tasks-with-scripting-agent.html
- http://www.ehloworld.com/194
- http://www.mikepfeiffer.net/2011/06/implementing-custom-validation-in-the-exchange-2010-management-tools/
- http://blog.crayon.no/blogs/janegil/archive/2010/10/17/using_2D00_cmdlet_2D00_extension_2D00_agents_2D00_to_2D00_customize_2D00_mailbox_2D00_provisioning.aspx
- http://www.flobee.net/automatically-disable-activesync-for-new-mailboxes-in-exchange-2010
- http://byronwright.blogspot.co.uk/2011/08/objects-available-to-scripting-agent.html
Enjoy