- Create a File Share Witness
- Create the DAG – FSW, name and IP assigned
- Add a DNS record for the DAG on a DNS server
- Add a computer object for the DAG
- Add permissions for Exchange servers to the DAG computer object
- Disabled the computer object
Seems like a short and easy list. However, it did take a few iterations to get the DNS sorted out and the permissions sorted out. I also used a PowerShell cmdlet that is new to me Add-DatabaseAvailabilityGroupServer, which adds computer accounts to the DAG.
Run this script on an Exchange Server, but make sure to use Windows PowerShell and NOT the Exchange Management Shell. If you do, the Add-AdPermission cmdlet will not work because the EMS uses the Exchange Trusted Subsystem in order to connect to AD, while Windows PS uses the current logged in account. EMS generates an error like this:
Above is the results of running this in the EMS. The blue circled results show what happens when the Exchange Trusted Subsystem does not have permissions on the DAG CNO. The green circled area is when the Exchange Trusted Subsystem has the correct rights and can add the permission to the DAG CNO. The only way to avoid this, since it is a manual step, is to run the script in Windows PS.
The Script
The script is a bit of coding I’ve found from Microsoft along with my own customizations and features – computer object creation, DNS entry added and security applied to the CNO for the DAG.
CLS write-host " " write-host "Do you want to (1) create or (2) remove a DAG? " -ForegroundColor Green -NoNewline $dagchoice = read-host if ($dagchoice -eq "1") { CreateDAG } if ($dagchoice -eq "2") { DeleteDAG }
This section, while at the bottom of the script, is the beginning of the script. First a question is asked, do you want to create or delete a DAG. The Create a DAG function will run a function called CreateDAG. The DeleteDAG function that is called by option ‘2’ will walk through the process of removing the servers from the DAG, removing the DNS entry for the CNO, remove the CNO and remove the DAG from Exchange Server as well.
CreateDAG Function
$DagName = Read-Host "Enter the name for the DAG:" $DAGip = Read-Host "Enter the ip/ips for the DAG:" $FSW = Read-host "Enter the name of a server to be used for a FSW" $FSWDir = read-host "Please enter the file directory for the FSW share on $FSW" write-host " " write-host "Please verify you have added permissions for a non-Exchange server to be the FSW for Exchange 2013" -ForegroundColor Green write-host " "
The above section is used for gathering information on the DAG creation – name, FSW, FSW directory and DAG IP address.
#If Multiple ips below variable will be used $IPSplit = $DAGip.Split(',;') $Search = New-Object DirectoryServices.DirectorySearcher([ADSI]“”) $Search.filter = “(&(objectClass=Computer)(name=$DagName))” $A=$Search.Findall() if ($A[0].path -ilike "*$DagName*") { Write-Host "DAG name $DagName Already Exist in AD, select a DAG Name that does not exist in AD and re-run the script" }
This section handles the option of multiple IP Addresses as well as looks for a duplicate name for the DAG in AD. If there is a duplicate, the script exits.
Else { Write-Host "Creating DAG $Dagname ........" $New = New-DatabaseAvailabilityGroup -Name $DAGName -WitnessDirectory $FSWDir -WitnessServer $FSW Write-Host "Fileshare witness is created on $FSW and Fileshare Witness located at $FSWDir" Write-Host "Sleeping for 20 seconds to replicate" ; start-sleep -seconds 20
This section handles adding one or more IP addresses to the DAG:
if ($New.name -ilike "$DagName") { Write-Host "$DagName is created successfully, Setting up the Static Ip addresses." #Condition to check if its single or multiple ips if ($Dagip -ilike "*,*") { Set-DatabaseAvailabilityGroup -Identity $Dagname -DatabaseAvailabilityGroupIpAddresses ($IPSplit[0]),($IPSplit[1]) if ($? -eq $False){$Status = "FAILED"} else { $Status = "SUCCESS"} write-Host "$Status - Set ip address $DAGip to DAG $Dagname" if ($Status -eq "FAILED"){writelog $error[0]} start-sleep -seconds 15 Get-DatabaseAvailabilityGroup $Dagname |fl } Else { Set-DatabaseAvailabilityGroup -Identity $Dagname -DatabaseAvailabilityGroupIpAddresses $DAGip if ($? -eq $False){$Status = "FAILED"} else{$Status = "SUCCESS"} write-Host "$Status - Set ip address $DAGip to DAG $Dagname" if ($Status -eq "FAILED"){writelog $error[0]} start-sleep -seconds 30 Get-DatabaseAvailabilityGroup $Dagname |fl
This section will create the CNO in AD, disables the object per Microsoft and then gets the distinguished name for later use:
# Create Computer account, assign permissions, disable the object New-ADcomputer –name $dagname –SamAccountName $dagname Get-ADComputer cu7dag |set-adcomputer -enabled $false $dn=(get-adcomputer $dagname).distinguishedname
This section of code installed the DNS Server Tool Windows feature, adds a DNs entry for the DAG, validates it and then removed the DNS Server Tool Windows feature:
# Add DNS Record write-host "Now the script will add a DNS Record for the $dagname DAG." -ForegroundColor Yellow;write-host " ";write-host "Installing DNS Server Tool Feature" -ForegroundColor red;write-host " " # Check if DNS Module is available, if not, add it $installed = (Get-WindowsFeature rsat-dns-server).installstate if ($instaled -ne "Installed") {Add-WindowsFeature rsat-dns-server} import-module dnsserver write-host " ";write-host "Specify a DNS Server Name or IP Address " -NoNewline -ForegroundColor Green;$server = read-host $dnsroot = (get-addomain).dnsroot Add-DnsServerResourceRecordA -Name $dagname -ZoneName $dnsroot -AllowUpdateAny -IPv4Address $DAGip -TimeToLive 01:00:00 -ComputerName $server write-host "Validating the record was added:" -ForegroundColor white Get-DnsServerResourceRecord -name $dagname -zonename $dnsroot -computername $server |ft # Remove the DNS Module write-host "Removing DNS Server Tool Feature" -ForegroundColor red Get-WindowsFeature rsat-dns-server | Remove-WindowsFeature
This final section adds the computer accounts to the DAG’s CNO with full control as per Microsoft:
# Add computers to DAG write-host " ";write-host "Do you want to add (1) All mailbox server to the $dagname DAG or (2) Just some servers?" -nonewline -ForegroundColor Green;write-host " " $dagmembers = read-host # Add security so the script can continue its progress write-host" ";write-host "If using Windows PowerShell, ignore the below error. If you are using the Exchange Management Shell, you need to follow the steps below:" -ForegroundColor yellow;write-host " " write-host "MANUAL STEP" -NoNewline -ForegroundColor Red write-host ": Make sure that the Exchange Trusted Subsystem has full control on the CNO for the DAG (use ADUC to check)." Write-Host "Press any key to continue ..." $x = $host.UI.RawUI.ReadKey("NoEcho,IncludeKeyDown") $mbxsrvs = (get-MailboxServer).name if ($dagmembers -eq "1") { foreach ($line in $mbxsrvs) { # Grants permission for Exchange Servers to the CNO and adds them to the DAG # Add-AdPermission -Identity "$dn" -User "$($Computer)$" -AccessRights GenericAll Add-AdPermission -Identity "$dn" -User "$($line)$" -AccessRights GenericAll Add-DatabaseAvailabilityGroupServer -Identity $dagname -MailboxServer $line } } if ($dagmembers -eq "2") { foreach ($line in $mbxsrvs) { write-host " ";write-host "Do you want to add $line to your $dagname DAG? [y or n] " -NoNewline -ForegroundColor Green;4answer = read-host if ($answer -eq "y") { Add-AdPermission -Identity "$dn" -User "$($line)$" -AccessRights GenericAll Add-DatabaseAvailabilityGroupServer -Identity $dagname -MailboxServer $line } } }
Script Run Through
In my test lab I wanted to show the script in action. The first step is all the localized information you need to enter as well as the basic DAG creation:
Then the DNS entry is created:
After the DNS entry is validate, the script will then add one or more servers to your DAG:
… and that’s it. You can validate results by looking that the Exchange Admin Center, DNS and ADUC:
RemoveDAG Function
The RemoveDAG function is relatively simple. I’ve placed comments above each section as to what it does. I even have a ‘Are you sure?’ question just to make sure you want to go through a removal.
function DeleteDAG { write-host " ";write-host "Are you sure you want to remove your DAG?" -ForegroundColor Red;write-host " " Write-Host "Press any key to continue ..." -foregroundcolor white write-host " " $x = $host.UI.RawUI.ReadKey("NoEcho,IncludeKeyDown") # Remove all database copies $servers = (get-mailboxdatabase | Get-MailboxDatabaseCopyStatus |where {$_.status -eq "mounted"}).mailboxserver foreach ($line in $servers) {Get-MailboxDatabaseCopyStatus -server $line|remove-mailboxdatabasecopy -erroraction silentlycontinue} # Remove servers from the DAG $dagname = (Get-DatabaseAvailabilityGroup).name $names = ((Get-DatabaseAvailabilityGroup $dagname).servers).name foreach ($line in $names) { remove-DatabaseAvailabilityGroupServer -Identity $dagname -MailboxServer $line } # Remove computer object Get-ADComputer cu7dag | remove-adcomputer # Remove DNS Entry write-host " ";write-host "Specify a DNS Server Name or IP Address " -NoNewline -ForegroundColor Green;$server = read-host $dnsroot = (get-addomain).dnsroot remove-DnsServerResourceRecord -name $dagname -zonename $dnsroot -computername $server -rrtype a -erroraction silentlycontinue # Remove DAG itself Remove-DatabaseAvailabilityGroup $dagname }
In action
Notice each step will ask for you to confirm that you indeed want to remove the members from the DAG, to remove the DAG AD object or the Exchange DAG object as well.
Download the script
The script can be found on the TechNet Wiki Gallery.
Resources
I have a lot of good links for this script for you to read over for reference:
Add Computer Account to AD
Adding Windows Features
Add a DNS A record on a local DNS server
Remove a DNS A record on a local DNS server
CNO Pre-staging
Add-DatabaseAvailabilityGroupServer
Rights – written by a fellow Exchange MVP, I stumbled upon this while looking for how to add permissions for the computer objects to another computer object.
Exchange Trusted Subsystem – requires Full control because that is the account that is used by the Exchange Management Shell.
Rights issues – for Exchange 2010, but may apply to 2013 depending on your scenario.