Win32::MailboxGUID - functions to convert Exchange mailbox GUIDs

    version 0.02

      # Example that requires Win32::OLE, DBI, DBD::ADO and administrative permissions
      # invoked with a list of Exchange servers on the command line to query
      # Use of 'exch_to_ad'

      use strict;
      use warnings;
      use Win32::OLE qw(in);
      use Win32::MailboxGUID qw[exch_to_ad];
      use DBI;


      my %limitinfo = (
        '1', 'Below Limit',
        '2', 'Issue Warning',
        '4', 'Prohibit Send',
        '8', 'No Checking',
       '16', 'Mailbox Disabled',

      my $Root = Win32::OLE-> GetObject("LDAP://RootDSE");
      my $DefaultDomainNC = $Root-> Get("DefaultNamingContext");
      my $dsn = "Provider=ADsDSOObject;ConnectionString=$DefaultDomainNC";
      my ($usr,$pwd);
      my $att = { };
      my $dbi = DBI->connect("dbi:ADO:$dsn", $usr, $pwd, $att ) or die $DBI::errstr;

      OUTER: foreach my $server ( @ARGV ) {
        my $object = Win32::OLE->GetObject("winmgmts:{impersonationLevel=impersonate}!//$server/root/MicrosoftExchangeV2");
        next OUTER unless $object;
        INNER: foreach my $mailbox ( in $object->InstancesOf("Exchange_Mailbox") ) {

           # Look up the quota info from the user account in AD

           my $mbguid = $mailbox->{MailboxGUID};
           my @quotas = _find_user( $dbi, $mbguid );

           my $limit = defined $mailbox->{StorageLimitInfo} && $limitinfo{ $mailbox->{StorageLimitInfo} } ? $limitinfo{ $mailbox->{StorageLimitInfo} } : '';
           print join ',', $mailbox->{MailboxDisplayName}, $mailbox->{Size}, @quotas, $limit, $mailbox->{ServerName}, $mailbox->{TotalItems} || 0;
           print "\n";

      exit 0;

      sub _find_user {
        my $dbh = shift;

        my $guid = exch_to_ad( shift ); # convert the GUID Exchange to AD

        $guid = $dbi->quote( $guid );
        my $sth = $dbi->prepare(qq{ select AdsPath FROM 'LDAP://$DefaultDomainNC' WHERE msExchMailboxGuid = $guid }) or die "Error $DBI::err ($DBI::errstr)\n";
        $sth->execute() or die "Error $DBI::err ($DBI::errstr)\n";
        while ( my $hashref = $sth->fetchrow_hashref ) {
           my $object = Win32::OLE->GetObject($hashref->{AdsPath});
           next unless $object;
           if ( $object->{mDBUseDefaults} ) {
             return ( 'defaults', 'defaults', 'defaults' );
           else {
             return map { $object->{$_} } qw(mDBStorageQuota mDBOverQuotaLimit mDBOverHardQuotaLimit);
        return ('orphaned','orphaned','orphaned');

    Active Directory and Exchange Server use a GUID to link a user account
    to a mailbox. Unfortunately, both these beasts cannot agree on the
    storage/presentation format of the GUID.

    Retrieving user objects from Active Directory with "ADSI", the
    "msExchMailboxGuid" is in a byte array format, which can be represented


    Whereas using the "WMI" Exchange provider, "MailboxGUID" is in the
    following format:


    This module provides two functions that will convert between these two
    formats, making the life of the Win32 Perl scripting system
    administrator slightly less painful.

    The functions listed may be imported into your namespace on demand.

      use Win32::MailboxGUID qw[ad_to_exch exch_to_ad];

    Or called as class methods.

      use Win32::MailBoxGUID;

      my $guid = Win32::MailboxGUID->ad_to_exch( $adexchguid );

        Takes a byte array such as the "msExchMailboxGuid" attribute from an
        Active Directory user object. Returns the GUID as a "MailboxGUID"
        formatted string as per the "Exchange_Mailbox" WMI class.

        Takes a "MailboxGUID" formatted string as per the "Exchange_Mailbox"
        WMI class. Returns a hex string of the "msExchMailboxGuid" suitable
        for searching/updating Active Directory.


    Chris Williams <>

    This software is copyright (c) 2011 by Chris Williams.

    This is free software; you can redistribute it and/or modify it under
    the same terms as the Perl 5 programming language system itself.