Exchange 2010 Scripting Agent

#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:

Enjoy

Comments

  1. Or you could just set up an ipsec tunnel to one domain controller and ensure that you are always writing to the same controller – its not that AD isn’t keeping up, its that you are doing commits to multiple domain controllers – well at least it was that way in older versions

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

%d bloggers like this: