Exchange 2010 Scripting Agent


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

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


Microsoft Exchange Server 2013 Preview Help


Not sure if you have found this link yet?

This download contains the Help content for the Microsoft Exchange Server 2013 Preview, Exchange Online Preview, and Exchange Server 2013 Preview Hybrid Deployments release.

BTW the download is 1.36GB and you can get it from here:

#Powershell Service Uptime

So i wanted to see how long a couple of BlackBerry servers had been up, but I wanted to know how long the services has been running.  So i knocked this up.  Its dead simple to change for other services!

$Servers = "BES01", "BES02"
$Matrix = @()
ForEach($Server in $Servers){
  Write-Host $Server -Foregroundcolor Green
  $SVC = Get-Service -ComputerName $Server | Where {$_.Name -like "Black*"}
  Foreach($item in $SVC){
    $tmpMatrix="" | Select Server, Service, State, Uptime
    Write-Host "-" $Item.Name
    $tmpMatrix.Server = $Server
    $tmpMatrix.Service = $item.Name
    $s = gwmi win32_service -ComputerName $Server -filter "name = ‘$($item.Name)’"
    $tmpMatrix.State = $s.State
    If ($s.State -eq "Running"){
      $tmpUpTime = "{0}" -f ((get-date) – ([wmi]”).ConvertToDateTime((gwmi Win32_Process  -ComputerName $Server -filter "ProcessID = ‘$($s.ProcessId)’").CreationDate))
      $tmpMatrix.Uptime = $tmpUpTime
    $Matrix += $tmpMatrix