Exchange Tip: Comparison of time span values

I needed to compare database copies with lagged time bigger than 0. It doesnt work to compare this way:

$database = Get-MailboxDatabase |select *
$lagged = $database | select * -ExpandProperty ReplayLagTimes | where {$_.value -ne "0.00:00:00"}

The reason is, that ReplyLagTime is of class TimeSpan. To compare it we must compare with the object of the same class. In my case I made variable of class TimeSpan and then compared.

$database | Select -ExpandProperty ReplayLagTimes | SELECT VALUE | GET-MEMBER

   TypeName: Selected.System.Collections.Generic.KeyValuePair`2[Microsoft.Exchange.Data.Directory.ADObjectId,Microsoft.

Name        MemberType   Definition
----        ----------   ----------
Equals      Method       bool Equals(System.Object obj)
GetHashCode Method       int GetHashCode()
GetType     Method       type GetType()
ToString    Method       string ToString()
Value       NoteProperty Microsoft.Exchange.Data.EnhancedTimeSpan Value=00:00:00


$a = New-TimeSpan

Days              : 0
Hours             : 0
Minutes           : 0
Seconds           : 0
Milliseconds      : 0
Ticks             : 0
TotalDays         : 0
TotalHours        : 0
TotalMinutes      : 0
TotalSeconds      : 0
TotalMilliseconds : 0


$database | Select  -ExpandProperty ReplayLagTimes | where {$_.value -ne $a}
Key                                                         Value
---                                                         -----
EX13NODE1                                                   1.00:00:00

$database | Select  -ExpandProperty ReplayLagTimes | where {$_.value -eq $a}
Key                                                         Value
---                                                         -----
EX13NODE2                                                   00:00:00

Exchange Tip: Exchange Data Type – ByteQuantifiedSize

Here are few tips how to work with ByteQuantifiedSize (Microsoft.Exchange.Data.ByteQuantifiedSize – Microsoft.Exchange.Data.dll) that is typical for Exchange sizes such as TotalDeletedItemSize, FolderSize, TotalItemSize, RecoverableItemsQuota, AvailableNewMailboxSpace etc.

# Example for BQS property
[PS] C:\> Get-MailboxStatistics filip |select TotalItemSize

4.38 MB (4,592,642 bytes)

# Get BQS value
[PS] C:\> (Get-MailboxStatistics filip).TotalItemSize.Value

4.38 MB (4,592,642 bytes)

# Check BQS methods especially ToBytes, ToKB, ToMB, ToGB, ToTB
[PS] C:\> (Get-MailboxStatistics filip).TotalItemSize.value|Get-Member

TypeName: Microsoft.Exchange.Data.ByteQuantifiedSize

Name          MemberType Definition
----          ---------- ----------
CompareTo     Method     int CompareTo(Microsoft.Exchange.Data.ByteQuantifiedSize other)
Equals        Method     bool Equals(System.Object obj), bool Equals(Microsoft.Exchange.Data.ByteQuantifiedSize other)
GetHashCode   Method     int GetHashCode()
GetType       Method     type GetType()
RoundUpToUnit Method     System.UInt64 RoundUpToUnit(Microsoft.Exchange.Data.ByteQuantifiedSize+Quantifier quantifier)
ToBytes       Method     System.UInt64 ToBytes()
ToGB          Method     System.UInt64 ToGB()
ToKB          Method     System.UInt64 ToKB()
ToMB          Method     System.UInt64 ToMB()
ToString      Method     string ToString(), string ToString(string format), string ToString(string format, System.IF...
ToTB          Method     System.UInt64 ToTB()

# Get BQS value (4.38 MB) in bytes
[PS] C:\> (Get-MailboxStatistics filip).TotalItemSize.Value.toBytes()


# Get BQS values in bytes from more objects
[PS] C:\> Get-Mailbox -Anr "fil"|Get-MailboxStatistics |%{$_.TotalItemSize.Value.toBytes()}


# Be careful to use BQS methods like ToGB because output is UInt64 (4.38 MB in GB?)
[PS] C:\> (Get-MailboxStatistics filip).TotalItemSize.Value.toGB()


# Get BQS as Double
[PS] C:\> (Get-MailboxStatistics filip).TotalItemSize.Value.toBytes()/1GB


# Select BQS value as needed
[PS] C:\> Get-MailboxStatistics filip|select @{Name='TotalItemSizeBytes';Expression={$_.TotalItemSize.Value.toBytes()/1GB}}


# BQS value as string
[PS] C:\> $string=(Get-MailboxStatistics filip).TotalItemSize.Value.toString()    
[PS] C:\> $string="4.38 MB (4,592,642 bytes)"

# Get bytes from BQS string
[PS] C:\> $string|%{($_.Substring($_.indexof("(")+1,$_.indexof("b")-$_.indexof("(")-2)) -replace(",","")}


# Get BQS string in GB
[PS] C:\> ($string|%{($_.Substring($_.indexof("(")+1,$_.indexof("b")-$_.indexof("(")-2)) -replace(",","")})/1GB

# Parse BQS string
[PS] C:\> [Microsoft.Exchange.Data.ByteQuantifiedSize]::Parse("$string")

4.38 MB (4,592,642 bytes)

[PS] C:\> ([Microsoft.Exchange.Data.ByteQuantifiedSize]::Parse("$string")).gettype()

IsPublic IsSerial Name                                     BaseType
-------- -------- ----                                     --------
True     True     ByteQuantifiedSize                       System.ValueType

# Invalid measuring for BQS values - ERROR
[PS] C:\> Get-Mailbox -Anr "fil"|Get-MailboxStatistics| Measure-Object -Sum -Average -Maximum -Minimum -Property TotalItemSize

Measure-Object : Input object "14.79 MB (15,511,742 bytes)" is not numeric.
At line:1 char:62
+ Get-Mailbox -Anr "fil"|Get-MailboxStatistics| Measure-Object <<<<  -Sum -Average -Maximum -Minimum -Property TotalItemSize
+ CategoryInfo          : InvalidType: (14.79 MB (15,511,742 bytes):Unlimited`1) [Measure-Object], PSInvalidOperat   ionException
+ FullyQualifiedErrorId : NonNumericInputObject,Microsoft.PowerShell.Commands.MeasureObjectCommand

# Measure BQS values
[PS] C:\> Get-Mailbox -Anr "fil"|Get-MailboxStatistics|%{$_.TotalItemSize.Value.toBytes()}| Measure-Object -Sum -Average -Maximum -Minimum

Count    : 4
Average  : 401522533
Sum      : 1606090132
Maximum  : 986385403
Minimum  : 13339213
Property :

# Measure BQS values as needed
[PS] C:\>Get-Mailbox -Anr "koch"|Get-MailboxStatistics|%{$_.TotalItemSize.Value.toBytes()}| Measure-Object -Sum |select@{Name='TotalMailboxSizeGB';Expression={$_.sum/1GB}}


Exchange 2010/2013 noreply e-mail solution

I have recently came accross the problem. One of my customers had wrong setting of no reply e-mail address and messages got lost between on-premise hub transport servers and Symantec cloud in the way, that it appeared message has been sent successfully, but dropped on Symantec side without notification.

Wrong settings:

All noreply email addresses has been set in MailContact object as follows:, …. and ExternalEmailAddress:

It means that all messages outside the company send from, aliases has been sent with ReturnPath and due to same reason (non existing domain and recipient) messages were dropped.

Solution 1:

  • Change External email address of Mail Contact Object to recipient from existing domain
  • Create transport rule to drop messages to this recipient

Solution 2:

From my point of view very ellegant and easy.

  • Remove Mail Contact object
  • Create DL, enable non authenticated senders to send messages to this DL
  • Assign noreply addresses to this DL
  • Use external e-mail address as primary SMTP address
  • Do not add any members to this DL. This step will cause to drop all incoming noreply messages without notifying anyone.


Exchange 2013 CU3 upgrade problem #3 – Failure cleaning up search foundation data folder

Another problem while upgrading Exchange 2013 CU3. During configuration of backend transport service search foundation folder error ocured:


error search foundationSolution:

Tricky one, but I have checked Exchange setup log and found the folder with search foundation installation script is located under %Exchangeinstalldirectory%\Bin\Search\Ceres\Installer\. I browse to the folder in powershell and run configuration script manually without arguments first, it gave me a list of available arguments and in my case it was needed to add configuration to existing one so “a” was the right choice.

.\InstallConfig.ps1 -action a

And voila. Next run setup of Exchange 2013 CU3 went ok without problems. Needed to say, that it has happened because of problem to connect to DC during setup.


Exchange 2013 CU3 upgrade problem #2 – IIS default web page incorrect binding

In this case I am not sure if it is problem or not, but just to remind myself for the future. After Exchange 2013 CU3 setup there was strange setting in IIS. Missing binding for all unassigned IP addresses for HTTPS on port 443. Solution is to remove incorrect binding and add new one.

ECP error IIS

Exchange 2013 CU3 upgrade problem #1 – EAC doesn´t work (HTTP 400, bad request)

I came into problem recently. After upgrade of Exchange 2013 CU2 to CU3 my ECP stopped to work. I tried to:

  • re-create ECP virtual directory
  • renew certificate (which expired recently)

none of those helped.


ECP error WEB

OWA - wrong authentication set

Then I checked authentication methods for my virtual directories and found, that Exchange 2013 CU3 setup messed up my OWA authentication methods. The goal here is to have both virtual directories set with the same authentication methods. In my case FBA and Basic.


Set correct authentication methods and run IISreset on problematic backend exchange servers.

Get-OwaVirtualDirectory | Set-OwaVirtualDirectory -FormsAuthentication $true -BasicAuthentication $true

OWA - correct authentication