Add a IP Address to the RemoteIPRanges of an existing Receive Connector

Scenario:  Your Exchange 2013 Servers Receive Connector already has multiple values assigned to it.  Because its a multi-valued field,  you cannot easily add a single IP address to it without overwriting the contents of the field using a command similar to: set-receiveconnector -remoteipranges 10.10.0.2

Solution: In order to add a IP address to an existing set of RemoteIPRanges for a receiveconnector, run the following:

$RC = Get-ReceiveConnector "Ex2013-1Default FrontEnd Ex2013-1"

$RC.RemoteIPRanges += "10.10.0.2"

Set-ReceiveConnector "Ex2013-1Default FrontEnd Ex2013-1" -RemoteIPRanges $RC.RemoteIPRanges

 

Determine the IP Address and check to see if a PTR record exists for each Exchange Server

Scenario:  You want to determine the IP Address and PTR record for each Exchange Server in your environment.   Below is the script I used.  This will query for DNS and put the results into a table called $final.

Script:

$servers = get-exchangeserver ex2013* | Where AdminDisplayVersion -like *15*

$final = @()

$Servers | %{ 
write-host $_.Name
$Name = ([System.Net.Dns]::GetHostEntry("$_")).HostName;
$Address = ([System.Net.Dns]::GetHostEntry("$_")).AddressList;
$PTR = ([System.Net.Dns]::GetHostByAddress($Address)).HostName

$returnobj = new-object psobject
$returnobj |Add-Member -MemberType NoteProperty -Name "ServerName" -Value $Name
$returnobj |Add-Member -MemberType NoteProperty -Name "IPAddress" -Value $Address
$returnobj |Add-Member -MemberType NoteProperty -Name "PTR" -Value $PTR
$final += $returnObj

$Name = $null
$address = $null
$ptr = $null


}

$final

 

 

 

Working with Mailbox Database Copy Activation

This example only suspends activation for the copy of the database DB1 hosted on the Mailbox server MBX3.
Suspend-MailboxDatabaseCopy –identity DB1MBX3 –ActivationOnly

To Resume activation
Resume-MailboxDatabaseCopy –identity DB1MBX3

To block all databases hosted on a server from activating.
Set-MailboxServer –identity MBX3 –DatabaseCopyAutoActivationPolicy Blocked

Resume activation of server
Set-MailboxServer –identity MBX3 –DatabaseCopyAutoActivationPolicy Unrestricted

To block all databases hosted on a group of servers from activating. Use wildcard (MBX*)
Set-MailboxServer –identity MBX* –DatabaseCopyAutoActivationPolicy Blocked

Determine the true size of a mailbox by adding together the TotalItemSize and TotalDeletedItemSize values.

Scenario:  Determine the true size of a mailbox by adding together the TotalItemSize and TotalDeletedItemSize values together via a script and put the values into a table.  These values are properties of the Get-MailboxStatistics commandlet.

Note:  The TotalDeletedItemSize is not included in the TotalItemSize value for a mailbox.  Test it by deleting all of your mailbox content and comparing the values before and after.  Then perform a mailbox move and Exchange will show the total size of the mailbox which is a combination of the two.

Script:

#query for your mailboxes
$stat = get-mailboxdatabase DB* | Get-mailboxstatistics | Select DisplayName,TotalDeletedItemSize, TotalItemSize,ItemCount

#Define array variable
$final = @()

#Loop
$stat | %{

$TIS = $_.TotalItemSize.Value.ToMB() | Measure-object -sum

$TDIS = $_.TotalDeletedItemSize.Value.ToMB() | Measure-object -sum

$Total = $TIS.sum + $TDIS.sum


#Build the Array
 $ServerObj = New-Object PSObject
 $ServerObj | Add-Member NoteProperty -Name "DisplayName" -Value $_.DisplayName
 $ServerObj | Add-Member NoteProperty -Name "MbxSize(InMB)" -Value $total
 $Final += $ServerObj    
}

$Final

 

 

 

Build a custom table in Powershell that includes mailbox count

Scenario:  You want to build a custom table to include the MailboxCount and other elements of the Get-ExchangeServer command.

$exchangeservers = Get-ExchangeServer | Where AdminDisplayVersion -like "*15*"

$final = @()

$Exchangeservers | %{

#Put the Server Name into a Variable
$server = $_.Name

#Grab the Mailbox Count Per server
$MBXCount = (Get-mailbox -server $_.Name).Count

#Version of Exchange
$AdminDisplayVersion = $_.AdminDisplayVersion

Write-Host "Checking $server"

#Grab the InstallPath
$ExchangeInstallPath = $null

$ExchangeInstallPath = Invoke-Command –Computername $server -ScriptBlock {$env:ExchangeInstallPath} -ErrorAction STOP

#Build the Array
 $ServerObj = New-Object PSObject
 $ServerObj | Add-Member NoteProperty -Name "ServerName" -Value $server
 $ServerObj | Add-Member NoteProperty -Name "InstallPath" -Value $ExchangeInstallPath
 $ServerObj | Add-Member NoteProperty -Name "MBXCount" -value $MBXCount
 $ServerObj | Add-Member NoteProperty -Name "Version" -value $AdminDisplayVersion
    $Final += $ServerObj    
}
$Final

 

 

Exchange Database Restore with CommVault

Here are the steps for performing the restore:

1. Create the Recovery Exchange Database in Exchange

2. Restore the Database from backup in CommVault

3. Restore the contents of the mailbox in the recovery database to a place holder mailbox in Exchange.

4. Create a PST of the of the mailbox content of the place holder mailbox in Exchange.

 

Create a Recovery Database in Exchange 2013:
The server MBX1 has a dedicated mount point for restoring databases in Exchange. The mountpoint is C:RecoveryDB on MBX1. Run the following powershell command:

New-MailboxDatabase -Recovery -Name RDB_DB01 -Server MBX1 -EdbFilePath “C:RecoveryDBRDBDB01.edb” -LogFolderPath “C:RecoveryDBRDB logs”

 

Restore to the Recovery Database in CommVault:

1. Ensure the database you want to restore is dismounted and marked for overwrite.

2. From the CommCell Console, navigate to Client Computers | <Exchange CommVault Client>. Right-click Exchange Database and then click All Tasks | Browse Backup Data.

3. Select your Browse option for when to Restore From. Select the date of the last known good backup of the data that needs to be restored.

4. In the left pane of the Client Browse window, navigate to Exchange Database | Microsoft Information Store | <Storage Group>. Select the database to be restored in the right pane and click Recover All Selected.

5. In the Restore Destination section, select the destination client that holds the Recovery Database; MBX1. In the Destination DB, select the new recovery database that was created; RDB_DB01. Click OK. You can monitor the restore in the Job Controller so you know when it is 100%.
Extract Content from Recovery Database:
1. Mount the Recovery Database so we can access the content by running the following in Exchange PowerShell:

Mount-database RDB_DB01

2. The following PowerShell command we can use to extract content of the mailboxes. The content can be extracted and placed into another mailbox. We will use a place holder mailbox called r_steve2010 and put all of the content into a recovery folder which will be created during the mailbox restore.

Exchange 2013 command:

New-MailboxRestoreRequest -SourceDatabase “RDB_DB01” -SourceStoreMailbox “<DisplayName of User on RDB Database>” -TargetMailbox “r_steve2010” -TargetRootFolder Recovery -AllowLegacyDNMismatch

Exchange 2010 Command:

Restore-Mailbox -Identity “R_Steve2010” -RecoveryDatabase “RDB_DB01” -RecoveryMailbox ‘steve2010’ -TargetFolder Recovery

3. From here we can either provide access the dummy account, or export the content from the dummy mailbox to a PST and give it to the customer. To export it to a pst, run the following Powershell Command:

New-MailboxExportRequest R_steve2010 –FilePath “\servernamesharenamefilename.pst” -acceptlargedataloss -baditemlimit 999
Now we have successfully restored and recovered content from a Commvault backup.

How to quickly gather IP Addresses for a list of Servers

Scenario: You want to quickly gather the IP addresses from a list of HostNames.  Gather your hostnames into a variable and run the following script:

#Gather into your Variable ( I am gathering a list of all Exchange 2010 servers) – You could also Import-CSV or other import types.

$Servers = Get-ExchangeServer ExSvr* | Where AdminDisplayversion -like *14* | Sort Name

#Loop It!  You can also write it out to a file as well by inserting Out-File with -append OR other export types.

$servers | %{
$IP = [System.Net.DNS]::GetHostAddresses($_.Name).IPAddressToString
$Name = $_.Name +":"+$IP
Write-Host $name
}

Exchange 2010 is no longer connecting with Outlook Anywhere

Scenario: After the installation of additional Exchange 2013 servers​, we noticed that Outlook Anywhere is broke in our Exchange 2010 environment. The Exchange 2013 environment and mailboxes are unaffected by the connection problems, but the Exchange 2010 mailboxes cannot use Outlook Anywhere. Ex2010 mailboxes have to make a connection directly to the CAS Array or connect via other protocols as workarounds.

Symptoms:

◦We are seeing 503 HTTP Statuses (Service Unavailable) in the Ex2013 IIS logs when trying to connect to Exchange 2010 for Outlook Anywhere.

◦Outlook Clients either cannot establish a Outlook Anywhere connection, or their connection failback’s to a standard TCP connection.

◦Exchange 2013 mailboxes may have problems connecting to Public Folders on Exchange 2010 via Outlook.

◦Running the powershell command below fails when trying to get a referral and gives a 0x0000006BA or 0x6Ba error:

test-outlookconnectivity -protocols HTTP -credential $mycreds -verbose

◦Using the following command, you are unable to make a connection to ports 6001, 6002, and 6004.

