Recently one of our Clients bought 750 licenses for GFI MailEssentials 20. As GFI on their websites claims that only Active Mailboxes are counted it was safe to assume that all Shared Mailboxes wouldn't count for the license limit. This allowed us to not have to delete old users mailboxes and simply make sure those mailboxes are either Shared Mailboxes or Disabled.
Problem Description
However the GFI Licensing interface was showing quite different story.
This wasn't good. Having double checked the count number in the Licensing section confirmed the information.
We've first tried to check things using standard method that makes a lot of sense in this scenario. Counting all mailboxes, counting all disabled mailboxes and getting all active mailboxes that way.
function GetUsersCount() { # Option 1 $usersAll = (Get-Mailbox -ResultSize Unlimited).Count $usersDisabled = (Get-Mailbox -ResultSize Unlimited | ?{$_.ExchangeUserAccountControl -eq 'AccountDisabled'}).Count write-host "Total Mailboxes = $usersAll" write-host "Total Disabled Mailboxes = $usersDisabled " write-host "Total Active Mailboxes = $($usersAll-$usersDisabled)" }
However the result was a bit different then the one provided by GFI Interface
PS C:\Windows\system32> C:\ExchangeScripts\Manual\MailboxCount.ps1 Total Mailboxes = 1314 Total Disabled Mailboxes = 578 Total Active Mailboxes = 736
Not knowing what it is we've actually asked GFI to provide information how they count the licenses. After a lot of going back and forth with GFI support there seems there is bad information on their website how it's counted along with bad counting in the product itself. It would seem the way they count the product licenses is by using LDAP query.
Solution
It seems the information which query is used for gathering the licenses is stored in C:\Program Files (x86)\GFI\MailEssentials\Attendant\debuglogs\usercntvsapi.txt
There are multiple queries used inside so we've created a simple way to check them
function GetUsersCountGFI () { # Option 2 $strFilter = "(&(objectClass=person)(!(userAccountControl:1.2.840.113556.1.4.803:=2))(mail=*)(samAccountName=*))", "(&(objectClass=msExchPrivateMDB)(msExchOwningServer=CN=MAIL1,CN=Servers,CN=Exchange Administrative Group (FYDIBOHF23SPDLT),CN=Administrative Groups,CN=LOCAL,CN=Microsoft Exchange,CN=Services,CN=Configuration,DC=DOMAIN,DC=LOCAL))", "(&(objectClass=person)(!(userAccountControl:1.2.840.113556.1.4.803:=2))(mail=*)(samAccountName=*)(!(msExchRecipientTypeDetails:1.2.840.113556.1.4.803:=549755813888)))", "(&(objectClass=person)(!(userAccountControl:1.2.840.113556.1.4.803:=2))(mail=*)(samAccountName=*)(homeMDB=CN=MailboxDatabase1,CN=Databases,CN=Exchange Administrative Group (FYDIBOHF23SPDLT),CN=Administrative Groups,CN=LOCAL,CN=Microsoft Exchange,CN=Services,CN=Configuration,DC=DOMAIN,DC=LOCAL)(!(msExchRecipientTypeDetails:1.2.840.113556.1.4.803:=549755813888)))", "(&(objectClass=person)(!(userAccountControl:1.2.840.113556.1.4.803:=2))(mail=*)(samAccountName=*)(homeMDB=CN=MailboxDatabase2,CN=Databases,CN=Exchange Administrative Group (FYDIBOHF23SPDLT),CN=Administrative Groups,CN=LOCAL,CN=Microsoft Exchange,CN=Services,CN=Configuration,DC=DOMAIN,DC=LOCAL)(!(msExchRecipientTypeDetails:1.2.840.113556.1.4.803:=549755813888)))" foreach ($filter in $strFilter) { $objDomain = New-Object System.DirectoryServices.DirectoryEntry $objSearcher = New-Object System.DirectoryServices.DirectorySearcher $objSearcher.SearchRoot = $objDomain $objSearcher.PageSize = 1000 $objSearcher.Filter = $filter $objSearcher.SearchScope = "Subtree" $colResultsOption2 = $objSearcher.FindAll() write-host "Testing filter - $filter" write-host "Total License Count needed by GFI $($colResultsOption2.Count)" } } GetUsersCountGFI
After running the query the results were really weird. It would seem that depending on position of the databases the query would return different results on each server. So while on one server the query was showing over 750 user limit, on other server it was showing 361 users only.
Due to how the databases in Exchange were distributed server MAIL1 was reporting only Active Database users from MailboxDatabase1, server MAIL2 from MailboxDatabase2 and MAIL3 and MAIL4 were reporting over limit even thou the total count by 2 queries for MAIL1 and MAIL2 is giving 366 and 362 respectively.
Due to how the Mailbox Databases are spread across the servers it seems that GFI licensing counting is loosing it's count.
function GetUsersCount() { # Option 1 $usersAll = (Get-Mailbox -ResultSize Unlimited).Count $usersDisabled = (Get-Mailbox -ResultSize Unlimited | ?{$_.ExchangeUserAccountControl -eq 'AccountDisabled'}).Count write-host "Total Mailboxes = $usersAll" write-host "Total Disabled Mailboxes = $usersDisabled " write-host "Total Active Mailboxes = $($usersAll-$usersDisabled)" } function GetUsersCountGFI () { # Option 2 $strFilter = "(&(objectClass=person)(!(userAccountControl:1.2.840.113556.1.4.803:=2))(mail=*)(samAccountName=*))" $strFilter1 = "(&(objectClass=msExchPrivateMDB)(msExchOwningServer=CN=MAIL1,CN=Servers,CN=Exchange Administrative Group (FYDIBOHF23SPDLT),CN=Administrative Groups,CN=LOCAL,CN=Microsoft Exchange,CN=Services,CN=Configuration,DC=DOMAIN,DC=LOCAL))" $strFilter2 = "(&(objectClass=person)(!(userAccountControl:1.2.840.113556.1.4.803:=2))(mail=*)(samAccountName=*)(!(msExchRecipientTypeDetails:1.2.840.113556.1.4.803:=549755813888)))" $strFilter3 = "(&(objectClass=person)(!(userAccountControl:1.2.840.113556.1.4.803:=2))(mail=*)(samAccountName=*)(homeMDB=CN=MailboxDatabase1,CN=Databases,CN=Exchange Administrative Group (FYDIBOHF23SPDLT),CN=Administrative Groups,CN=LOCAL,CN=Microsoft Exchange,CN=Services,CN=Configuration,DC=DOMAIN,DC=LOCAL)(!(msExchRecipientTypeDetails:1.2.840.113556.1.4.803:=549755813888)))" $strFilter4 = "(&(objectClass=person)(!(userAccountControl:1.2.840.113556.1.4.803:=2))(mail=*)(samAccountName=*)(homeMDB=CN=MailboxDatabase2,CN=Databases,CN=Exchange Administrative Group (FYDIBOHF23SPDLT),CN=Administrative Groups,CN=LOCAL,CN=Microsoft Exchange,CN=Services,CN=Configuration,DC=DOMAIN,DC=LOCAL)(!(msExchRecipientTypeDetails:1.2.840.113556.1.4.803:=549755813888)))" $strFilter5 = "(&(objectClass=person)(!(userAccountControl:1.2.840.113556.1.4.803:=2))(mail=*)(samAccountName=*)(!(msExchRecipientTypeDetails:1.2.840.113556.1.4.803:=549755813888)))" $objDomain = New-Object System.DirectoryServices.DirectoryEntry $objSearcher = New-Object System.DirectoryServices.DirectorySearcher $objSearcher.SearchRoot = $objDomain $objSearcher.PageSize = 1000 $objSearcher.SearchScope = "Subtree" $objSearcher.Filter = $strFilter $colResultsOption = $objSearcher.FindAll() write-host "Total License Count needed according to GFI KB $($colResultsOption.Count)" $objSearcher.Filter = $strFilter1 $colResultsOption = $objSearcher.FindAll() write-host "Total License Count needed according to GFI Logs MAIL1 $($colResultsOption.Count)" $objSearcher.Filter = $strFilter2 $colResultsOption = $objSearcher.FindAll() write-host "Total License Count needed according to GFI Logs MAIL1 Next Query $($colResultsOption.Count)" $objSearcher.Filter = $strFilter3 $colResultsOption = $objSearcher.FindAll() write-host "Total License Count needed according to GFI Logs MAIL2 Query $($colResultsOption.Count)" $objSearcher.Filter = $strFilter4 $colResultsOption = $objSearcher.FindAll() write-host "Total License Count needed according to GFI Logs MAIL2 Query $($colResultsOption.Count)" $objSearcher.Filter = $strFilter5 $colResultsOption = $objSearcher.FindAll() write-host "Total License Count needed according to GFI Logs MAIL3 Query $($colResultsOption.Count)" } #ConnectExchange GetUsersCount GetUsersCountGFI
And the result:
Total Mailboxes = 1315 Total Disabled Mailboxes = 578 Total Active Mailboxes = 737 Total License Count needed according to GFI KB 1102 Total License Count needed according to GFI Logs MAIL1 0 Total License Count needed according to GFI Logs MAIL1 Next Query 1050 Total License Count needed according to GFI Logs MAIL2 Query 366 Total License Count needed according to GFI Logs MAIL2 Query 362 Total License Count needed according to GFI Logs MAIL3 Query 1050
The total count of mailboxes should be 727 according to own GFI queries, yet it's quite different depending where you look. We've reported this to GFI as bug, but for now your results may vary depending on which server you ask for the license count.