Sunday, April 23, 2017

Import calendar items to user mailboxes while supporting multiple user language folders

Import calendar items to user mailboxes while supporting multiple user language folders (English / Hebrew and others)

It is usual for a company to want to add important events to users calendars such as vacations, holidays etc.
There are a few possible ways to do this. The best option I found is the one that requires the least user intervention which is - not intervention at all.

Basically the method (centered here on Exchange on premise deployment) include the following steps:
  1. Providing HR with mailboxes for prepping the calendars for import. One for each language.
  2. Exporting each mailbox calendar to a PST file.
  3. Clearing permissions from the PST file with MFCMapi tool.
  4. Make sure you got the proper permissions for the task
  5. Scripting the import based on correct mailbox language.

Providing HR with mailboxes for prepping the calendar for import. One for each language
If there are different versions on Office in use withing your company, it is possible that there are different default folder languages (for example Calendar for English "לוח שנה" for Hebrew etc).
Since the import operation will be done from a PST file, the Calendar folder name in the PST file must match the Calendar folder name in the target mailbox.

Create a user and a mailbox for each one of the required languages. 
Logon to each mailbox with Outlook with the proper language in order for the default folders to be created with the appropriate language. (You may also try to logon to the mailbox for the first time with OWA and select the language to be used in order for the default folders to be created with the desired language.

Provide HR with the user accounts and ask HR to fill in the desired calendar items.

Exporting each mailbox calendar to a PST file
After HR are done with adding the required items, log on to each mailbox by creating a unique Outlook profile. This can be much easier if your user account has full mailbox access to all of those mailboxes.

After logging on to each mailbox, go to File menu, Open & Export, Import/Export, Select
Export to a file, select Outlook Data File (.pst).
In the folder tree select the Calendar folder (You may clear the "Include subfolders" if not required.
and provide a name for the new PST file.
Make sure to name the file based on the language of the default folder for that mailbox (ex. English.pst or Hebrew.pst). Click Finish

When the export is done, open the created PST file from within the Outlook profile by using the File menu, Open Outlook Data File (.pst), and selecting the newly created file.
Close the outlook profile


Clearing permissions from the PST file with MFCMapi tool
When exporting a folder to a pst file from Outlook, the PST file contains folder permissions.
Since we will import the PST file to user mailboxes, we would like to prevent removing any existing permissions on the user calendars.

Download a copy of MFCMapi from here

Once downloaded, start the program on the computer where the Outlook profiles are configured.
Click the
Session menu and Click Logon.
Select the Outlook profile for the first PST file to process.
You will see the mailbox and
Outlook Data File. That is the PST file.

Double click the
Outlook Data File.
Expand the
Root Container and Top of Outlook Data file and click Calendar once (based of the language for the specific mailbox profile).
Locate on the list of properties the property named PR_NT_SECURITY_DESCRIPTOR and delete it.
Close all of the application windows and repeat for each Outlook profile language required.

Copy the PST files to a network share to be used later on.

Make sure you got the proper permissions for the task
In the next steps you will need the right to list mailboxes and import PST files into mailboxes using Exchange Management Shell with the command New-MailboxImportRequest
You should check if this cmdlet is available to your account to be used. If it is not you probably require additional permissions. Please see the following Link in order to assign the required permissions:
New-MailboxImportRequest

Scripting the import based on correct mailbox language
Now, we need to identify the user mailboxes to which we would like to import the calendar data and the folder language they are using.
If possible ask HR to provide you with a CSV / Excel file containing the user names. If no such list exists you can use the the following command to generate a list of all mailboxes in the organization

$mailboxes = Get-Mailbox -ResultSize unlimited | select Samaccountname,Enabled,Language

You may use filters in order to remove mailboxes you don't like to include in the list.
You can also export this list to a csv file, edit the list manually, and import it back

Use: $mailboxes | export-csv c:\mailboxes.csv -NoTypeInformation
after editing the list using notepad, import it back using:$mailboxes = import-csv c:\mailboxes.csv


Here are the commands you need to run on the list of mailboxes.
Note that you need to customize it to your environment based on languages and PST file paths

# Import the required Exchange and Active Directory modules
Add-PSSnapIn Microsoft.Exchange.Management.PowerShell.E2010 -ErrorAction Stop
Import-Module activedirectory -ErrorAction Stop

# Check each user on the list for the account status
$mailboxes | foreach { $_.Enabled = (get-aduser -Identity $_.samaccountname).enabled }

# Filter out all the disabled mailbox user accounts
$mailboxes = $mailboxes | where { $_.Enabled -eq $true }

# This will search each mailbox for the calendar type folder and mark the language based on
# the folder actual name. Customize it for your own language needs

Foreach ($m in $mailboxes)  { 
$FolderName = $null
$FolderName = (Get-MailboxFolderStatistics $m.samaccountname | ? {$_.foldertype -eq "Calendar"}).name

if ($FolderName -like "Calendar") { $m.Language = "English" }
if ($FolderName -like "*לוח שנה*") { $m.Language = "Hebrew" }

}

# Imports the proper PST file into the user mailboxes
foreach ($m in $mailboxes) {
if ($m.Language -eq "English") { New-MailboxImportRequest –Mailbox $m.samaccountname –FilePath \\Server\PSTShare\English.pst }
if ($i.language -eq "Hebrew") { New-MailboxImportRequest –Mailbox $m.samaccountname –FilePath \\Server\PSTShare\Hebrew.pst }

}

Additional Notes

Import will fail if a mailbox storage limit has been reached.
You can query the status of the import request using 
Get-MailboxImportRequest and clear the competed ones using 
Get-MailboxImportRequest | where {$_.status -eq "Completed"} | Remove-MailboxImportReuest
Use the same logic to remove failed import requests.

In regards to duplicates, it should not happen by default in case you import the same file twice as the default behavior is "KeepSourceItem". This setting can be modified using the ConflictResolutionOption setting in the New-MailboxImportRequest cmdlet.

I will love to get your feedback

Liran