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

One thought on “Exchange 2010 Scripting Agent

  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

This site uses Akismet to reduce spam. Learn how your comment data is processed.