Microsoft KB Archive/930879: Difference between revisions

From BetaArchive Wiki
m (Text replacement - "<" to "<")
m (Text replacement - ">" to ">")
Line 297: Line 297:
<div class="indent">
<div class="indent">


<p><code>User_DN</code><\TAB &gt;<code>CDO_Time_Zone</code><\TAB&gt;<code>Outlook Web Access_Time_Zone</code><\TAB&gt;<code>Outlook_Time_Zone</code><\TAB &gt;<code>Recurring_Meeting_Time_Zone</code><\CRLF&gt;</p>
<p><code>User_DN</code><\TAB ><code>CDO_Time_Zone</code><\TAB><code>Outlook Web Access_Time_Zone</code><\TAB><code>Outlook_Time_Zone</code><\TAB ><code>Recurring_Meeting_Time_Zone</code><\CRLF></p>


</div>
</div>
Line 322: Line 322:
<div class="indent">
<div class="indent">


<p><code>User_DN</code><\TAB&gt;<code>Server_Friendly_Name</code><\TAB&gt;<code>OS_Time Zone_Registry_Key</code><\CRLF&gt;</p>
<p><code>User_DN</code><\TAB><code>Server_Friendly_Name</code><\TAB><code>OS_Time Zone_Registry_Key</code><\CRLF></p>


</div>
</div>
Line 835: Line 835:
End Select
End Select


If (cScriptMode = MODE_INVALID Or dArgCount <&gt; dArgExpected) Then
If (cScriptMode = MODE_INVALID Or dArgCount <> dArgExpected) Then
     DisplaySyntax
     DisplaySyntax
End If
End If
Line 856: Line 856:
     objconn.Provider = &quot;ADSDSOObject&quot;
     objconn.Provider = &quot;ADSDSOObject&quot;
     objconn.Open &quot;ADs Provider&quot;
     objconn.Open &quot;ADs Provider&quot;
     If (err.number <&gt; 0) Then
     If (err.number <> 0) Then
         WScript.StdOut.WriteLine(&quot;Failed to bind to Active Directory server, error:&quot; &amp; err.Description)
         WScript.StdOut.WriteLine(&quot;Failed to bind to Active Directory server, error:&quot; &amp; err.Description)
         objfileError.WriteLine(&quot;Failed to bind to Active Directory server, error:&quot; &amp; err.Description)
         objfileError.WriteLine(&quot;Failed to bind to Active Directory server, error:&quot; &amp; err.Description)
