Hobby Chef

March, 2009 - Jive into Messaging world - Site Home - MSDN Blogs

Blog - Title

March, 2009

  • Jive into Messaging world

    HOWTO: Give Service Account Access to all mailboxes on an Exchange 2007 Server


    This is my first attempt to write a Powershell sample to my readers. In this sample we will give Send-As, Receive-As, ms-Exch-Store-Admin rights to an active directory user. We will be piping two commands here… Get-MailboxServer and the result will go to Add-AdPermission.

    You may give same permissions using Exchange Power Shell Window

    C:\>Get-MailboxServer –Identity MSGEX07 | Add-AdPermission –User UserA –AccessRights GenericRead, GenericWrite –ExtendedRights Send-As, Receive-As, ms-Exch-Store-Admin

    Here is the sample…

    using System;
    using System.Collections.Generic;
    using System.Text;
    using System.Management.Automation.Runspaces;
    using System.Collections.ObjectModel;
    namespace PowershellSample
        class Program
            static void Main(string[] args)
                RunspaceConfiguration config = RunspaceConfiguration.Create();
                PSSnapInException warning;
                // Load Exchange PowerShell snap-in.
                config.AddPSSnapIn("Microsoft.Exchange.Management.PowerShell.Admin", out warning);
                if (warning != null) throw warning;
                using (Runspace thisRunspace = RunspaceFactory.CreateRunspace(config))
                        using (Pipeline thisPipeline = thisRunspace.CreatePipeline())
                            //Please change parameter values.
                            Command cmdGetMailbox = new Command("Get-MailboxServer");
                            Command cmdAddAdPermission = new Command("Add-AdPermission");
                            cmdGetMailbox.Parameters.Add("Identity", @"MSGEX07");
                            cmdAddAdPermission.Parameters.Add("User", "UserA");
                            cmdAddAdPermission.Parameters.Add("AccessRights", new string[] { "GenericRead", "GenericWrite" });
                            cmdAddAdPermission.Parameters.Add("ExtendedRights", new string[] { "Send-As", "Receive-As", "ms-Exch-Store-Admin" });
                            catch (Exception exx)
                                Console.Write("Error: " + exx.ToString());
                            // Check for errors in the pipeline and throw an exception if necessary.
                            if (thisPipeline.Error != null && thisPipeline.Error.Count > 0)
                                StringBuilder pipelineError = new StringBuilder();
                                pipelineError.AppendFormat("Error calling cmdLets...");
                                foreach (object item in thisPipeline.Error.ReadToEnd())
                                    pipelineError.AppendFormat("{0}\n", item.ToString());
                                throw new Exception(pipelineError.ToString());
  • Jive into Messaging world

    Exchange 2007 SDK on Windows Server 2008, is it supported? YES it is!!!


    I have seen lots of confusion lately and people asking this question in various forums. I do not have an official statement yet on this and waiting for a response from Exchange SDK documentation owners.

    Here is my understanding, I may be wrong here.

    According to http://www.microsoft.com/downloadS/details.aspx?familyid=47720D33-FA5A-4AF4-A8EB-FA39695CBAD1&displaylang=en, the Exchange 2007 SP1 SDK does not list Windows 2008 as supported platform.

    It does not says it’s NOT supported but it also does not mention that whether its supported or not. Usually something which is NOT documented as “not supported” is assumed to be supported :-)

    Let’s take an example of “Exchange 2007 SP1” - http://www.microsoft.com/downloads/details.aspx?displaylang=en&FamilyID=44c66ad6-f185-4a1d-a9ab-473c1188954c

    The download page does not mention that it’s supported on Windows 2008 while it is the only version of Exchange so far which is supported on Windows 2008

    Source: http://technet.microsoft.com/en-us/library/bb232170.aspx

    Exchange 2007 and Windows Server 2008

    The RTM version of Exchange 2007 cannot be installed on Windows Server 2008. However, Exchange 2007 SP1 is supported for installation on Windows Server 2008. Although you cannot install the RTM version of Exchange 2007 on Windows Server 2008, the RTM version of Exchange 2007 will be supported for use with Windows Server 2008 directory servers.

    Exchange Server 2003 Service Pack 2 (SP2) is similarly supported. Exchange Server 2003 cannot be installed on a computer running Windows Server 2008, but Exchange 2003 will be supported for use with Windows Server 2008 directory servers.

    Be aware of the following when combining Microsoft Exchange with Windows Server 2008:

    • Exchange 2007 RTM and all previous versions of Microsoft Exchange are not supported for installation on a computer running Windows Server 2008.
    • Exchange 2007 SP1 can be installed on a computer running Windows Server 2008.
    • Management tools for Exchange 2007 RTM and all previous versions of Microsoft Exchange are not supported for installation on a computer running Windows Server 2008 or Windows Vista.
    • Management tools for Exchange 2007 SP1 can be installed on a computer running Windows Server 2008 or Windows Vista.

    With all that into consideration, it is safe to assume that if you are running with Exchange Sp1 Management Tools on a Windows 2008 machine you are under support boundaries to install and use SDK. I will update this document once I have more information along with facts & confirmation from documentation team.

    Stay tuned…

    EDIT: UPDATED ON 3/18/2009

    I have got confirmation from product group that its a document bug and nothing more or less. So we DO support Exchange 2007 SP1 SDK on Windows Server 2008.

  • Jive into Messaging world

    HOWTO: CDOEXM: Add Associated External Account permission to existing mailbox


    If you ever tried to modify the msExchMailboxSecurityDescriptor attribute directory then you must be aware that this attribute exists on the user object in the Active Directory and stores a partial copy of the user's mailbox security descriptor. This attribute is not back linked to the user's mailbox security descriptor.

    If msExchMailboxSecurityDescriptor is modified directly, the actual mailbox security descriptor on the user's mailbox in the information store is not updated if the mailbox is already created. You can modify this attribute before mailbox is created and those permissions will retain even after the mailbox is created.

    To be able to modify this attribute for existing mailboxes you need to use CDOEXM and run the script on Exchange 2003 server itself. If the user's mailbox security descriptor is modified from ADUnC or as demonstrated in the code in this article, msExchMailboxSecurityDescriptor is automatically updated to reflect these changes

    Here is the code that I have used in a recent support case to add Associated External Account (AEA) permission. AEA permission require you to also assign Full Mailbox permission. This script will add both ACE to the mailbox.

    Option Explicit
    'Constant variable declarations
    'Used for Associate external account
    Const E2K_MB_FULL_MB_ACCESS = &H1
    Const E2K_MB_SEND_AS = &H2
    Const E2K_MB_READ_PERMISSIONS = &H20000
    Const E2K_MB_TAKE_OWNERSHIP = &H80000
    ' ********************************************************************
    ' Change these variables according to your environment.
    Const sUserADsPath = "LDAP://SERVER/CN=USER,CN=Users,DC=ExchangeLab,DC=com"
    Const sTrustee = "NT AUTHORITY\SELF"
    ' ********************************************************************
    Dim objUser
    Dim oSecurityDescriptor 
    Dim dacl 
    Dim ace 
    Dim bFound 
    bFound = False
    'Get directory user object.
    Set objUser = GetObject(sUserADsPath)
    ' Get the Mailbox security descriptor (SD).
    Set oSecurityDescriptor = objUser.MailboxRights
    ' Extract the Discretionary Access Control List (DACL) using the IADsSecurityDescriptor.
    ' Interface.
    Set dacl = oSecurityDescriptor.DiscretionaryAcl
    Set ace = CreateObject("AccessControlEntry")
    ' Add the modified DACL to the security descriptor.
    oSecurityDescriptor.DiscretionaryAcl = dacl
    ' Save new SD onto the user.
    objUser.MailboxRights = oSecurityDescriptor
    ' Commit changes from the property cache to the information store.
    wscript.echo "Done modifying the mailboxsecurity descriptor"
    '* Function AddAce(dacl, TrusteeName, gAccessMask, gAceType,
    '*          gAceFlags, gFlags, gObjectType, gInheritedObjectType)
    '* Purpose: Adds an ACE to a DACL
    '* Input:   dacl            Object's Discretionary Access Control List
    '*          TrusteeName     SID or Name of the trustee user account
    '*          gAccessMask     Access Permissions
    '*          gAceType        ACE Types
    '*          gAceFlags       Inherit ACEs from the owner of the ACL
    '*          gFlags          ACE has an object type or inherited object type
    '*          gObjectType     Used for Extended Rights
    '*          gInheritedObjectType
    '* Output:  Object - New DACL with the ACE added
    Function AddAce(dacl, TrusteeName, gAccessMask, gAceType, gAceFlags, gFlags, gObjectType, gInheritedObjectType)
        Dim Ace1
        ' Create a new ACE object.
        Set Ace1 = CreateObject("AccessControlEntry")
        Ace1.AccessMask = gAccessMask
        Ace1.AceType = gAceType
        Ace1.AceFlags = gAceFlags
        Ace1.Flags = gFlags
        Ace1.Trustee = TrusteeName
        'See whether ObjectType must be set
        If CStr(gObjectType) <> "0" Then
           Ace1.ObjectType = gObjectType
        End If
        'See whether InheritedObjectType must be set.
        If CStr(gInheritedObjectType) <> "0" Then
            Ace1.InheritedObjectType = gInheritedObjectType
        End If
        dacl.AddAce Ace1
        ' Destroy objects.
        Set Ace1 = Nothing
    End Function

    Known Limitations: This script will throw an error if the same permissions (Associated External Mailbox) already exist on the mailbox.

  • Jive into Messaging world

    HOWTO: WebDav: Exchange 2003: Poll for unread emails & notify admin if a predefined level is reached


    I think you may find it useful as well. I wrote this script to monitor a particular mailbox for unread emails count in a particular folder and notify people about it. It could be useful to monitor a service mailbox and make sure it does not have any email unprocessed after a certain period of time. You may schedule this script as job to run every hour or so and notify you if there were any unread emails pending in the inbox.

    Const strServer = "ExchangeServerName"                            ' Exchange 2003 Server's HOSTNAME/IPADDRESS
    Const strDomain = "ExchangeLab"                        ' Credentials to login to mailbox
    Const strUser = "Administrator"                        ' It could be credentials for the same mailbox
    Const strPass = "********"                            ' or the credentials of a service account which has access to all mailboxes
    Const strMailBox = "Administrator"                    ' Mailbox alias to login to
    Const strFrom = "administrator@exchangelab.com"        ' From address of sender, ideally should be same as the Mailbox
    Const strTo = "administrator@exchangelab.com"        ' Email sent TO
    Const strSubject = "Unread mails alert!"            ' Email's subject
    Const strBody = "You have {X} unread emails"         ' leave the {X} as is and this will be replaced with the actual number of unread message 
    Const SSL_Enabled = ""                                ' change this to "s" if you want to enable SSL (HTTPS)
    Const MaxUnreadAllowed = 10                            ' change it to maximum unread allowed in an inbox
    Const strLogFilePath = "C:\UnreadEmailMonitor.log"    ' Change to the file path where you want to save the log
    Dim xDoc
    Dim xNodes
    Dim strURL
    Dim strResponse
    Dim HttpWebRequest
    Dim strXMLRequest
    Dim strUnreadCount
    strXMLRequest = "<?xml version=""1.0""?>"
    strXMLRequest = strXMLRequest + "<D:propfind xmlns:D=""DAV:"" xmlns:z=""urn:schemas:httpmail:"">"
    strXMLRequest = strXMLRequest + "<D:prop><z:unreadcount/></D:prop>"
    strXMLRequest = strXMLRequest + "</D:propfind>"
    strURL = "http" & SSL_Enabled & "://" & strServer & "/Exchange/" & strMailBox & "/Inbox"
    Set HttpWebRequest = CreateObject("microsoft.xmlhttp")
    Set xDoc = CreateObject("MSXML.DOMDocument")
    HttpWebRequest.open "PROPFIND", strURL, False, strUser, strPass
    HttpWebRequest.setRequestHeader "Content-type:", "text/xml"
    HttpWebRequest.send strXMLRequest
    WriteLog "Polling unread count from mailbox : " & strMailBox
    If (HttpWebRequest.Status >= 200 And HttpWebRequest.Status < 300) Then
       WriteLog "Success downloading mailbox data"
    ElseIf HttpWebRequest.Status = 401 Then
       WriteLog "You don't have permission to connect to this mailbox: " & strMailBox
       WriteLog "Error downloading mailbox data. Status: " & HttpWebRequest.Status & ": " & HttpWebRequest.statusText
    End If
    strResponse = HttpWebRequest.responseText
    If xDoc.loadXML(strResponse) Then
    Dim startPos
    Dim endPos
    Dim ns
        endPos = InStr(strResponse, "=""urn:schemas:httpmail:")
        startPos = InStrRev(strResponse, "xmlns:", endPos) + 6
        ns = Mid(strResponse, startPos, endPos - startPos)
        strUnreadCount = xDoc.selectSingleNode("//" & ns & ":unreadcount").Text
    End If
    If strUnreadCount > MaxUnreadAllowed Then 
    WriteLog "Unread emails found: " & strUnreadCount & " , sending mail to " & strTo
    strURL = "http" & SSL_Enabled & "://" & strServer & "/Exchange/" & strUser & "/##DavMailSubmissionURI##"
    HttpWebRequest.open "PUT", strURL, False, strDomain & "\" & strUser, strPass
    strXMLRequest = "From: " & strFrom & vbNewLine & _
    "To: " & strTo & vbNewLine & _
    "Subject: " & strSubject & vbNewLine & _
    "Date: " & Now() & vbNewLine & _
    "X-Mailer: Mailbox Polling Application" & vbNewLine & _
    "MIME-Version: 1.0" & vbNewLine & _
    "Content-Type: text/html" & vbNewLine & _
    "Charset = ""iso-8859-1""" & vbNewLine & _
    "Content-Transfer-Encoding: 7bit" & vbNewLine & vbNewLine & _
    Replace(strBody, "{X}", strUnreadCount)
    HttpWebRequest.setRequestHeader "Translate", "f"
    HttpWebRequest.setRequestHeader "Content-Type", "message/rfc822"
    HttpWebRequest.setRequestHeader "Content-Length", "" & Len(strXMLRequest)
    HttpWebRequest.send strXMLRequest
     If (HttpWebRequest.Status >= 200 And HttpWebRequest.Status < 300) Then
       WriteLog "Message successfully sent."
     ElseIf HttpWebRequest.Status = 401 Then
       WriteLog "You don't have permission to send the Message."
       WriteLog "Message not successfully sent. Status: " & HttpWebRequest.Status & ": " & HttpWebRequest.statusText
     End If
    End If
    Private Sub WriteLog(ByVal sText)
        Dim objFSO
        Dim objTextFile
        Const ForAppending = 8
        Set objFSO = CreateObject("Scripting.FileSystemObject")
        Set objTextFile = objFSO.OpenTextFile(strLogFilePath, ForAppending, True)
        ' Write a line.
        objTextFile.Write (sText & vbCRLFde)
    End Sub 
Page 1 of 1 (4 items)