rpcping -t ncacn_http -o RpcProxy=mail.domain.com -P “user,domain,password” -H 1 -F 3 -a connect -u 9 -v 3 -s casarray.domain.com -I “user,domain,password” -e 6001

 

Cause:  Ex2010 has a limit of servers that can be entered into a ServerFarm value in the Registry.   The addition of the new Ex2013 servers took us over the 64 server limit. When this happened, Outlook Anywhere (RPC/HTTP) in Ex2010 broke. Troubleshooting various symptoms pointed to different areas of Exchange that could be the cause of this behavior.  Later it was discovered that it was a bug confirmed by Microsoft. The real kicker of this ‘bug’ is that the Exchange 2013 servers, regardless if their frontend (CAS) or backend (MBX) servers, gets populated in this Ex 2010 key because of the Ex2013 architectural differences.

 

2 Resolutions:

1. Microsoft has an IU (interium update) for Exchange 2010 to fix this issue. You just need to remove this IU before you proceed with other installs. Supposedly this issue will be fixed in Exchange 2010 RU9 for SP3.   This was our fix

Or

2. You can edit the registry manually. Note this worked for us for a while, but we did have problems with this and resorted to the IU method. Regardless , this method may get you by for a little while:

Turn the Polling for the RPCHttpConfigurator off by going setting the PeriodicPollingMinutes to 0:

HKEY_LOCAL_MACHINESYSTEMCurrentControlSetservicesMSExchangeServiceHostRpcHttpConfiguratorPeriodicPollingMinutes

Manually remove the Exchange 2013 servers from the ServerFarm Registry Key to take the number of entries below 64:

HKEY_LOCAL_MACHINESOFTWAREMicrosoftRpcRpcProxyLBSConfigurationca5b08e5-4a52-5701-0000-000000000000

Cert Work! Querying, Removing, Assigning Services to Exchange Servers via Powershell

Scenario:  You want to clean up Exchange Certificates on your Exchange Servers. The following steps are examples of querying and building your query to perform an action.

1. Check to see what Exchange Certs are on your server.

get-exchangecertificate -server  ExSvr1

2. Query a list of Certificates that have the subject mail.domain.com:

get-exchangecertificate – Server ExSvr1 | Where Subject -like CN=Mail.dom*

3.  Query a list of Certificates that have the subject mail.domain.com and have a Expiration less than a specific date:

Get-ExchangeCertificate -Server ExSvr1 | Where {($_.NotAfter -lt “3/22/2019”) -and ($_.Subject -like “CN=Mail.dom*”)} 

4.  Remove the list of Certificates that have the subject mail.domain.com and an expiration less than a specific date:

Get-ExchangeCertificate -Server ExSvr1 | Where {($_.NotAfter -lt “3/22/2019”) -and ($_.Subject -like “CN=Mail.dom*”)}  | Remove-Exchangecertificate -confirm:$false

 

Lets say you want to query all Ex2013 servers to find and remove the certs:

1. Gather your Servers into a Variable:

$Servers = Get-ExchangeServers | Where AdminDisplayVersion -like *15*

2. Use that variable in a loop to loop through the certs:

$Servers | %{

Write-Host $_.name;

Get-ExchangeCertificate -server $_.nameWhere {($_.NotAfter -lt “3/22/2019”) -and ($_.Subject -like “CN=M*”)}  | Remove-Exchangecertificate -confirm:$false

}

 

How to move/enable services on an Exchange Certificate:

1. Determine the Thumbprints of the Certificate you want to move Exchange Services to:

Get-exchangecertificate -server ExSrv1

2. Move/Enable services on an Exchange Certificate

Enable-ExchangeCertificate -thumbprint <thumpbrint> -server ExSrv1 -services IIS,SMTP,POP,IMAP

 

Now lets say you want to loop it:

1. Gather your servers into a variable:

$Servers = Get-ExchangeServers | Where AdminDisplayVersion -like *15*

2. Enable Services on all your servers certs with a Loop:

$Servers | %{ 

Write-Host $_.name;

Enable-ExchangeCertificate -thumbprint <thumpbrint> -server $_.name -services IIS,SMTP,POP,IMAP

}

 

15 Minute Message Delays when Receiving email

Scenario:  It was reported that mailboxes were receiving message delays when receiving a message.​ The customer stated the time was 15-20 minutes before the message would make it into the mailbox. The message header was showing the delay, but not showing what was causing the delay.

Cause: We found that one of the servers was not accepting any messages, thus causing that hop to be delayed.  15 minutes was how long it would take for the next hop to occur again. When the next hop would happen it would select a different server to send the message.

Troubleshooting: We ran the following command to see where the message was being delayed.

get-transportserver | Get-messagetrackinglog -eventID Defer -Start 3/18/15 | Export-csv C:defer.csv

When we opened the csv file we found the common Servername that was having the issue.  When we logged onto the server to attempt to restart some Exchange services, it was apparent the server was having other issues. We rebooted the server and all was well when it came online again.