Line 864: Line 864:
     Set rootDSE = GetObject(&quot;LDAP://rootDSE&quot;)
     Set rootDSE = GetObject(&quot;LDAP://rootDSE&quot;)
     sDomainContainer = rootDSE.Get(&quot;defaultNamingContext&quot;)
     sDomainContainer = rootDSE.Get(&quot;defaultNamingContext&quot;)
     If (err.number <&gt; 0) Then
     If (err.number <> 0) Then
         WScript.StdOut.WriteLine(&quot;Failed to find a Domain Container:&quot; &amp; err.Description)
         WScript.StdOut.WriteLine(&quot;Failed to find a Domain Container:&quot; &amp; err.Description)
         objfileError.WriteLine(&quot;Failed to find a Domain Container:&quot; &amp; err.Description)
         objfileError.WriteLine(&quot;Failed to find a Domain Container:&quot; &amp; err.Description)
Line 872: Line 872:
     Set objCommand.ActiveConnection = objconn
     Set objCommand.ActiveConnection = objconn


     Do While objfileImport.AtEndOfStream <&gt; True
     Do While objfileImport.AtEndOfStream <> True
         fOneError = False
         fOneError = False
         sUserLDAPPath = EMPTYSTRING
         sUserLDAPPath = EMPTYSTRING
Line 878: Line 878:


         sOneRow = Trim(objfileImport.ReadLine)
         sOneRow = Trim(objfileImport.ReadLine)
         If sOneRow <&gt; EMPTYSTRING Then
         If sOneRow <> EMPTYSTRING Then
          
          
             sUserLDAPPath = GetLDAPPathFromLegacyDN(sOneRow)
             sUserLDAPPath = GetLDAPPathFromLegacyDN(sOneRow)
             If (err.number <&gt; 0) Then
             If (err.number <> 0) Then
                 objfileError.WriteLine(&quot;Failed to get user's LDAP path from &quot; &amp; sOneRow)
                 objfileError.WriteLine(&quot;Failed to get user's LDAP path from &quot; &amp; sOneRow)
                 fOneError = True
                 fOneError = True
Line 889: Line 889:
             If (fOneError = False) Then
             If (fOneError = False) Then
                 Set objUser = GetObject(sUserLDAPPath)
                 Set objUser = GetObject(sUserLDAPPath)
                 If (err.number <&gt; 0) Then
                 If (err.number <> 0) Then
                     objfileError.WriteLine(&quot;Failed to get user object from &quot; &amp; sUserLDAPPath)
                     objfileError.WriteLine(&quot;Failed to get user object from &quot; &amp; sUserLDAPPath)
                     objfileError.WriteLine(&quot;Error: &quot; &amp; err.Description)
                     objfileError.WriteLine(&quot;Error: &quot; &amp; err.Description)
Line 902: Line 902:
                 Set objSDNTsecurity = objUser.ntSecurityDescriptor
                 Set objSDNTsecurity = objUser.ntSecurityDescriptor
                 Set objDACLNT = objSDNTsecurity.DiscretionaryAcl
                 Set objDACLNT = objSDNTsecurity.DiscretionaryAcl
                 If (err.number <&gt; 0) Then
                 If (err.number <> 0) Then
                     objfileError.WriteLine(&quot;Failed to get DACL of &quot; &amp; sUserLDAPPath)
                     objfileError.WriteLine(&quot;Failed to get DACL of &quot; &amp; sUserLDAPPath)
                     objfileError.WriteLine(&quot;Error: &quot; &amp; err.Description)
                     objfileError.WriteLine(&quot;Error: &quot; &amp; err.Description)
Line 919: Line 919:
                 CheckFullMailboxAccess objDACLEX, sGrantedUser, fFMA, AccessTypeForFMA
                 CheckFullMailboxAccess objDACLEX, sGrantedUser, fFMA, AccessTypeForFMA
                 CheckSendAs objDACLNT, sGrantedUser, fSendAs, AccessTypeForSendAS
                 CheckSendAs objDACLNT, sGrantedUser, fSendAs, AccessTypeForSendAS
                 If (err.number <&gt; 0) Then
                 If (err.number <> 0) Then
                     objfileError.WriteLine(&quot;Failed to Check permission of &quot; &amp; sUserLDAPPath)
                     objfileError.WriteLine(&quot;Failed to Check permission of &quot; &amp; sUserLDAPPath)
                     objfileError.WriteLine(&quot;Error: &quot; &amp; err.Description)
                     objfileError.WriteLine(&quot;Error: &quot; &amp; err.Description)
Line 944: Line 944:
                     objSDMailbox.DiscretionaryAcl = objDACLEX
                     objSDMailbox.DiscretionaryAcl = objDACLEX
                     objUser.MailboxRights = Array(objSDMailbox)
                     objUser.MailboxRights = Array(objSDMailbox)
                     If ( err.number <&gt; 0 ) Then
                     If ( err.number <> 0 ) Then
                         objfileError.WriteLine(&quot;Failed to add FullMailbox Access: &quot; &amp; sUserLDAPPath)
                         objfileError.WriteLine(&quot;Failed to add FullMailbox Access: &quot; &amp; sUserLDAPPath)
                         objfileError.WriteLine(&quot;Error: &quot; &amp; err.Description)
                         objfileError.WriteLine(&quot;Error: &quot; &amp; err.Description)
Line 962: Line 962:
                     objUser.Put &quot;ntSecurityDescriptor&quot;, Array( objSDNTsecurity )
                     objUser.Put &quot;ntSecurityDescriptor&quot;, Array( objSDNTsecurity )
                     objUser.SetOption ADS_OPTION_SECURITY_MASK, ADS_SECURITY_INFO_DACL
                     objUser.SetOption ADS_OPTION_SECURITY_MASK, ADS_SECURITY_INFO_DACL
                     If ( err.number <&gt; 0 ) Then
                     If ( err.number <> 0 ) Then
                         objfileError.WriteLine(&quot;Failed to add SendAs permission: &quot; &amp; sUserLDAPPath)
                         objfileError.WriteLine(&quot;Failed to add SendAs permission: &quot; &amp; sUserLDAPPath)
                         objfileError.WriteLine(&quot;Error: &quot; &amp; err.Description)
                         objfileError.WriteLine(&quot;Error: &quot; &amp; err.Description)
Line 975: Line 975:
                 If (fOneError = False ) Then  
                 If (fOneError = False ) Then  
                     objUser.SetInfo
                     objUser.SetInfo
                     If (err.number <&gt; 0) Then
                     If (err.number <> 0) Then
                         objfileError.WriteLine(&quot;Failed to update user: &quot; &amp; sUserLDAPPath)
                         objfileError.WriteLine(&quot;Failed to update user: &quot; &amp; sUserLDAPPath)
                         objfileError.WriteLine(&quot;Error: &quot; &amp; err.Description)
                         objfileError.WriteLine(&quot;Error: &quot; &amp; err.Description)
Line 1,016: Line 1,016:
     End If
     End If
      
      
     Do While objfileImport.AtEndOfStream <&gt; True
     Do While objfileImport.AtEndOfStream <> True
         fOneError = False
         fOneError = False
         sUserLDAPPath = EMPTYSTRING
         sUserLDAPPath = EMPTYSTRING
Line 1,036: Line 1,036:


         Set objUser = GetObject(sUserLDAPPath)
         Set objUser = GetObject(sUserLDAPPath)
         If (err.number <&gt; 0) Then
         If (err.number <> 0) Then
             objfileError.WriteLine(&quot;Failed to get user object from &quot; &amp; sUserLDAPPath)
             objfileError.WriteLine(&quot;Failed to get user object from &quot; &amp; sUserLDAPPath)
             objfileError.WriteLine(&quot;Error: &quot; &amp; err.Description)
             objfileError.WriteLine(&quot;Error: &quot; &amp; err.Description)
Line 1,047: Line 1,047:
             Set objDACLEX = objSDMailbox.DiscretionaryAcl
             Set objDACLEX = objSDMailbox.DiscretionaryAcl
             fRemovedFMA = RemoveFullMailboxAccess(objDACLEX, sGrantedUser)
             fRemovedFMA = RemoveFullMailboxAccess(objDACLEX, sGrantedUser)
             If (err.number <&gt; 0) Then
             If (err.number <> 0) Then
                 objfileError.WriteLine(&quot;Failed to Remove Full MailboxAccess from &quot; &amp; sUserLDAPPath)
                 objfileError.WriteLine(&quot;Failed to Remove Full MailboxAccess from &quot; &amp; sUserLDAPPath)
                 objfileError.WriteLine(&quot;Error: &quot; &amp; err.Description)
                 objfileError.WriteLine(&quot;Error: &quot; &amp; err.Description)
Line 1,069: Line 1,069:


             fRemovedSendAs = RemoveSendAs(objDACLNT, sGrantedUser)
             fRemovedSendAs = RemoveSendAs(objDACLNT, sGrantedUser)
             If (err.number <&gt; 0) Then
             If (err.number <> 0) Then
                 objfileError.WriteLine(&quot;Failed to Remove SendAs from &quot; &amp; sUserLDAPPath)
                 objfileError.WriteLine(&quot;Failed to Remove SendAs from &quot; &amp; sUserLDAPPath)
                 objfileError.WriteLine(&quot;Error: &quot; &amp; err.Description)
                 objfileError.WriteLine(&quot;Error: &quot; &amp; err.Description)
Line 1,089: Line 1,089:
         If ((fOneError = False) And (fRemovedFMA Or fRemovedSendAs)) Then
         If ((fOneError = False) And (fRemovedFMA Or fRemovedSendAs)) Then
             objUser.SetInfo
             objUser.SetInfo
             If (err.number <&gt; 0) Then
             If (err.number <> 0) Then
                 objfileError.WriteLine(&quot;Failed to update ADSI for user: &quot; &amp; sUserLDAPPath)
                 objfileError.WriteLine(&quot;Failed to update ADSI for user: &quot; &amp; sUserLDAPPath)
                 objfileError.WriteLine(&quot;Error: &quot; &amp; err.Description)
                 objfileError.WriteLine(&quot;Error: &quot; &amp; err.Description)
Line 1,142: Line 1,142:
     End If   
     End If   


     If (err.number <&gt; 0) Then
     If (err.number <> 0) Then
         objfileError.WriteLine(&quot;Check SendAs permissions Failed : &quot; &amp; sUser)
         objfileError.WriteLine(&quot;Check SendAs permissions Failed : &quot; &amp; sUser)
         objfileError.WriteLine(&quot;Error: &quot; &amp; err.Description)
         objfileError.WriteLine(&quot;Error: &quot; &amp; err.Description)
Line 1,161: Line 1,161:
     If intACECount Then
     If intACECount Then
         For Each objACE In objACL
         For Each objACE In objACL
             If ( (UCase(objACE.Trustee) = UCase(sUser)) And ((objACE.AccessMask And EX_FULLMAILBOX_ACCESSMASK) <&gt; 0)) Then
             If ( (UCase(objACE.Trustee) = UCase(sUser)) And ((objACE.AccessMask And EX_FULLMAILBOX_ACCESSMASK) <> 0)) Then
                 fFoundFMA = True
                 fFoundFMA = True
                 AccessType = objACE.AceType
                 AccessType = objACE.AceType
Line 1,168: Line 1,168:
     End If
     End If


     If (err.number <&gt; 0) Then
     If (err.number <> 0) Then
         objfileError.WriteLine(&quot;Check FullMailbox permissions Failed : &quot; &amp; sUser)
         objfileError.WriteLine(&quot;Check FullMailbox permissions Failed : &quot; &amp; sUser)
         objfileError.WriteLine(&quot;Error: &quot; &amp; err.Description)
         objfileError.WriteLine(&quot;Error: &quot; &amp; err.Description)
Line 1,207: Line 1,207:
     If intACECount Then
     If intACECount Then
         For Each objACE In objACL
         For Each objACE In objACL
             If((0 <&gt; Instr(UCase(objACE.Trustee), UCase(sUser))) And (objACE.AccessMask And EX_FULLMAILBOX_ACCESSMASK) <&gt; 0) Then
             If((0 <> Instr(UCase(objACE.Trustee), UCase(sUser))) And (objACE.AccessMask And EX_FULLMAILBOX_ACCESSMASK) <> 0) Then
                 objACE.AccessMask = (objACE.AccessMask Xor EX_FULLMAILBOX_ACCESSMASK)
                 objACE.AccessMask = (objACE.AccessMask Xor EX_FULLMAILBOX_ACCESSMASK)
                 fFound = True
                 fFound = True
Line 1,221: Line 1,221:
     Dim sLdapPath
     Dim sLdapPath
      
      
     objCommand.CommandText = &quot;<GC://&quot; &amp; sDomainContainer &amp; &quot;&gt;;(&amp;(&amp;(&amp; (mailnickname=*) (| (&amp;(objectCategory=person)(objectClass=user)(legacyExchangeDN=&quot; &amp; sLegacyDN &amp; &quot;)) ))));adspath;subtree&quot;
     objCommand.CommandText = &quot;<GC://&quot; &amp; sDomainContainer &amp; &quot;>;(&amp;(&amp;(&amp; (mailnickname=*) (| (&amp;(objectCategory=person)(objectClass=user)(legacyExchangeDN=&quot; &amp; sLegacyDN &amp; &quot;)) ))));adspath;subtree&quot;
     objCommand.Properties(&quot;searchscope&quot;) = ADS_SCOPE_SUBTREE
     objCommand.Properties(&quot;searchscope&quot;) = ADS_SCOPE_SUBTREE
     objCommand.Properties(&quot;Page Size&quot;) = 10
     objCommand.Properties(&quot;Page Size&quot;) = 10
Line 1,229: Line 1,229:
     err.Clear   
     err.Clear   
     Set rsUsers = objCommand.Execute
     Set rsUsers = objCommand.Execute
     If (err.number <&gt; 0) Then
     If (err.number <> 0) Then
         objfileError.WriteLine(&quot;Search for mailbox owners failed, error:&quot; &amp; err.Description)
         objfileError.WriteLine(&quot;Search for mailbox owners failed, error:&quot; &amp; err.Description)
         fOneError = True
         fOneError = True
Line 1,239: Line 1,239:
     End If
     End If


     If (rsUsers.RecordCount &gt; 1) Then
     If (rsUsers.RecordCount > 1) Then
         objfileError.WriteLine(&quot;Multiple mailboxs owner user accounts found for &quot; &amp; sLegacyDN &amp; &quot; in &quot; &amp; sDomainContainer &amp; &quot;.&quot;)
         objfileError.WriteLine(&quot;Multiple mailboxs owner user accounts found for &quot; &amp; sLegacyDN &amp; &quot; in &quot; &amp; sDomainContainer &amp; &quot;.&quot;)
         fOneError = True         
         fOneError = True         
Line 1,299: Line 1,299:
     End If
     End If


     If (sOutputFileName <&gt; EMPTYSTRING) Then
     If (sOutputFileName <> EMPTYSTRING) Then
         'Check if output file already exists.
         'Check if output file already exists.
         If (objFSO.FileExists(sOutputFileName)) Then
         If (objFSO.FileExists(sOutputFileName)) Then
Line 1,305: Line 1,305:
             sOneRow = objfileOutput.ReadLine
             sOneRow = objfileOutput.ReadLine
             'If user name in the file is different from parameter, we can't proceed.
             'If user name in the file is different from parameter, we can't proceed.
             If ( sOneRow <&gt; sGrantedUser ) Then
             If ( sOneRow <> sGrantedUser ) Then
                 WScript.StdOut.WriteLine(&quot;The Domain\User must be the same as &quot; &amp; sOneRow )
                 WScript.StdOut.WriteLine(&quot;The Domain\User must be the same as &quot; &amp; sOneRow )
                 WScript.Quit
                 WScript.Quit
Line 1,317: Line 1,317:
     End If
     End If
      
      
     If (err.number <&gt; 0) Then
     If (err.number <> 0) Then
         WScript.StdOut.WriteLine(&quot;Failed to open Log file, error:&quot; &amp; err.Description)
         WScript.StdOut.WriteLine(&quot;Failed to open Log file, error:&quot; &amp; err.Description)
         WScript.Quit
         WScript.Quit
Line 1,333: Line 1,333:
     Ace1.Trustee = TrusteeName
     Ace1.Trustee = TrusteeName
     'Determine whether ObjectType has to be set
     'Determine whether ObjectType has to be set
     If CStr(gObjectType) <&gt; &quot;0&quot; Then
     If CStr(gObjectType) <> &quot;0&quot; Then
         Ace1.ObjectType = gObjectType
         Ace1.ObjectType = gObjectType
     End If
     End If


     'Determine whether InheritedObjectType has to be set.
     'Determine whether InheritedObjectType has to be set.
     If CStr(gInheritedObjectType) <&gt; &quot;0&quot; Then
     If CStr(gInheritedObjectType) <> &quot;0&quot; Then
         Ace1.InheritedObjectType = gInheritedObjectType
         Ace1.InheritedObjectType = gInheritedObjectType
     End If
     End If

Revision as of 09:26, 21 July 2020

Knowledge Base


Using the Exchange Calendar Update Tool to address daylight saving time changes for Exchange Server

Article ID: 930879

Article Last Modified on 10/31/2007



APPLIES TO

  • Microsoft Exchange Server 2007 Enterprise Edition
  • Microsoft Exchange Server 2007 Standard Edition
  • Microsoft Exchange Server 2003 Enterprise Edition
  • Microsoft Exchange Server 2003 Standard Edition
  • Microsoft Exchange 2000 Enterprise Server
  • Microsoft Exchange 2000 Server Standard Edition



Important The update that is described in this Microsoft Knowledge Base article has been replaced by the update that is described in Microsoft Knowledge Base article 941018. To make sure that Windows has the latest time-zone data, install the update that is described in Microsoft Knowledge Base article 941018. You do not have to uninstall the update that is described in this Microsoft Knowledge Base article before you install the update that is described in Microsoft Knowledge Base article 941018.

For more information, click the following article number to view the article in the Microsoft Knowledge Base:

941018 How to address daylight saving time by using the Exchange Calendar Update Tool


INTRODUCTION

Daylight saving time is a system of setting clocks ahead so that both sunrise and sunset occur at a later hour. The effect is additional daylight in the evening. Many countries observe daylight saving time, although most have their own rules and regulations for when it begins and ends. The dates of daylight saving time (otherwise known as DST) may change year to year, and users have to update their Microsoft Office Outlook calendar every time that the DST law or rules change. The dates between the previous DST rules and the current DST rules are referred to in this article as the "extended DST period."

This article focuses on the actions that you can take to address calendar items in Microsoft Outlook that occur during the extended DST period.

For more information about how to prepare for changes in daylight saving time in 2007 (DST 2007) for all affected Microsoft products, visit the following Microsoft Web site:

This article focuses on the actions that should be taken to update calendar items that are stored in Microsoft Exchange Server according to the new DST rules. The solution that is presented in this article involves the Exchange Calendar Update Tool (“the Exchange tool”). The Exchange tool relies on the Time Zone Data Update Tool for Microsoft Office Outlook (“the Outlook tool”).
For more information about the Outlook tool, click the following article number to view the article in the Microsoft Knowledge Base:

931667 How to address the daylight saving time changes in 2007 by using the Time Zone Data Update Tool for Microsoft Office Outlook


About the Exchange tool

After you install the DST updates for Microsoft Windows, all old appointments that occur during the DST change periods will be incorrectly displayed as occurring one hour later. This is true for both recurring and single-instance appointments. These appointments must be updated so that they will be displayed correctly in Outlook, in Outlook Web Access, and in CDO-based applications.

Outlook provides a tool that is named the Time Zone Data Update Tool for Microsoft Office Outlook . This tool enables users to update their own calendars.

Note In Microsoft Office Outlook 2007, the Time Zone Data Update Tool is built in. However, we recommend that you use the stand-alone version of the Time Zone Data Update Tool.

931667 How to address the daylight saving time changes in 2007 by using the Time Zone Data Update Tool for Microsoft Office Outlook


The Exchange Calendar Update Tool ("the Exchange tool") enables you to avoid the challenges that are involved when you deploy the Outlook tool widely to all users and enables you to make sure that each user runs the tool correctly.

High-level description of the Exchange tool

The Exchange tool consists of two separate executable files. These files are described in the following table.

File name Description
Msextmz.exe This executable program extracts time zone information from mailboxes on a server that is running Exchange Server. This executable program also updates mailbox calendars for a specified list of users by invoking the Outlook tool against each specified user.
Msextmzcfg.exe This executable program is a configuration tool that performs most of the steps that are involved in updating an Exchange Server server.

Version 2 of the Exchange tool

Version 2 of the Exchange Calendar Update Tool was released on February 21, 2007. This article refers to version 2 of the Exchange tool. If you are running version 1 of the Exchange tool, uninstall it and install version 2. Version 2 of the Exchange tool includes the following improvements:

  • Performance in version 2 is twice as fast as version 1 when you run the tool in Update mode.
  • User interface is improved.
  • Memory leak is fixed that required client computers to be frequently restarted.
  • Improved algorithm is included for mapping extracted time zones to the operating system time zone.

Risks and limitations of running the Exchange tool

There are two issues to consider before you run the Exchange tool. The following table lists these issues, their potential effects on the IT infrastructure, and on users and their mitigation strategies.

Risk Effect Mitigation
There are lots of meeting updates. Server and network performance is decreased. Determine what the effect on the server and network performance may be by updating a small batch of users first. If the load is disruptive, run the tool during off-peak hours or during dedicated maintenance hours.
The tool takes too long to run. MSXTMZ.exe is single threaded. If you run this file in Update mode against several thousand users at the same time, the Exchange tool may take many hours or possibly days to finish. To speed up the update process for all mailboxes, divide the users into batches, and then update each batch of users by using a separate instance of MSXTMZ.exe on a separate computer.

Options for updating mailboxes

The following table lists five options that can be used to update user mailboxes to use the DST 2007 time zone rules.

Option Pros Cons
Distribute the Outlook tool to each user, and then instruct users to update their own mailboxes. This option avoids the risks and limitations of running the Exchange tool. It is difficult to guarantee that all users will run the Outlook tool correctly and in a timely manner. Users who do not have Outlook will be unable to run the Outlook tool. An additional educational effort is needed to lessen confusion for users.
Run the Exchange tool against all affected users and servers. This option provides a streamlined experience for users. There are issues associated with running the Exchange tool, as described in the previous table.
Run the Exchange tool and update only recurring appointments. Let users update single-instance appointments in their own mailboxes by using the Outlook tool. There is less risk involved of single-instance appointments being incorrectly updated. The cons of running the Outlook tool are combined with the cons of running the Exchange tool.
Run neither the Exchange tool nor the Outlook tool. Ask users to examine their calendars and re-book appointments as needed. This option avoids the issues of running the Exchange tool. Unless all users re-book all affected appointments, some calendar items will be one hour off during the extended DST period. An additional educational effort is needed to lessen confusion for users.
Distribute the Outlook tool to each user, and then instruct users to update their own mailboxes. Then, use the Time Zone Extraction Mode of the Exchange tool to determine whether users are running the Outlook tool. If the users are not running the Outlook tool, the administrator can run the Exchange tool. This option reduces the risk of users not running the tool in a timely manner, and avoids the issues of running the Exchange tool. This is not an option if users are running Outlook 2007.

How to install the Exchange tool

The Exchange Calendar Update Tool is available in the form of the self-extracting executable file Msextmz.exe.

After installation, the files in the installation directory should include the following files:

  • Msextmz.exe
  • Msextmzcfg.exe
  • Msextmz.ini


This file is the master .ini file that documents all parameters that are used by Msextmz.exe.

  • Msextmzcfg.xml


This file is the time zone mapping file that maps Outlook, CDO, and Outlook Web Access time zones to operating system time zones.

For more information about the latest version of the Exchange Calendar Update tool, click the following article number to view the article in the Microsoft Knowledge Base:

941018 How to address daylight saving time by using the Exchange Calendar Update Tool


Languages that are supported by the Exchange tool

The Exchange tool is available only in English. The tool will run only on an English (US) computer.

Versions of Exchange Server that are compatible with the Exchange tool

The Exchange tool can update mailboxes on the following versions of Exchange Server:

  • Microsoft Exchange Server 2007 Enterprise Edition
  • Microsoft Exchange Server 2007
  • Microsoft Exchange Server 2007 Standard Edition
  • Microsoft Exchange Server 2003
  • Microsoft Exchange Server 2003 Enterprise Edition
  • Microsoft Exchange 2000 Server
  • Microsoft Exchange Server 2003 Standard Edition
  • Microsoft Exchange 2000 Server Enterprise Edition
  • Microsoft Exchange 2000 Server Standard Edition

Operating systems that are supported by the Exchange tool

The Exchange tool will run on the following operating systems:

  • Microsoft Windows Server 2003
  • Microsoft Windows XP
  • Microsoft Windows 2000

Windows Vista is not supported.

What to do before you run the Exchange tool

Install updates

Before you run the Exchange tool, make sure that client and server computers are updated correctly with the following updates:

  1. Install the Windows daylight saving time update on client and server computers. For more information about how to update a computer that is running Windows operating system software, click the following article number to view the article in the Microsoft Knowledge Base:

    933360 August 2007 cumulative time zone update for Microsoft Windows operating systems

  2. For Exchange 2003 SP2, install the following update that is relevant to your organization:
    • 911829 You receive an error message when you try to perform any editing tasks, or you must click to enable the compose frame in Outlook Web Access

    • 924334 The Compose Message form stops responding after you install Internet Explorer 7.0 and the S/MIME control on an Outlook Web Access client in Exchange Server 2003

    Note This step can be completed at the same time as step 1.

Verify the system requirements

The Exchange tool must be run on a computer that has Microsoft Office Outlook 2003 or Microsoft Office Outlook 2007 installed, and that has the Outlook Time Zone Data Tool installed. Additionally, Microsoft .NET Framework Version 2.0 must be installed on the client computer.

Outlook and the Zone Data Update Tool for Microsoft Office Outlook are not part of the Exchange tool download package. They have to be installed separately.

Note Do not confuse the Outlook tool installer package that is named Tzmove.exe with the actual Outlook tool executable file that is also named Tzmove.exe.

To run the Exchange tool successfully, the computer must not have the PickLogonProfile registry value set. Alternatively, this registry value must be set to 0. To determine whether this registry value exists, follow these steps.

Important This section, method, or task contains steps that tell you how to modify the registry. However, serious problems might occur if you modify the registry incorrectly. Therefore, make sure that you follow these steps carefully. For added protection, back up the registry before you modify it. Then, you can restore the registry if a problem occurs. For more information about how to back up and restore the registry, click the following article number to view the article in the Microsoft Knowledge Base:

322756 How to back up and restore the registry in Windows XP and Windows Vista


Warning Serious problems might occur if you modify the registry incorrectly by using Registry Editor or by using another method. These problems might require that you reinstall the operating system. Microsoft cannot guarantee that these problems can be solved. Modify the registry at your own risk.

  1. Click Start, click Run, type regedit, and then click OK.
  2. Expand the following subkey:

    HKEY_CURRENT_USER\Software\Microsoft\Exchange\client\options\

  3. Click options, and then determine whether the PickLogonProfile value exists. If the PickLogonProfile value exists and is set to 1, set the value to 0. To do this, follow these steps:
    1. Right-click PickLogonProfile, and then click Modify.
    2. In the Value data box, type 0, and then click OK.

The Exchange tool cannot be run on a computer that is running Exchange Server or the Exchange System Management tools. If you try to install the Exchange tool on a computer that is running Exchange Server or the Exchange System Management tools, you receive the following error message:

Microsoft Exchange Calendar Update Tool cannot be installed with Microsoft Exchange.

How to manually configure and run Msextmz.exe

Configure the Msextmz.ini file

The Msextmz.ini file must be configured correctly for Msextmz.exe to run correctly. We recommend that you read the comments in the Msextmz.ini file carefully before you modify the Msextmz.ini file.

Specify the Msextmz.exe execution mode

Msextmz.exe runs in two modes. To specify the mode of execution, specific parameters have to be set in the Msextmz.ini file. The following list describes the three modes and describes how to configure the modes in the Msextmz.ini file.

  • Time Zone Extraction

    In this mode, Msextmz.exe extracts time zone information from each mailbox by reading a set of MAPI properties.

    Msextmz.exe can examine recurring appointments that are organized by the user in the user’s calendar and then try to determine a time zone for the user. However, this option is resource-intensive. By default, therefore, this option is not enabled. To enable this option, set the ReadCalendarTimezones parameter in the Msextmz.ini file.

    Msextmz.exe records the time zone information for each user in an output file that contains a list of mailbox legacy DNs. Each mailbox legacy DN has the following types of time zone values:
    • Outlook Web Access Time Zone
    • CDO Time Zone
    • Outlook Time Zone
    • Recurring Meeting Time Zone

    The format of the file uses the following format:

    User_DN<\TAB >CDO_Time_Zone<\TAB>Outlook Web Access_Time_Zone<\TAB>Outlook_Time_Zone<\TAB >Recurring_Meeting_Time_Zone<\CRLF>

    If Msextmz.exe cannot extract time zone information for any of the four types of time zones, the mailbox legacy DN will be logged in the error file.

    To map the user to only one time zone, you must import the output file to Microsoft Excel. In Excel, filter the list of users according to one of the time zones. The time zone that you use depends on your environment.

    For example, if most users use BlackBerry devices, Exchange 5.5 Outlook Web Access, or other CDO-based solutions, filter the list by CDO Time Zone. If most users use Exchange Outlook Web Access, filter the list by Outlook Web Access Time Zone. If most users do not fit into one of these scenarios, filter the list by Recurring Meeting Time Zone.

    To run the tool in Time Zone Extraction mode, configure the .ini file as follows:

    • Leave the CommandLine parameter uncommented.
    • Set the OutputFile parameter.
    • Set the ErrorFile parameter.
    • Set the ServerDN parameter.
    • Set the Profile parameter.
    • Set the LogFile parameter.
    • Set the ExportTimezones parameter to 1.
    • Comment out the rest of the parameters in the .ini file.
  • Update

    In this mode, Msextmz.exe will update all mailboxes that are specified in an input file. The input file should be in the following format:

    User_DN<\TAB>Server_Friendly_Name<\TAB>OS_Time Zone_Registry_Key<\CRLF>

    Only one instance of Msextmz.exe can run on one client. However, Msextmz.exe can be run on multiple clients at the same time.

    To run Msextmz.exe in this mode, you must configure the Msextmz.ini file as follows:

    • Make sure that the CommandLine parameter is uncommented and points to the correct location of Tzmove.exe.
    • Set the InputFile parameter.
    • Comment out the OutputFile parameter.
    • Set the ErrorFile parameter.
    • Set the ServerDN parameter.
    • Set the LogFile parameter.
    • Set the LogDirectory parameter.
    • Comment out the ExportTimezones parameter.
    • Uncomment remaining parameters.

    In Update mode, Msextmz.exe can accept an input file that contains users on different Exchange servers. The .ini setting requires that you provide the DN of an Exchange server. In this case, you only have to specify a server DN of an Exchange server in the Exchange organization.

    To update recurring appointments only, configure the CommandLine parameter with the following value:

    tzmove.exe /q /onlyrecurring

    To update both recurring and single-instance appointments, use the default CommandLine value.

Configure permissions for Msextmz.exe

The permissions that are required to run Msextmz.exe depend on the execution mode that is used. The following table lists the permissions that are needed for each execution mode.

Execution mode Permissions
Time Zone Extraction Exchange View-Only Administrator

Local administrator of the computer that is running Msextmz.exe

Update Domain user who has Full Mailbox Access and Send As rights to all mailboxes

Local administrator of the computer that is running Msextmz.exe

"Grant Mailbox Permission" script

You can use the sample GrantMailboxPermission.vbs script to grant a domain user Full Mailbox Access and Send As rights to all mailboxes.

This script can be run only by an Exchange administrator on a computer that is running Exchange 2000 Server or Exchange Server 2003. This script cannot be run on a computer that is running Exchange Server 2007. However, you can use the Exchange Management Shell to grant the necessary permissions.

The code for the VBS script is provided in the "References" section. The following table describes the two modes in which this script runs.

Mode Command line Description
Add CScript GrantMailboxPermission.vbs –add Domain_Name\User_Name File_Name Grants Domain_Name\User_Name Full Mailbox Access and Send As rights to user mailboxes that are listed in the input file. The input file must be a text file that contains legacy DNs of the user mailboxes that are delimited by CRLF.


The script generates a GrantMailboxPermission.log file. This file is a record of the mailboxes that were processed. The first line of the log file is the Domain_Name\User_Name user who is granted access. Do not delete this file. This file is used in the Remove mode.

If an explicit "deny" access has been assigned to the user, the script logs the information in a file that is named "GrantMailboxPermission.err." The script will not grant or change the permission.

If the user is part of a security group that has been assigned "deny" access, the script grants Full Mailbox Access and Send As permissions. However, the user will be unable to log on to the mailbox. All errors will be logged in the GrantMailboxPermission.err file.

Remove CScript GrantMailboxPermission.vbs –remove Removes Full Mailbox Access and Send As rights to mailboxes that are listed in the GrantMailboxPermission.log file from Domain_Name\User_Name. The Domain_Name\User_Name is specified in the GrantMailboxPermission.log file.

Note When you run this script on the computer that is running Exchange Server, the script returns a period (.) when the script successfully processes a user. The script returns an exclamation point (!) if it does not successfully process a user.

Note The output file of the Time Zone Extraction mode cannot be used as an input file for this script. To create the input file for this script, you can paste the contents of the Time Zone Extraction output file into Notepad, save the contents as a new document, and then use the new document as the input file.

How logging works in Update mode

Logs from the Outlook Time Zone Data Update tool

When the Outlook tool is run, the tool creates a log file in the temp directory. This file is named "Outlook Time Zone Update.log." Msextmz.exe extracts the information from "Outlook Time Zone Update.log," and then creates per-user log files in the directory that is specified in the LogDirectory of the .ini file.

These files are named by using the following format:

MSExTmz-User’s CN from the User DN-Random number.LOG


For example, the Outlook tool logs the following information:

MSExTmz-USER3-0x0131273E.LOG


The Outlook tool does this when it processes a user who has the following DN:

/O=FIRST ORGANIZATION/OU=FIRST ADMINISTRATIVE GROUP/CN=RECIPIENTS/CN=USER3


Error file

If Msextmz.exe is unable to run the Outlook tool against any mailbox, the DN of the user will be logged in the error file. Msextmz.exe will not log anything to the error file if the Outlook tool ran successfully.

Log file

If the Log file option is configured in the Msextmz.ini file, the information output from Msextmz.exe to the Command Prompt window is also available in the specified file.

How to run Msextmzcfg.exe

Msextmzcfg.exe automates the process of extracting time zones, of resolving time zones for each user, and of generating the user lists and .ini files that are required to run Msextmzcfg.exe in Update mode. We recommend that you use Msextmzcfg.exe to perform these steps instead of performing them manually. This section describes how to run Msextmzcfg.exe.

Permissions that are required

The account that is used to run Msextmzcfg.exe must have the following permissions on the client:

  • Exchange View-Only Admin
  • Local administrator

Example of the process to update an Exchange server by using Msextmzcfg.exe

  1. On the client computer, create an Outlook profile that logs on to a mailbox that resides on the Exchange server that you are trying to update. Make sure that the profile is in Online mode, and then configure this profile to be the default profile.

    Note The Exchange server must support Online mode.
  2. Run Msextmzcfg.exe to start the Exchange tool.
  3. On page one of the Exchange Calendar Update Tool wizard, complete one of the following procedures:

    To extract the time zone of all the mailboxes on an Exchange server, follow these steps:
    1. In the Server Name box, type the friendly name or the Fully Qualified Domain Name (FQDN) of the Exchange server. If the friendly name contains a ".", use the NetBIOS name instead. Msextmzcfg.exe will fail if the server is in another Active Directory forest.
    2. In the Output File From Extraction box, type the name of the file that will contain all the mailbox time zone information.
    3. If you want to extract the time zones for recurring meetings, click to select the Extract Recurring Meeting Time Zones check box.

      Important If you use this setting, the run time of the extraction mode will be significantly increased. By default, the Extract Recurring Meeting Time Zones check box is cleared.
    4. Click the Outlook Profile Name list, and then click the profile you created in step 1.
    5. Click Next.



    To skip time zone extraction, follow these steps:

    1. Click to select the Skip time zone extraction check box. By default, the Skip time zone extraction check box is cleared.
    2. In the Output File From Extraction box, type the name of an output file from a previous time zone extraction run.
    3. In the Server Name box, type the friendly name or the FQDN of the Exchange server that was used to generate the output file that you specified in step 3b.
    4. Click Next.
  4. After the time zone extraction finishes, Msextmzcfg.exe parses the output file and tries to map the time zones from the user mailboxes to actual operating system time zones.

    If any time zones cannot be matched, you must manually map the time zone on the Map Time Zone page. To do this, click the Windows time zone that matches the User time zone in the Windows Time Zone list, and then click Next.
  5. When the mapping process is complete, Msextmzcfg.exe categorizes users into the following groups:
    • Users who have only one time zone (for example, users who have the CDO, Outlook Web Access, Outlook, or Recurring Meeting time zone) or users who have multiple time zones that map to the same operating system time zone
    • Users who have multiple time zones that map to different operating system time zones
    • Users who do not have any time zone information

    Msextmzcfg.exe lets you save the list of “conflicted” and “nonexistent” users in separate text files. To do this, follow these steps:

    1. In the Users with conflicting time zone information area, type ConflictUsers.txt in the Output File box.
    2. In the Users with no time zone information area, type NonExistent.txt in the Output File box.
  6. On the Calendar update configuration page, provide the information that is required to generate the user list input files, the .ini files, and the batch files with which to update the mailboxes. To do this, follow these steps:
    1. In the Select time zones that need to be updated list, click to select the check box for the time zones that you want to update.
    2. In the Number of Batch Files box, type the number of batches of users that you want to generate.

      This information is useful if you want to speed up the update run time. You can do this by breaking a large list of users into smaller batches and then running multiple instances of Msextmz.exe in Update mode. Do this on separate computers, and have each instance of Msextmz.exe process a separate batch of users.

      Note You cannot run multiple instances of Msextmz.exe on the same client computer.
    3. In the Tzmove.exe path box, type the path of the Outlook tool and its parameters. If you want to update only recurring meetings, click to select the Recurring meetings only check box.
    4. In the Post Mailbox Delay (seconds) box, type the number of seconds by which you want to delay profile creation in between updating mailboxes. We recommend that you use the default value of 0 seconds.
    5. In the Per Mailbox Timeout (minutes) box, type the number of minutes for which you want the Outlook tool to wait before it will time out. We recommend that you use the default value of 15 minutes.
  7. Click Finish. Msextmzcfg.exe generates a subdirectory under the current execution directory. The name of the subdirectory is the friendly name of the Exchange server. The subdirectory contains the following files:
    • MSExTmz_x.ini

      This file is the .ini file that is used by Msextmz.exe to run in Update mode. x is a placeholder for the batch number.
    • Mailboxes_x.txt

      This file is the user list input file that is used by Msextmzcfg.exe to run in Update mode. x is a placeholder for the batch number.
    • MSExTmz_x.bat

      This file is the batch file that runs the Msextmzcfg.exe in Update mode against the users who are specified in the Mailboxes_x.txt file.
    • NonExistent.txt

      This file contains the list of users who do not have time zone information in their mailbox.
    • ConflictUsers.txt

      This file contains the list of users who have time zone conflicts.
  8. Locate the subdirectory that is named after the server, open the Mailboxes_x.txt file in Notepad, remove any resource or system mailbox entries, and then save the Mailboxes_x.txt file.
  9. Follow these steps:
    1. Start Outlook, and then verify that Outlook correctly logs on to the server by using the default profile and without prompting you to select a profile.
    2. Verify that no prompts appear during Outlook startup. Msextmz.exe cannot run if there are prompts.
    3. Verify that the following file does not exist:

      %USERPROFILE%\Local Settings\Application Data\Microsoft\Outlook\Extend.dat

      If this file exists, rename it.
    Update the mailboxes by going to the subdirectory that is named after the server, and by running the batch files one by one. To run the batch files successfully, you must use an account that has Full Mailbox Access and Send As rights for the mailboxes that you want to update.

What to do after you run the Exchange tool

Install updates

After you finish updating all Exchange servers in your environment, install the following update on the Exchange servers:

926666 Update for daylight saving time changes in 2007 for Exchange 2003 Service Pack 2


Known issues

  • Recurring meetings that are created in Outlook Web Access are not updated by the Exchange Tool

    If you install the update that is mentioned in Knowledge Base article 926666 on the Exchange server before you update the mailboxes, recurring meetings that are created in Outlook Web Access are not updated by the Exchange tool. To resolve this problem, remove update 926666, run the Exchange tool, and then reinstall update 926666 on the Exchange server.
  • Exchange 2007 must be restarted after you run the Exchange tool

    For Exchange 2007 Outlook Web Access to correctly display calendar items after you run the Exchange tool, the Exchange services must be restarted.
  • You cannot install the Exchange tool

    The Exchange tool will not be installed successfully if either of the following registry keys exists:
    • HKEY_CLASS_ROOT\Outlook.Application.9
    • HKEY_CLASS_ROOT\Outlook.Application.10

    In this case, you receive the following error message when you try to install the Exchange tool:

    Exchange Server Calendar Rebasing Tool cannot be installed with this version of Microsoft Outlook.

    To work around this issue, delete these registry keys, install the Exchange tool, and then restore the registry keys.
  • A time zone may be ambiguous

    Recurring calendar items that are created by using DST 2006 rules in the Pacific (PST) time zone in Outlook 2003 or in an earlier version of Outlook are not updated by the Outlook tool. This problem affects Msextmz.exe because Msextmz.exe runs the Outlook tool.

    To work around this issue, change the registry to remove the Mexican time zones on the computer that is running Msextmz.exe. Run Msextmzcfg.exe in Update mode, and then restore the Mexican time zones in the registry. To do this, follow these steps.

    Warning Serious problems might occur if you modify the registry incorrectly by using Registry Editor or by using another method. These problems might require that you reinstall the operating system. Microsoft cannot guarantee that these problems can be solved. Modify the registry at your own risk.
    1. Back up the registry.
    2. Click Start, click Run, type regedit, and then click OK.
    3. Expand the following subkey:

      HKEY_LOCAL_MACHINE\Software\Microsoft\Windows NT\CurrentVersion\Time Zones

    4. Right-click Mexico Standard Time, and then click Delete.
    5. In the Confirm Key Delete dialog box, click Yes.
    6. Right-click Mexico Standard Time 2, and then click Delete.
    7. In the Confirm Key Delete dialog box, click Yes.
    8. Run Msextmzcfg.exe in Update mode.
    9. Restore the registry from the backup that you created in step 1.

    For more information about how to back up and to restore the registry, click the following article number to view the article in the Microsoft Knowledge Base:

    256986 Description of the Microsoft Windows registry

  • There is a limit on the number of mailboxes that can be processed per server

    In User List mode and in Time Zone Extraction mode, Msextmz.exe can process only 65,535 mailboxes on a server. If the server has more than 65,535 mailboxes, some mailboxes will not be processed.
  • There may be conflicts with conference room assignments

    When you use the Outlook tool, meetings are shifted to the correct time. However, this may cause conflicts with conference room assignments.

    If you are running Exchange Server 2007, we recommend that you set the conflict limit for the Resource Booking Attendant in Exchange 2007 to 3. After all mailboxes are updated, the conflicts will automatically be resolved.

    If you are using direct booking or the Auto Accept Agent, follow these steps to update the resource mailboxes:

    For direct booking

    Note The following steps require that you download the latest hotfix for the Time Zone Data Update tool for Microsoft Office Outlook (Tzmove.exe).
    1. Run Tzmove.exe (the Outlook tool) with the /FORCEREBASESUPPRESSALLUPDATES command line parameter against resource mailboxes.
    2. Run Tzmove.exe in normal mode against all other mailboxes.

    After the updating is finished, if you use Outlook to log on to the resource mailboxes andto read the updates that are sent in step 2, those meeting updates appear as "tentative" on the resource mailbox calendar. If no one logs on to the resource mailbox, the original meeting requests that were updated in step 1 will appear as "accepted" on the resource mailbox calendar.

    For more information about FORCEREBASESUPPRESSALLUPDATES, click the following article number to view the article in the Microsoft Knowledge Base:

    933146 Description of the hotfix package for the Time Zone Data Update tool for Microsoft Office Outlook



    For the Auto Accept Agent

    1. Make sure that the Auto Accept Agent is running on the server.
    2. Install the daylight saving time update on the client computer.
    3. Run Tzmove.exe (the Outlook tool) with the /FORCEREBASESUPPRESSALLUPDATES command line parameter against resource mailboxes that have the Auto Accept Agent enabled.
    4. Verify again that the Auto Accept Agent is running. This is important to make sure that users will receive the acceptance mail for the updated meetings that they organized.
    5. Run Tzmove.exe in normal mode against all the other mailboxes.
  • Public Folder calendars

    The Exchange tool does not update Public Folder calendars. For information about how to update a Public Folder calendar, see the Outlook tool documentation.
  • You must use "Run As" in the command line

    If you intend to run Msextmz.exe by using “Run As” in the command line, make sure that you also use “Run As” to configure Registry Editor to set the PickLogonProfile value in the registry.
  • Msextmz.exe may stop responding

    Issues with the global catalog servers may cause Msextmz.exe to stop responding. If this happens, follow these steps:
    1. Stop Msextmz.exe.
    2. If the Logfile parameter was set in Msextmz.ini, find out which mailbox was being processed. The Processing Mailbox entry in the log file provides the user DN for the mailbox that was being processed when Msextmz.exe stopped responding.

      If the Logfile parameter was not set in Msextmz.ini, the Processing Mailbox information can be found in the Command Prompt window.

      All user mailboxes that come after the mailbox that was being processed when Msextmz.exe stopped responding are not processed. This applies to the mailboxes in the ServerName_TimeZone_Input_File.txt that was used as the input file for this run.
    3. Create a new input file that contains the user DNs of the mailboxes that were not processed.
    4. Before you run Msextmz.exe again with this new input file, make sure that you process the users in the error file that was generated by the previous run.
  • You can run the Outlook tool and the Exchange tool in the same environment

    You can run the Outlook tool and the Exchange tool in the same environment. If you run the Exchange tool on a mailbox that has already been updated by the Outlook tool, or vice versa, you will experience no side effects. However, if the administrator runs the Exchange tool, there is no need for users to separately run the Outlook tool.
  • Reminders appear later than expected

    Non-meeting reminders for mailboxes that are updated by the Exchange tool will not be updated if Outlook has never connected to the mailbox in Online mode. In this situation, reminders will appear one hour later than expected.

    If Outlook has never connected in Online mode, you must adjust the incorrect reminders for calendar appointments that the Outlook Time Zone Update tool finds. If Outlook has never connected in Online mode, the reminders search folder does not exist in the mailbox. Therefore the tool will not update e-mail items, contacts, or other reminders. For example, the tool will not update a reminder on an e-mail item to follow up at a time in the future or a reminder on a task item that has a reminder.
  • Run time may be long

    Msextmz.exe is single-threaded. Therefore, it could take many hours to run the tool against many mailboxes.

    For reference, Microsoft IT was able to update approximately 53,000 mailboxes in 16 hours by using nine clients. This equates to an update rate of 6.13 mailboxes per minute per client.

    The number of invitees in a meeting request should not affect the run time of the Update mode. This is because from the client perspective, sending a meeting update to one recipient takes the same time as sending a meeting update to one hundred recipients.

    The number of invitees does affect the number of copies of the meeting update. However, that is an issue of mail flow, not of run time.
  • The event log may run out of space after updating many mailboxes

    Tzmove.exe generates an informational event that includes source TZMOVE EventID 32 for each successful update. Lots of events can cause the Application log to exceed the allocated space on the disk. In Update mode, Msextmz.exe relies on these events to determine the successful execution of Tzmove.exe. If Msextmz.exe cannot find the corresponding Tzmove.exe event that is associated with the mailbox that Msextmz.exe is trying to update, Msextmz.exe assumes that the update was unsuccessful. Therefore Msextmz.exe logs the mailbox DN in the error.txt file. To avoid this issue, we recommend that you set the event log size to maximum and that you allow overwriting.
  • “Unable to install because previous versions of “Microsoft Exchange Calendar Update Tool” were detected. Please uninstall them and run this setup again.”

    If you previously installed the Exchange Calendar Update Tool version 1.0, you must uninstall version 1.0 before you install version 2.0. Version 1.0 was distributed as a self-extracting executable program that contained two MSI packages: Msextmz.msi and Msextmzcfg.msi. You must uninstall both packages before you install version 2.0. If you still experience problems installing version 2.0, try re-installing and uninstalling version 1.0 by using the *.msi packages instead of using the Add or Remove Programs tool. Then, restart your computer, and install version 2.0. If all else fails, directly extract the binaries from the *.msi packages.

Error messages and resolutions

  • Unable find mailbox timezone:Error 0x80004005

    This error message may be caused by any of the following issues:

    • The tool was unable to find any time zone values in the mailbox of that specific user. To resolve this issue, try adding “ReadCalendarTimeZones=1” (without the quotation marks) to the Msextmz.ini file to force the tool to examine recurring calendar items for time zone information. You can create a new input file by using the DNs from the error log that you received from the last run.
    • You are referencing Tzmove.exe from the wrong directory. To resolve this issue, extract the downloaded installation file into the folder where Msextmz resides or update the Msextmz.ini to include a full path to where Tzmove.exe is installed on the workstation that you are using.

      Note When you download the Time Zone Data Update Tool for Microsoft Office Outlook, the Tzmove.exe file is the installer for the actual tool. Referencing the installer will cause errors when you run Msextmz.
    • The account that you are using to run Msextmz does not have full mailbox permissions and has not been delegated the correct Exchange permissions. To resolve this issue, run the “Grant Mailbox Permission” script from an Exchange Server computer.
  • Unable to process mailbox /O=CONTOSO/OU=FIRST ADMINISTRATIVE GROUP/CN=RECIPIENTS/CN=TESTMB01 - 0x80004005

    Carefully review the legacyExchangeDN and make any necessary corrections. To make sure that the value is accurate, use ADSIEdit to copy and paste the value.
  • Unable open mailbox table for server /O=CompanyRoot/ OU=IT/cn=Configuration/cn=Servers/cn=EXCH01. Error 80040115

    This is an RPC error. Carefully review the legacyExchangeDN, and make any necessary corrections.

    Please Select the Valid Server

    You need the distinguished name (DN) of the server. The DN should resemble the following DN:

    ServerDN:/O=CompanyRoot/OU=IT/cn=Configuration/cn=Servers/cn=EXCH01

  • The application failed to initialize properly (0xc0000135). Click on OK to terminate the application

    This error message occurs because the .NET Framework 2.0 is not installed.
  • HrTestMailboxAccess:Unable Open mailbox - 0x8004011D.

    If you receive this error message during the update operation, the account that you are using does not have full access to the mailbox. The account must have Full Mailbox Access permissions to all mailboxes for the tool to be able to update the mailboxes.

    Verify that the correct permissions have been granted by using the method that is described in the "Configure permissions for Msextmz.exe" section.


REFERENCES

"Grant Mailbox Permission" script

Option Explicit
' For FileSystemObject
Const ForReading = 1
Const ForWriting = 2
Const ForAppending = 8
Const TristateTrue = -1
Const TristateUseDefault = -2
Const TristateFalse = 0

'Permission Type: Allow or Deny
Const ADS_ACETYPE_ACCESS_ALLOWED = &H0
Const ADS_ACETYPE_ACCESS_DENIED = &H1
Const ADS_ACETYPE_ACCESS_ALLOWED_OBJECT = &H5
Const ADS_ACETYPE_ACCESS_DENIED_OBJECT = &H6

Const ADS_ACEFLAG_INHERIT_ACE = &H2
Const ADS_ACEFLAG_NO_PROPAGATE_INHERIT_ACE = &H4
Const ADS_ACEFLAG_INHERIT_ONLY_ACE = &H8
Const ADS_ACEFLAG_INHERITED_ACE = &H10
Const ADS_ACEFLAG_VALID_INHERIT_FLAGS = &H1f
Const ADS_ACEFLAG_SUCCESSFUL_ACCESS = &H40
Const ADS_ACEFLAG_FAILED_ACCESS = &H80

'Declare ADSI constants
Const ADS_SCOPE_SUBTREE = 2
Const ADS_OPTION_SECURITY_MASK = 3
Const ADS_OPTION_REFERRALS  = 1
Const ADS_SECURITY_INFO_DACL = 4
Const ADS_CHASE_REFERRALS_NEVER = &h00 
Const ADS_CHASE_REFERRALS_SUBORDINATE = &h20 
Const ADS_CHASE_REFERRALS_EXTERNAL = &h40

'Microsoft Exchange 
Const EX_MB_SEND_AS_ACCESSMASK  = &H00100
Const EX_FULLMAILBOX_ACCESSMASK = 1
Const EX_MB_SEND_AS_GUID = "{AB721A54-1E2F-11D0-9819-00AA0040529B}"

'Application Parameter Index
Const ARG_INDEX_MODE = 0
Const ARG_INDEX_USERNAME = 1
Const ARG_INDEX_FILENAME = 2
Const MIN_ARG = 1

Const MODE_INVALID = -1 
Const MODE_ADD = 0
Const MODE_REMOVE = 1

Const ADD = "-ADD"
Const REMOVE = "-REMOVE"

'Application Const String
Const EMPTYSTRING = ""
Const ERROR_FILENAME = "GrantMailboxPermission.err"
Const OUTPUT_FILENAME = "GrantMailboxPermission.log"
Dim OUTPUT_DELIMITER
OUTPUT_DELIMITER = vbTab

'Logging file
Dim objFSO
Dim objfileError
Dim objfileOutput
Dim objfileImport
Dim objconn
Dim objCommand
Dim rootDSE
Dim sDomainContainer
Dim sUserLDAPPath
Dim objUser
Dim objSDNTsecurity
Dim objDACLNT
Dim objDACLEX
Dim objSDMailbox
Dim fFMA
Dim fSendAs
Dim AccessTypeForFMA
Dim AccessTypeForSendAS
Dim fAddedFMA
Dim fAddedSendAs
Dim fRemovedFMA
Dim fRemovedSendAs
Dim sArraySplit
Dim sOneRow
Dim sGrantedUser
Dim dArgCount
Dim cScriptMode
Dim dArgExpected
Dim fOneError

On Error Resume Next
'Parameter Checking
dArgCount = Wscript.Arguments.Count
If (dArgCount < MIN_ARG) Then
    DisplaySyntax
End If

cScriptMode = MODE_INVALID
Select Case UCase(WScript.Arguments(ARG_INDEX_MODE))
    Case ADD
        cScriptMode = MODE_ADD
        dArgExpected = ARG_INDEX_FILENAME + 1
    Case REMOVE
        cScriptMode = MODE_REMOVE
        dArgExpected = ARG_INDEX_MODE + 1
    Case Else
        cScriptMode = MODE_INVALID
End Select

If (cScriptMode = MODE_INVALID Or dArgCount <> dArgExpected) Then
    DisplaySyntax
End If

If (cScriptMode = MODE_ADD) Then
    sGrantedUser = WScript.Arguments(ARG_INDEX_USERNAME)
    If (IsValidUserName(sGrantedUser) = False) Then
        DisplaySyntax
    End If
End If

CreateImportExportFiles

If (cScriptMode = MODE_ADD) Then
    err.Clear
    
    'Prepare LDAP connection
    Set objconn = CreateObject("ADODB.Connection")
    Set objCommand = CreateObject("ADODB.Command")
    objconn.Provider = "ADSDSOObject"
    objconn.Open "ADs Provider"
    If (err.number <> 0) Then
        WScript.StdOut.WriteLine("Failed to bind to Active Directory server, error:" & err.Description)
        objfileError.WriteLine("Failed to bind to Active Directory server, error:" & err.Description)
        WScript.Quit
    End If
        
    Set rootDSE = GetObject("LDAP://rootDSE")
    sDomainContainer = rootDSE.Get("defaultNamingContext")
    If (err.number <> 0) Then
        WScript.StdOut.WriteLine("Failed to find a Domain Container:" & err.Description)
        objfileError.WriteLine("Failed to find a Domain Container:" & err.Description)
        WScript.Quit
    End If
        
    Set objCommand.ActiveConnection = objconn

    Do While objfileImport.AtEndOfStream <> True
        fOneError = False
        sUserLDAPPath = EMPTYSTRING
        err.Clear

        sOneRow = Trim(objfileImport.ReadLine)
        If sOneRow <> EMPTYSTRING Then
        
            sUserLDAPPath = GetLDAPPathFromLegacyDN(sOneRow)
            If (err.number <> 0) Then
                objfileError.WriteLine("Failed to get user's LDAP path from " & sOneRow)
                fOneError = True
                err.Clear
            End If

            If (fOneError = False) Then
                Set objUser = GetObject(sUserLDAPPath)
                If (err.number <> 0) Then
                    objfileError.WriteLine("Failed to get user object from " & sUserLDAPPath)
                    objfileError.WriteLine("Error: " & err.Description)
                    fOneError = True
                    err.Clear
                End If
            End If
        
            If (fOneError = False) Then
                Set objSDMailBox = objUser.MailboxRights
                Set objDACLEX = objSDMailbox.DiscretionaryAcl
                Set objSDNTsecurity = objUser.ntSecurityDescriptor
                Set objDACLNT = objSDNTsecurity.DiscretionaryAcl
                If (err.number <> 0) Then
                    objfileError.WriteLine("Failed to get DACL of " & sUserLDAPPath)
                    objfileError.WriteLine("Error: " & err.Description)
                    fOneError = True
                    err.Clear
                End If
            End If

            ' Check Full Mailbox Access and Send As permission
            fFMA = False
            fSendAs = False
            AccessTypeForFMA = ADS_ACETYPE_ACCESS_ALLOWED
            AccessTypeForSendAS = ADS_ACETYPE_ACCESS_ALLOWED

            If (fOneError = False) Then
                CheckFullMailboxAccess objDACLEX, sGrantedUser, fFMA, AccessTypeForFMA
                CheckSendAs objDACLNT, sGrantedUser, fSendAs, AccessTypeForSendAS
                If (err.number <> 0) Then
                    objfileError.WriteLine("Failed to Check permission of " & sUserLDAPPath)
                    objfileError.WriteLine("Error: " & err.Description)
                    fOneError = True
                    err.Clear
                End If
            End If

            'If we don't have either SendAS or FMA, we're going to add these permission
            If ( (AccessTypeForFMA = ADS_ACETYPE_ACCESS_DENIED) Or (AccessTypeForSendAs = ADS_ACETYPE_ACCESS_DENIED_OBJECT) ) Then
                'Deny access already granted, won't add permission to this user
                objfileError.WriteLine("Deny permission already added: " & sUserLDAPPath)
                fOneError = True
            End If
            
            If ( fOneError = False And ((fFMA = False) Or (fSendAs = False)) ) Then
                fAddedFMA = False
                fAddedSendAs = False
                
                If (fFMA = False) Then
                    'Add FMA permission
                    err.Clear
                    AddAce objDACLEX, sGrantedUser, EX_FULLMAILBOX_ACCESSMASK, ADS_ACETYPE_ACCESS_ALLOWED, ADS_ACEFLAG_INHERIT_ACE, 0,0,0
                    objSDMailbox.DiscretionaryAcl = objDACLEX
                    objUser.MailboxRights = Array(objSDMailbox)
                    If ( err.number <> 0 ) Then
                        objfileError.WriteLine("Failed to add FullMailbox Access: " & sUserLDAPPath)
                        objfileError.WriteLine("Error: " & err.Description)
                        fOneError = True
                        fAddedFMA = False
                        err.Clear
                    Else
                        fAddedFMA = True
                    End If
                End If
                
                If (fSendAs = False) Then
                    'Add SendAs permission
                    err.Clear
                    AddAce objDACLNT, sGrantedUser, EX_MB_SEND_AS_ACCESSMASK, ADS_ACETYPE_ACCESS_ALLOWED_OBJECT, 0,1, EX_MB_SEND_AS_GUID, 0
                    objSDNTsecurity.DiscretionaryAcl = objDACLNT
                    objUser.Put "ntSecurityDescriptor", Array( objSDNTsecurity )
                    objUser.SetOption ADS_OPTION_SECURITY_MASK, ADS_SECURITY_INFO_DACL
                    If ( err.number <> 0 ) Then
                        objfileError.WriteLine("Failed to add SendAs permission: " & sUserLDAPPath)
                        objfileError.WriteLine("Error: " & err.Description)
                        fOneError = True
                        fAddedSendAs = False
                        err.Clear
                    Else
                        fAddedSendAs = True
                    End If
                End If

                If (fOneError = False ) Then 
                    objUser.SetInfo
                    If (err.number <> 0) Then
                        objfileError.WriteLine("Failed to update user: " & sUserLDAPPath)
                        objfileError.WriteLine("Error: " & err.Description)
                        fOneError = True
                        err.Clear       
                    Else
                        'Update Logging
                        objfileOutput.WriteLine(sUserLDAPPath & OUTPUT_DELIMITER & fAddedFMA & OUTPUT_DELIMITER & fAddedSendAs)     
                    End If
                End If
            End If

            Set objUser = Nothing
            Set objSDNTsecurity = Nothing
            Set objDACLNT = Nothing
            Set objDACLEX = Nothing
            Set objSDMailBox = Nothing

            If (fOneError = True) Then
                WScript.StdOut.Write("!")
            Else
                WScript.StdOut.Write(".")
            End If
        End If
    Loop

Set rootDSE = Nothing
Set objCommand = Nothing
Set objconn = Nothing

End If

If (cScriptMode = MODE_REMOVE) Then
    'Retreive the granted user from the first line of import file
    sGrantedUser = objfileImport.ReadLine
    If (IsValidUserName(sGrantedUser) = False) Then
        WScript.StdOut.WriteLine("Invalid User in import file. please check import file..")
        objfileError.WriteLine("Invalid User in import file. please check import file..")
        WScript.Quit
    End If
    
    Do While objfileImport.AtEndOfStream <> True
        fOneError = False
        sUserLDAPPath = EMPTYSTRING
        fAddedFMA = False
        fAddedSendAs = False
        fRemovedFMA = False
        fRemovedSendAs = False
        err.Clear

        sOneRow = objfileImport.ReadLine
        sArraySplit = Split(sOneRow, OUTPUT_DELIMITER)

        'First column is Ldap path
        sUserLDAPPath = sArraySplit(0)
        'Second column is FullMailbox Permission
        fAddedFMA = sArraySplit(1)
        'Third column is SendAs
        fAddedSendAs = sArraySplit(2)

        Set objUser = GetObject(sUserLDAPPath)
        If (err.number <> 0) Then
            objfileError.WriteLine("Failed to get user object from " & sUserLDAPPath)
            objfileError.WriteLine("Error: " & err.Description)
            fOneError = True
            err.Clear
        End If
        
        If ((fOneError = False) And (fAddedFMA = "True")) Then      
            Set objSDMailBox = objUser.MailboxRights
            Set objDACLEX = objSDMailbox.DiscretionaryAcl
            fRemovedFMA = RemoveFullMailboxAccess(objDACLEX, sGrantedUser)
            If (err.number <> 0) Then
                objfileError.WriteLine("Failed to Remove Full MailboxAccess from " & sUserLDAPPath)
                objfileError.WriteLine("Error: " & err.Description)
                fOneError = True
                err.Clear
            End If
            
            If (fRemovedFMA = False) Then
                objfileError.WriteLine("Couldn't find Full mailbox access permission on " & sUserLDAPPath)
            End If
            
            If ((fOneError = False) And (fRemovedFMA = True)) Then
                objSDMailbox.DiscretionaryAcl = objDACLEX
                objUser.MailboxRights = Array(objSDMailbox)
            End If
        End If

        If ((fOneError = False) And (fAddedSendAs = "True")) Then       
            Set objSDNTsecurity = objUser.ntSecurityDescriptor
            Set objDACLNT = objSDNTsecurity.DiscretionaryAcl

            fRemovedSendAs = RemoveSendAs(objDACLNT, sGrantedUser)
            If (err.number <> 0) Then
                objfileError.WriteLine("Failed to Remove SendAs from " & sUserLDAPPath)
                objfileError.WriteLine("Error: " & err.Description)
                fOneError = True
                err.Clear
            End If

            If (fRemovedSendAs = False) Then
                objfileError.WriteLine("Couldn't find SendAs permission on " & sUserLDAPPath)
            End If
            
            If ((fOneError = False) And (fRemovedSendAs = True)) Then
                objSDNTsecurity.DiscretionaryAcl = objDACLNT
                objUser.Put "ntSecurityDescriptor", Array( objSDNTsecurity )
                objUser.SetOption ADS_OPTION_SECURITY_MASK, ADS_SECURITY_INFO_DACL
            End If
        End If

        If ((fOneError = False) And (fRemovedFMA Or fRemovedSendAs)) Then
            objUser.SetInfo
            If (err.number <> 0) Then
                objfileError.WriteLine("Failed to update ADSI for user: " & sUserLDAPPath)
                objfileError.WriteLine("Error: " & err.Description)
                fOneError = True
                err.Clear       
            Else 
                If ( fRemovedFMA Or fRemovedSendAs ) Then
                    'Update Logging
                    objfileError.WriteLine("Removed Permission from " & sUserLDAPPath & OUTPUT_DELIMITER & fRemovedFMA & OUTPUT_DELIMITER & fRemovedSendAs)
                End If
            End If
        End If

        If (fOneError = True) Then
            WScript.StdOut.Write("!")
        Else
            WScript.StdOut.Write(".")
        End If
    Loop
End If

CloseImportexportFiles

Function IsValidUserName (sUserName)
    Dim dPosition
    dPosition = InStr(1, sUserName, "\")
    If (dPosition = 0 ) Then
        IsValidUserName = False
        objfileError.WriteLine("Invalid User:" & sUserName)
    Else
        IsValidUserName = True
    End If
End Function

Function CheckSendAs (objNTSD, sUser, fSendAs, AccessType)
    Dim intACECount
    Dim objACE
    
    err.Clear
    fSendAs = False
    AccessType = ADS_ACETYPE_ACCESS_ALLOWED
    intACECount = objNTSD.AceCount

    If intACECount Then
        For Each objACE In objNTSD
            err.Clear
            If ( (UCase(objACE.Trustee) = UCase(sUser)) And (objACE.ObjectType = EX_MB_SEND_AS_GUID) ) Then
                fSendAs = True
                AccessType = objACE.AceType
            End If
        Next
    End If  

    If (err.number <> 0) Then
        objfileError.WriteLine("Check SendAs permissions Failed : " & sUser)
        objfileError.WriteLine("Error: " & err.Description)
        err.Clear
        fOneError = True
    End If
    Set objACE = Nothing
End Function

Function CheckFullMailboxAccess (objACL, sUser, fFoundFMA, AccessType)
    Dim intACECount
    Dim objACE

    err.Clear
    fFoundFMA = False
    AccessType = ADS_ACETYPE_ACCESS_ALLOWED
    intACECount = objACL.AceCount
    If intACECount Then
        For Each objACE In objACL
            If ( (UCase(objACE.Trustee) = UCase(sUser)) And ((objACE.AccessMask And EX_FULLMAILBOX_ACCESSMASK) <> 0)) Then
                fFoundFMA = True
                AccessType = objACE.AceType
            End If
        Next
    End If

    If (err.number <> 0) Then
        objfileError.WriteLine("Check FullMailbox permissions Failed : " & sUser)
        objfileError.WriteLine("Error: " & err.Description)
        err.Clear
        fOneError = True
    End If
    Set ObjACE = Nothing
End Function

Function RemoveSendAs (objNTSD, sUser)
    Dim intACECount
    Dim objACE
    Dim fFound
    
    fFound = False
    intACECount = objNTSD.AceCount
    
    If intACECount Then
        For Each objACE In objNTSD
            If ((UCase(objACE.Trustee) = UCase(sUser)) And (objACE.ObjectType = EX_MB_SEND_AS_GUID) ) Then
                objNTSD.RemoveAce objACE
                fFound = True
            End If
        Next
    End If

    RemoveSendAs = fFound       
End Function

Function RemoveFullMailboxAccess (objACL, sUser)
    Dim intACECount
    Dim objACE
    Dim fFound
    
    fFound = False
    intACECount = objACL.AceCount
    
    If intACECount Then
        For Each objACE In objACL
            If((0 <> Instr(UCase(objACE.Trustee), UCase(sUser))) And (objACE.AccessMask And EX_FULLMAILBOX_ACCESSMASK) <> 0) Then
                objACE.AccessMask = (objACE.AccessMask Xor EX_FULLMAILBOX_ACCESSMASK)
                fFound = True
            End If
        Next
    End If

    RemoveFullMailboxAccess = fFound        
End Function

Function GetLDAPPathFromLegacyDN (sLegacyDN)
    Dim rsUsers
    Dim sLdapPath
    
    objCommand.CommandText = "<GC://" & sDomainContainer & ">;(&(&(& (mailnickname=*) (| (&(objectCategory=person)(objectClass=user)(legacyExchangeDN=" & sLegacyDN & ")) ))));adspath;subtree"
    objCommand.Properties("searchscope") = ADS_SCOPE_SUBTREE
    objCommand.Properties("Page Size") = 10
    objCommand.Properties("Timeout") = 30 
    objCommand.Properties("Chase referrals") = (ADS_CHASE_REFERRALS_SUBORDINATE Or ADS_CHASE_REFERRALS_EXTERNAL)

    err.Clear   
    Set rsUsers = objCommand.Execute
    If (err.number <> 0) Then
        objfileError.WriteLine("Search for mailbox owners failed, error:" & err.Description)
        fOneError = True
    End If
    
    If (rsUsers.RecordCount = 0) Then
        objfileError.WriteLine("No mailbox owner user accounts found for " & sLegacyDN & " in " & sDomainContainer & ".")
        fOneError = True        
    End If

    If (rsUsers.RecordCount > 1) Then
        objfileError.WriteLine("Multiple mailboxs owner user accounts found for " & sLegacyDN & " in " & sDomainContainer & ".")
        fOneError = True        
    End If

    sLdapPath = Replace(rsUsers.Fields(0).Value, "GC://", "LDAP://")    
    GetLDAPPathFromLegacyDN = sLdapPath
    Set rsUsers = Nothing
End Function

Function CloseImportexportFiles

    objfileError.WriteLine("*******************************************************")
    objfileError.WriteLine("End at " & Date & " " & Time)
    objfileError.WriteLine("*******************************************************")

    objFSO.Close
    objfileError.Close
    objfileOutput.Close
    objfileImport.Close
    
    Set objFSO = Nothing
    Set objfileError = Nothing
    Set objfileOutput = Nothing
    Set objfileImport = Nothing
End Function

Function CreateImportExportFiles
    Dim sErrorsFileName
    Dim sImportFileName
    Dim sOutputFileName

    err.Clear
    Set objFSO = CreateObject("Scripting.FileSystemObject")
    sErrorsFileName = ERROR_FILENAME
    sImportFileName = EMPTYSTRING
    sOutputFileName = EMPTYSTRING

    Select Case cScriptMode
        Case MODE_ADD
            sImportFileName = WScript.Arguments(ARG_INDEX_FILENAME)
            sOutputFileName = OUTPUT_FILENAME
        Case MODE_REMOVE
            sImportFileName = OUTPUT_FILENAME 'Use output file name as import file
            sOutputFileName = EMPTYSTRING   
        Case Else
            DisplaySyntax
    End Select

    Set objfileError = objFSO.OpenTextFile(sErrorsFileName, ForAppending, True, TristateTrue)
    objfileError.WriteLine("*******************************************************")
    objfileError.WriteLine("Start at " & Date & " " & Time)
    objfileError.WriteLine("*******************************************************")

    If (cScriptMode = MODE_REMOVE) Then
        Set objfileImport = objFSO.OpenTextFile(sImportFileName, ForReading, False, TristateTrue)
    Else
        Set objfileImport = objFSO.OpenTextFile(sImportFileName, ForReading, False, TristateFalse)
    End If

    If (sOutputFileName <> EMPTYSTRING) Then
        'Check if output file already exists.
        If (objFSO.FileExists(sOutputFileName)) Then
            Set objfileOutput = objFSO.OpenTextFile(sOutputFileName, ForReading, False, TristateTrue)
            sOneRow = objfileOutput.ReadLine
            'If user name in the file is different from parameter, we can't proceed.
            If ( sOneRow <> sGrantedUser ) Then
                WScript.StdOut.WriteLine("The Domain\User must be the same as " & sOneRow )
                WScript.Quit
            End If
            Set objfileOutput = objFSO.OpenTextFile(sOutputFileName, ForAppending, True, TristateTrue)
        Else
            Set objfileOutput = objFSO.OpenTextFile(sOutputFileName, ForWriting, True, TristateTrue)
            'The first line of Log file is the user who is going to be granted the permissions
            objfileOutput.WriteLine(sGrantedUser)
        End If
    End If
    
    If (err.number <> 0) Then
        WScript.StdOut.WriteLine("Failed to open Log file, error:" & err.Description)
        WScript.Quit
    End If
End Function

Function AddAce(dacl, TrusteeName, gAccessMask, gAceType, gAceFlags, gFlags, gObjectType, gInheritedObjectType)
    Dim Ace1
    
    Set Ace1 = CreateObject("AccessControlEntry")
    Ace1.AccessMask = gAccessMask
    Ace1.AceType = gAceType
    Ace1.AceFlags = gAceFlags
    Ace1.Flags = gFlags
    Ace1.Trustee = TrusteeName
    'Determine whether ObjectType has to be set
    If CStr(gObjectType) <> "0" Then
        Ace1.ObjectType = gObjectType
    End If

    'Determine whether InheritedObjectType has to be set.
    If CStr(gInheritedObjectType) <> "0" Then
        Ace1.InheritedObjectType = gInheritedObjectType
    End If
    dacl.AddAce Ace1

    Set Ace1 = Nothing
End Function

Function DisplaySyntax
    WScript.StdOut.WriteLine("Syntax:")
    WScript.StdOut.WriteLine()
    WScript.StdOut.WriteLine("Grant Full mailbox access and SendAs permission to USER based on IMPORT_FILE:")
    WScript.StdOut.WriteLine("    CSCRIPT " & WScript.ScriptName & " -Add DOMAIN\USER IMPORT_FILE")
    WScript.StdOut.WriteLine("    NOTE: """ & OUTPUT_FILENAME & """ will be created for -Remove option ")
    WScript.StdOut.WriteLine()
    WScript.StdOut.WriteLine("Remove Full mailbox access and SendAs permission based on " & OUTPUT_FILENAME & ":")
    WScript.StdOut.WriteLine("    CSCRIPT """ & WScript.ScriptName & """ -Remove ")
    WScript.StdOut.WriteLine()
    WScript.StdOut.WriteLine("For all modes, errors are saved to " & ERROR_FILENAME )

    WScript.Quit    
End Function

Revisions

Version Date Change
1.0 11-Jan-2007 Original version
2.0 12-Jan-2007 Editorial changes
3.0 07-Feb-2007 Complete article rewrite
3.1 08-Feb-2007 Updated download center URL
3.2 08-Feb-2007 Editorial changes
4.0 09-Feb-2007 Added new information about conference room conflicts
4.1 12-Feb-2007 Added Exchange 2003 Enterprise Edition to “Applies to” section
4.2 12-Feb-2007 Corrected typographical error
4.3 12-Feb-2007 Corrected step number in note
5.0 13-Feb-2007 Added virtual machine information in the "How to install the Exchange tool" section
6.0 15-Feb-2007 Rewrite of "Reminders appear later than expected" section
7.0 15-Feb-2007 Added download information for the Virtual Machine for Microsoft Exchange Calendar Update Tool package
8.0 16-Feb-2007 Added information about the Exchange System Management tools in the "What to do before you run the Exchange tool" section
8.1 19-Feb-2007 Corrected file name in the “How to run Msextmzcfg.exe” section
8.2 20-Feb-2007 Added space between User_Name and File_Name in the "Grant Mailbox Permission" script section
9.0 20-Feb-2007 Rewrite of article
10.0 20-Feb-2007 Internal metadata updates
10.1 20-Feb-2007 Corrected typographical error
10.2 20-Feb-2007 Corrected typographical error
10.3 20-Feb-2007 Corrected typographical error
10.4 21-Feb-2007 Corrected typographical error
11.0 22-Feb-2007 Added information about version 2 of the Exchange tool
11.1 22-Feb-2007 Corrected typographical error
11.2 23-Feb-2007 Added table to indicate article revisions
12.0 26-Feb-2007 Added information about event log space and added information about error messages and resolutions to those errors
13.0 27-Feb-2007 Removed download URL for virtual machine information and added cross-reference to 933185
14.0 28-Feb-2007 In the "Known Issues" section, changed text in first bullet to include KB926666
15.0 27-Feb-2007 Added virtual machine information
16.0 28-Feb-2007 Added information about the the latest hotfix for the Time Zone Data Update Tool for Microsoft Office Outlook (Tzmove.exe) to the "For direct booking" section. Added cross-reference to 933146
16.1 28-Feb-2007 Corrected table tags
17.0 01-Mar-2007 Removed Exchange Server 5.5 information
18.0 05-Mar-2007 Rewrote Revisions table
19.0 08-Mar-2007 Added information about the "HRTestMailboxAccess" error message
19.1 13-Mar-2007 Removed duplicate paragraph about the number of invitees in a meeting request
19.2 19-Mar-2007 Updated Revisions table
19.3 21-Mar-2007 Removed virtual machine information in the "About the Exchange tool" section
19.4 03-Apr-2007 Updated Introduction section
19.5 04-Aug-2007 Updated title
21.0 06-Sep-2007 Added information about article 941018 with a newer tool
21.1 07-Sep-2007 Removed outdated Knowledge Base article link.


Keywords: kbhowto kbinfo kbexpertiseinter kbresolve KB930879