Tuesday, October 11, 2016

View Schema Version PowerShell

Hi folks,

I have recently discovered a nice way to retrieve schema version using PowerShell. Earlier I published how to do it using dsquery command. However with dsquery you need to remember the DN for your forest. This one-liner makes life a lot easier:

Get-ADObject (get-adrootdse).schemaNamingContext -Property objectVersion

About each version of Windows Server in schema you can read here.


Deleting Faulty Default Mailbox Databases

Hi folks,

Just wanted to share with you about the adventure I've had recently. As you know when Exchange Server 2010 and later is installed on the mailbox servers default mailbox database is created named something like "Mailbox Database 123456". Normally, new highly available databases are created which are stored outside of the default installation drive. Normally they are deleted.

When I was trying to delete my database I would see error as below:

I would see the same when trying to dismount database (which is also an invisible step when a database is being deleted):

As this article suggests this database has misconfigured MsExchMasterServerOrAvailabilityGroup property. When a mailbox server is a member of DAG this value should be equal to DN of DAG, for a standalone mailbox server this value will be DN of server.

When running Get-MailboxDatabase  DB01 | Format-Table Name, MasterType against my problematic database, I would see value of the MasterType property (corresponds to the MsExchMasterServerOrAvailabilityGroup attribute mentioned above) as Server. It indicates that DAG doesn't own this DB. Normally when a server is added to DAG MasterType value should be DatabaseAvailabilityGroup. So in my case this value wasn't properly updated and I was getting the error I was getting when attempting to delete or dismount DB.

The only way to fix it is tweaking Exchange objects in the AD on low level. Make sure it is backed up because AdsiEdit is not nice enough to warn you when you mistakenly delete something or mess a setting up. Therefore you should really know what you do. Or have MS support being at call with you and direct you as you tweak AD objects.

To access DB properties we will need to ADSIEDIT.MSC and navigate to CN=Databases,CN=Exchange Administrative Group (FYDIBOHF23SPDLT),CN=Administrative Groups,CN=CONTOSO,CN=Microsoft Exchange,CN=Services,CN=Configuration,DC=contoso,DC=com .

This is the AD container where Exchange stores information about mailbox databases. If mailbox database us called DB01 you will need to edit properties of CN=DB01 subcontainer.

We will need to open properties of mailbox database in AD and check the value of the attribute. In my case it was distinguished name (DN) of the mailbox server where it was hosted: CN=SERVER01,CN=Servers,CN=Exchange Administrative Group (FYDIBOHF23SPDLT),CN=Administrative Groups,CN=CONTOSO,CN=Microsoft Exchange,CN=Services,CN=Configuration,DC=contoso,DC=com

I had to tweak this value to the DN of DAG my server is part of:
CN=DAG01,CN=Database Availability Groups,CN=Exchange Administrative Group (FYDIBOHF23SPDLT),CN=Administrative Groups,CN=CONTOSO,CN=Microsoft Exchange,CN=Services,CN=Configuration,DC=contoso,DC=com

After this I gave some time for the AD to replicate. After which I have executed the following command again:

Get-MailboxDatabase  DB01 | Format-Table Name, MasterType

This time output was like below:

After which you can run the following command to remove mailbox database:
Remove-MailboxDatabase DB01 -Confirm:$false

After hitting Enter the default database should be successfully removed. At least it was a case for me.


Thursday, October 6, 2016

Which Domain Controller Can I Use for My EMS Commands

Hi folks,

I have previosly discussed how to use PowerShell commands (from the AD module) to discover domain controllers in an AD site. You can read about it in this post.

The same is possible to do by using EMS. In some of the cases when you are running multiple commands and dependent on the AD replication before running the next command it is nice to write all changes to the same AD command. MS has nicely provided -DomainController parameter which allows us to perform any reading/writing of Exchange information against the same domain controller. All you need is to specify DC host name.

Now if you have multiple domains or a lot of domain controllers within AD site where your Exchange server is located (or workstation with Exchange admin tools) you can use the Get-DomainController cmdlet to discover them. You can read about this cmdlet and all the available parameters here. Let's imagine that my Exchange server is located in the AD site called New York and in multi-domain forest. I need to write to a DC in the contoso.com domain. Then the following command will be used:

Get-DomainController -DomainName contoso.com |Where-Object {$_.AdSite -like "*NewYork*"} |select DnsHostName

It is pretty obvious. However, let me explain why I used filter for AdSite parameter and asked command to output DnsHostName parameter. Usually Get-DomainController returns distinguished value for AD site something like contoso.com/Configuration/Sites/New York. The same applies for domain controllers' parameter called Identity parameter of domain controller. It will be something like contoso.com/Configuration/Sites/New York/NYDC01. DnsHostName parameter will retrieve FQDN of DC which you can later use as value for the -DomainController parameter, like NYDC01.contoso.com.

I hope you will find this useful for your PowerShell adventures.


Wednesday, October 5, 2016

Dealing With Failed Passive Copies

Hi folks,

I would love to share with you about my recent experience which I had with mailbox DB copies. I had an issue where mailbox DBs on one of the servers in DAG which contains only passive DB copies only some of the copies couldn't replicate if they got activated on one of the servers in primary datacenter. I also saw the following event in the Application log:

Some investigations lead me to find that this server was missing static route for the replication link.

It was fairly easy to resolve as I had to add persistent static route for replication network by running route add -p command with the appropriate information for route. After adding route replication was sorted out.

Now I had to sort out the mailbox copies themselves. I used the Get-MailboxDatabaseCopyStatus command on the server where these copies were failed which without any specified parameters retrieves mailbox databases copies hosted on the server from which you run it explicitly. Since all the copies on my servers were only passive I could filter them out by running the following command:

Get-MailboxDatabaseCopyStatus |Where-Object {$_.Status -ne "Healthy"}

It retrieves all the copies DB copies that don't have status of healty. If you also have active DB copies you may also get all the mounted DB copies as their status will be Mounted. In this case you will need to tweak command to cater for these DB copies as well. So after I restored replication I ran this command to first suspend and then to resume copies:

Get-MailboxDatabaseCopyStatus |Where-Object {$_.Status -ne "Healthy"}| foreach {Suspend-MailboxDatabaseCopy -Identity $_.Name -Confirm:$false}

However, after trying to suspend I got an error as below because of double pipelines:

So instead I dumped all the failed copies into a variable called $FailedCopies. My code turned out something as below:

$FailedCopy = Get-MailboxDatabaseCopyStatus |Where-Object {$_.Status -ne "Healthy"}

After this I have ran commands to suspend and resume database copies against all DBs that were in variable:

$FailedCopy |foreach {Suspend-MailboxDatabaseCopy -Identity $_.Name -Confirm:$false}
$FailedCopy |foreach {Resume-MailboxDatabaseCopy -Identity $_.Name}

Finally if you decide to reseed (it may and will consume a lot of network traffic) you may run command as below:

$FailedCopy |foreach {Update-MailboxDatabaseCopy -Identity $_.Name -DeleteExistingFiles}