Scroll Top
Evotec Services sp. z o.o., ul. Drozdów 6, Mikołów, 43-190, Poland

GFI MailEssentials 20 – How to count licenses for users?

GFI MailEssentials

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.

Related Posts

Leave a comment

You must be logged in to post a comment.