Exchange 2013/16 Journal Mailbox Archive-to-PST PowerShell Script Automation with Reporting

Recent Exchange versions have built-in support of journaling for recording all inbound and outbound email messages for backup or compliance reasons. Overtime, the journal mailbox grows so large and needs to be trimmed or pruned. This script was written to automate the process.

This article documents a PowerShell maintenance script I have written for reporting and automating a monthly archive-to-PST process of the Exchange 2013 journaling mailbox. (Based on reader feedback, it also suits Exchange 2016 Standard.)

Archiving Concept

This script uses the PowerShell cmdlet New-MailboxExportRequest -Mailbox to export Exchange Journaling Mailbox of previous month (e.g. 2016-01-01 to 2016-01-31) as a standard PST file (e.g. archive 2016_01_31.pst) to specified locations (up to two locations) and then uses Search-Mailbox -DeleteContent to delete email messages within the date range if successful. It is designed to be run at the beginning of each month (e.g. 2/Feb/16) using Windows Task Scheduler.

Email Alerting, Reporting and Logging


A log file is created under a specified directory during each execution. An email is sent to specified email addresses with the log file when done. The email message subject indicates COMPLETE/FAILURE.

In addition, a list of email messages returned from search and deleted by Search-Mailbox cmdlet will be available as zip(csv) attachments in another specified mailbox and folder as mentioned in the message body of above email.

Safety Measure to Prevent Accidental Email Deletion

In case mail archiving has failed, script will send an alert mail and exit so that no mail deletion will occur. In technical terms, when status of Get-MailboxExportRequest is not "Completed", script keeps on waiting (looping) until it is complete. If the loop is broken or script receives any status other than "Completed", execution will be terminated and failure will be reported by email.

Assumptions and Requirements

  • PowerShell 3.0 or above
  • Execute this script on Exchange server where (preferably):
    • System Locale is English (United States)
    • Short date format (for en-US) is MM/dd/yyyy
  • Sufficient disk space for storing PST files in the specified location(s)
Note: This script was designed and tested for email messages of previous month, and has not been tested in other configurations but could still work with some tweaking. (In fact, it does not only work for journal mailbox.)

Getting Started – Script Usage and Instructions

  1. Edit variable parameters as required (See sections 1-4 in the script below.)
  2. Save the script in a local folder e.g. C:\scripts\ws_email_archiving_script.ps1
  3. To export email of last month, the script should be scheduled to run any day within the current month.

    For example, to export Jan 2016 email, running the script any day within Feb 2016 would do; the beginning of month is recommended (e.g. 2/Feb/16)

Setting up Windows Task Scheduler

Program/script:
  • C:\Windows\System32\WindowsPowerShell\v1.0\powershell.exe
Add arguments:
  • -PSConsoleFile "C:\Program Files\Microsoft\Exchange Server\V15\Bin\exshell.psc1" -command ". 'C:\Program Files\Microsoft\Exchange Server\V15\Bin\Exchange.ps1'; &'C:\scripts\ws_email_archiving_script.ps1'"
Start in:
  • C:\Scripts
Alternatively, start the .ps1 script using a .bat script:
  • "C:\Windows\System32\WindowsPowerShell\v1.0\powershell.exe" -PSConsoleFile "C:\Program Files\Microsoft\Exchange Server\V15\Bin\exshell.psc1" -command ". 'C:\Program Files\Microsoft\Exchange Server\V15\Bin\Exchange.ps1'; &'C:\scripts\ws_email_archiving_script.ps1'"

PowerShell Script

# WS Email Archiving - Journal Mailbox Archiving PowerShell Script for Exchange 2013
# Written by wandersick (https://tech.wandersick.com/2016/07/powershell-automation-of-journal.html)
# Version: 1.3 (20200614)
# The default parameters of this script assume monthly exporting. See above URL for more information.
# The [Output Examples] in the comment sections below assume:
# Date of script execution: 02 Feburary 2016
# Date of archive period: Between 01 and 31 January 2016 (previous month)
# ----------------------------------------
# 1. DEFINING MAIN VARIABLES
# ----------------------------------------
# Specify name of a journal mailbox where this script will process
# [Output Examples]
# journalMailboxName = "messagejournal"
$journalMailboxName = "Specify a mailbox name here"
# Period of messages to be exported to PST by New-MailboxExportRequest cmdlet
# Note: Previous month is assumed for the default parameters
# Get last day of last month, start day of this month (not converted to string yet)
# [Output Examples]
# endDate = Monday, February 1, 2016 12:00:00 AM
# startDate = Friday, Jaunuary 1, 2016 12:00:00 AM
$endDate = Get-Date -Day 1 "00:00:00"
$startDate = $endDate.AddMonths(-1)
# (continued)
# Get last day of last month in "yyyy_MM_dd" string
# Name PST file using: specified string + last day of last month
# Set file path from it for storing the first copy of PST file
# [Output Examples]
# archiveDate = 2016_01_31
# archiveFile = archive 2016_01_31.pst
# archiveFileDir = \\localhost\e$\Archive_PST\
# archiveFilePath = \\localhost\e$\Archive_PST\archive 2016_01_31.pst
$archiveDate = (Get-Date).AddDays(- (Get-Date).Day).ToString('yyyy_MM_dd')
$archiveFile = "archive " + $archiveDate + ".pst"
$archiveFileDir = "\\localhost\e$\Archive_PST\"
$archiveFilePath = $archiveFileDir + $archivefile
# Make a secondary copy at the end (optional)
# [Output Examples]
# archiveEnable2ndCopy = $true
# archiveFileDir2ndCopy = "\\FileServer\Archive_PST\Secondary_Backup\"
# archiveFilePath2ndCopy = "\\FileServer\Archive_PST\Secondary_Backup\archive 2016_01_31.pst"
$archiveEnable2ndCopy = $false
$archiveFileDir2ndCopy = "\\FileServer\Archive_PST\Secondary_Backup\"
$archiveFilePath2ndCopy = $archiveFileDir2ndCopy + $archivefile
# Log date & time (Set current date and time for use as archive job name and log file name)
$dateTime = Get-Date -format "yyyyMMdd_hhmmsstt"
# Define mailbox export request job name (for New-MailboxExportRequest cmdlet)
# Note: To ensure uniqueness in order for Get-MailboxExportRequest cmdlet to identify the correct job as Complete,
# the default setting of $archiveJobName below defines the archive job string using journal mailbox name, archive date and current date-time
# In addition, the script also checks whether the same mailbox export request job name exists and will attempt to remove the job entry beforehand if it does.
# [Output Examples]
# archiveJobName = messagejournal 2016_01_31 20160202_030034AM
$archiveJobName = $journalMailboxName + " " + $archiveDate + $dateTime
# Define search date string for email message deletion after archiving (by Search-Mailbox cmdlet)
# Note (again): The default settings specify email messages of previous month.
# [Output Examples]
# searchStartDate = 01/01/2016
# searchEndDate = 01/31/2016
# searchDateRange = Received:01/01/2016..31/01/2016
$searchStartDate = $startDate.ToString('MM/dd/yyyy')
$searchEndDate = (Get-Date).AddDays(- (Get-Date).Day).ToString('MM/dd/yyyy')
$searchDateRange = "Received:" + $searchStartDate + ".." + $searchEndDate
# ----------------------------------------
# 2. DEFINING LOG VARIABLES
# ----------------------------------------
# Log file (stdout, stderr)
$logFilePath = "C:\scripts\Log\Log_Email_Archive_$($archiveDate)_$($dateTime).log"
# ----------------------------------------------------------------------------------------------------------------
# 3. DEFINING SEARCH-MAILBOX VARIABLES FOR LOGGING MESSAGES SEARCHED AND DELETED FROM JOURNAL MAILBOX
# ----------------------------------------------------------------------------------------------------------------
# Specify a mailbox (TargetMailbox) and a folder (TargetFolder, within the mailbox) different from the journal mailbox for
# logging email messages searched and deleted under a specified folder within a specified mailbox
# An email message with a zip attachment (CSV inside, listing all email messages returned by the search) will be generated in
# the specified mailbox under the specified folder. Multiple email messages may be generated as needed by Search-Mailbox cmdlet
# This logging features is Exchange-native and provided by Search-Mailbox cmdlet.
# (In contrast, the logging feature in comment section 4, further down below, is provided by this script)
# Definitons from TechNet on Search-Mailbox: https://technet.microsoft.com/en-us/library/dd298173(v=exchg.150).aspx
# TargetMailbox: "The TargetMailbox parameter specifies the identity of the destination mailbox where search results are copied."
# (The mailbox should be precreated by Exchange administrator)
# TargetFolder: "The TargetFolder parameter specifies a folder name in which search results are saved in the target mailbox."
# (The folder, within the mailbox, is created in the target mailbox upon execution.)
$saveSearchLogMailbox = "Specify a different mailbox name here for saving log file of Search-Mailbox results"
$saveSearchLogFolder = "Specify a different folder name Here for saving log file of Search-Mailbox results"
# Tip: The above variables refer to TargetMailbox and TargetFolder from Search-Mailbox cmdlet respectively.
# Read the above Microsoft URL (definition of Search-Mailbox) for how to configure these two parameters.
#
# If still unsure, for these two variables, you may specify '$saveSearchLogMailbox = administrator' and
# '$saveSearchLogFolder = SearchAndDeleteLog' where logs will be emailed to a to-be-created/existing folder
# named 'SearchAndDeleteLog' within the mailbox of 'administrator'.
# --------------------------------------------------------------------
# 4. DEFINING EMAIL VARIABLES FOR MAILING LOG AND RESULTS
# --------------------------------------------------------------------
$emailSender = "Sender <sender@wandersick.com>"
$emailRecipient = "Recipient A <recipienta@wandersick.com>", "Recipient B <recipientb@wandersick.com>"
$emailCc = "Recipient C <recipientc@wandersick.com>"
$emailBcc = "Recipient D <recipientd@wandersick.com>"
$emailSubject = "Monthly Email Archive COMPLETE - " + $startDate.ToString('yyyy/MM') + " - Log Attached"
$emailBody = "This is an automated message after email archiving scheduled task has completed. Please check attached log file as well as $saveSearchLogFolder (folder) within $saveSearchLogMailbox (mailbox) for any problems."
$emailSubjectFailure = "Monthly Email Archive FAILED - " + $startDate.ToString('yyyy/MM') + " - Log Attached"
$emailBodyFailure = "This is an automated message after email archiving scheduled task has failed. Please check attached log file as well as $saveSearchLogFolder (folder) within $saveSearchLogMailbox (mailbox) for any problems."
$emailServer = "172.16.123.123"
$emailAttachment = $logFilePath
# ----------------------------------------
# RECORDING VARILABLES TO LOG FILE
# ----------------------------------------
Write-Output "" | tee $logFilePath -Append
Write-Output "[Variables]" | tee $logFilePath -Append
Write-Output "" | tee $logFilePath -Append
Write-Output '$dateTime = ' $dateTime | tee $logFilePath -Append
Write-Output "" | tee $logFilePath -Append
Write-Output '$endDate = ' $endDate | tee $logFilePath -Append
Write-Output "" | tee $logFilePath -Append
Write-Output '$journalMailboxName = ' $journalMailboxName | tee $logFilePath -Append
Write-Output "" | tee $logFilePath -Append
Write-Output '$startDate = ' $startDate | tee $logFilePath -Append
Write-Output "" | tee $logFilePath -Append
Write-Output '$archiveDate = ' $archiveDate | tee $logFilePath -Append
Write-Output "" | tee $logFilePath -Append
Write-Output '$archiveFile = ' $archiveFile | tee $logFilePath -Append
Write-Output "" | tee $logFilePath -Append
Write-Output '$archiveFileDir = ' $archiveFileDir | tee $logFilePath -Append
Write-Output "" | tee $logFilePath -Append
Write-Output '$archiveFilePath = ' $archiveFilePath | tee $logFilePath -Append
Write-Output "" | tee $logFilePath -Append
Write-Output '$archiveEnable2ndCopy = ' $archiveEnable2ndCopy | tee $logFilePath -Append
Write-Output "" | tee $logFilePath -Append
Write-Output '$archiveFileDir2ndCopy = ' $archiveFileDir2ndCopy | tee $logFilePath -Append
Write-Output "" | tee $logFilePath -Append
Write-Output '$archiveFilePath2ndCopy = ' $archiveFilePath2ndCopy | tee $logFilePath -Append
Write-Output "" | tee $logFilePath -Append
Write-Output '$archiveJobName = ' $archiveJobName | tee $logFilePath -Append
Write-Output "" | tee $logFilePath -Append
Write-Output '$searchStartDate = ' $searchStartDate | tee $logFilePath -Append
Write-Output "" | tee $logFilePath -Append
Write-Output '$searchEndDate = ' $searchEndDate | tee $logFilePath -Append
Write-Output "" | tee $logFilePath -Append
Write-Output '$searchDateRange = ' $searchDateRange | tee $logFilePath -Append
Write-Output "" | tee $logFilePath -Append
Write-Output '$emailSender = ' $emailSender | tee $logFilePath -Append
Write-Output "" | tee $logFilePath -Append
Write-Output '$emailRecipient = ' $emailRecipient | tee $logFilePath -Append
Write-Output "" | tee $logFilePath -Append
Write-Output '$emailCc = ' $emailCc | tee $logFilePath -Append
Write-Output "" | tee $logFilePath -Append
Write-Output '$emailSubject = ' $emailSubject | tee $logFilePath -Append
Write-Output "" | tee $logFilePath -Append
Write-Output '$emailBody = ' $emailBody | tee $logFilePath -Append
Write-Output "" | tee $logFilePath -Append
Write-Output '$emailSubjectFailure = ' $emailSubjectFailure | tee $logFilePath -Append
Write-Output "" | tee $logFilePath -Append
Write-Output '$emailBodyFailure = ' $emailBodyFailure | tee $logFilePath -Append
Write-Output "" | tee $logFilePath -Append
Write-Output '$emailServer = ' $emailServer | tee $logFilePath -Append
Write-Output "" | tee $logFilePath -Append
Write-Output '$emailAttachment = ' $emailAttachment | tee $logFilePath -Append
Write-Output "" | tee $logFilePath -Append
Write-Output '$PSScriptRoot = ' $PSScriptRoot | tee $logFilePath -Append
Write-Output "" | tee $logFilePath -Append
Write-Output '$logFilePath = ' $logFilePath | tee $logFilePath -Append
Write-Output "" | tee $logFilePath -Append
# ----------------------------------------
# EXECUTING MAIN PROCEDURE
# ----------------------------------------
# Create an archiving job (an export request of journal mailbox within last month, with a job name that is uniquely identified, to specified location)
Write-Output "" | tee $logFilePath -Append
Write-Output "Exporting items between $startDate and $endDate" | tee $logFilePath -Append
Write-Output "" | tee $logFilePath -Append
# Ensure no job of the same name exists.
Get-MailboxExportRequest -Name $archiveJobName | Remove-MailboxExportRequest -confirm:$false
New-MailboxExportRequest -ContentFilter "(Received -ge '$startDate') -and (Received -lt '$endDate')" -Mailbox $journalMailboxName -FilePath $archiveFilePath -Name $archiveJobName | tee $logFilePath -Append
# Wait for the archiving job to complete
while (!(Get-MailboxExportRequest -Name $archiveJobName -Status Completed))
{
Write-Output "" | tee $logFilePath -Append
Write-Output "Still exporting... Waiting 30 minutes for it to complete..." | tee $logFilePath -Append
Write-Output "" | tee $logFilePath -Append
Get-MailboxExportRequest -Name $archiveJobName | Get-MailboxExportRequestStatistics | fl | tee $logFilePath -Append
Write-Output "" | tee $logFilePath -Append
Start-Sleep -s 1800
}
# To be safe before deletion, double-check the Complete status of email archiving
$emailArchivingStatus = Get-MailboxExportRequest -Name $archiveJobName -Status Completed | select -expand status
if ($emailArchivingStatus -eq "Completed")
{
Write-Output "" | tee $logFilePath -Append
Write-Output "Export completed." | tee $logFilePath -Append
Write-Output "" | tee $logFilePath -Append
# Getting more details for manual verification/troubleshooting in log file
Get-MailboxExportRequest -Name $archiveJobName | fl | tee $logFilePath -Append
Get-MailboxExportRequest -Name $archiveJobName | Get-MailboxExportRequestStatistics | fl | tee $logFilePath -Append
# Optional: Clean up (but Get-MailboxExportRequest will no longer return information of the previous job for troubleshooting; instead, check log file for troubleshooting)
# Get-MailboxExportRequest -Name $archiveJobName | Remove-MailboxExportRequest -confirm:$false
}
else
{
# Report failure via email and exit script
Write-Output "" | tee $logFilePath -Append
Write-Output "Export failed." | tee $logFilePath -Append
Write-Output "" | tee $logFilePath -Append
# Getting more details for manual verification/troubleshooting in log file
Get-MailboxExportRequest -Name $archiveJobName | fl | tee $logFilePath -Append
Get-MailboxExportRequest -Name $archiveJobName | Get-MailboxExportRequestStatistics | fl | tee $logFilePath -Append
# Optional: Clean up (but Get-MailboxExportRequest will no longer return information of the previous job for troubleshooting; instead, check log file for troubleshooting)
# Get-MailboxExportRequest -Name $archiveJobName | Remove-MailboxExportRequest -confirm:$false
Send-MailMessage -From $emailSender -To $emailRecipient -Cc $emailCc -Bcc $emailBcc -Subject $emailSubjectFailure -Body $emailBodyFailure -SmtpServer $emailServer -Attachments $emailAttachment
Exit
}
# Creating a second copy to specified location
if ($archiveEnable2ndCopy) { Copy-Item -Path $archiveFilePath -Destination $archiveFilePath2ndCopy -Force -Confirm:$false | tee $logFilePath -Append }
# In case there is any error during copying, send email and exit script so that no deletion will occur.
$fileHashSrc = Get-FileHash $archiveFilePath | select -expand hash
$fileHashDst = Get-FileHash $archiveFilePath2ndCopy | select -expand hash
if ($fileHashSrc -eq $fileHashDst)
{
Write-Output "" | tee $logFilePath -Append
Write-Output "Second file copy completed and verified successfully." | tee $logFilePath -Append
Write-Output "" | tee $logFilePath -Append
}
else
{
# Report failure via email and exit script
Write-Output "" | tee $logFilePath -Append
Write-Output "Second file copy verification failed." | tee $logFilePath -Append
Write-Output "" | tee $logFilePath -Append
Send-MailMessage -From $emailSender -To $emailRecipient -Cc $emailCc -Bcc $emailBcc -Subject $emailSubjectFailure -Body $emailBodyFailure -SmtpServer $emailServer -Attachments $emailAttachment
Exit
}
# Creating a log file of email messages to be deleted, then delete email (after PST export task is complete)
# This might have to be run multiple times (automatically) in order to get rid of all (>10000) email messages as 10000 is the limit of a single Search-Mailbox query.
# Except the first run, any subsequent run of the mail deletion command only happens when remaining item count is 10000.
do
{
Write-Output "" | tee $logFilePath -Append
Write-Output "Logging a list of items in journal mailbox to be deleted into $saveSearchLogFolder (Folder) of $saveSearchLogMailbox (Mailbox)" | tee $logFilePath -Append
Write-Output "" | tee $logFilePath -Append
# Creating a log file of email messages to be deleted
$remainingItemCount = Get-Mailbox -Identity $journalMailboxName | Search-Mailbox -SearchQuery $searchDateRange -LogOnly -LogLevel Full -TargetFolder $saveSearchLogFolder -TargetMailbox $saveSearchLogMailbox | select -expand ResultItemsCount
Write-Output '$remainingItemCount = ' $remainingItemCount | tee $logFilePath -Append
Write-Output "" | tee $logFilePath -Append
Write-Output "Deleting archived messages from journal mailbox with specified date range: $searchDateRange" | tee $logFilePath -Append
Write-Output "" | tee $logFilePath -Append
# Delete email
Get-Mailbox -Identity $journalMailboxName | Search-Mailbox -SearchQuery $searchDateRange -DeleteContent -force | tee $logFilePath -Append
# Sleep for 5 minutes only when there are more email messages to delete (may not be required)
if ($remainingItemCount -eq 10000)
{
Write-Output "" | tee $logFilePath -Append
Write-Output "Sleep for 5 minutes" | tee $logFilePath -Append
Write-Output "" | tee $logFilePath -Append
start-sleep -s 300
}
}
while ($remainingItemCount -eq 10000)
Write-Output "" | tee $logFilePath -Append
Write-Output "Sending an email with log to $emailRecipient cc $emailCc bcc $emailBcc " | tee $logFilePath -Append
Write-Output "" | tee $logFilePath -Append
# Send an email using local SMTP server with log when done.
Send-MailMessage -From $emailSender -To $emailRecipient -Cc $emailCc -Bcc $emailBcc -Subject $emailSubject -Body $emailBody -SmtpServer $emailServer -Attachments $emailAttachment

Download

⭐ The script can be downloaded at GitHub 

Word of Mouth

Below are some of the kind comments left by users of this script. (Thanks!)
  • "We have some very large journaling mailboxes that we've been racking our brains trying to figure out what to do with to stop the sprawl. We're on Exchange 2016 Standard, so we're limited on our database count. This script has made it really easy for us to dig out emails by month and save them off to PST that we can store out on second tier storage for archive. Thanks for this!"
  • "I've used your script for a couple of years. It's GREAT and do a GREAT job. Thank you very much!"

Release History

Ver Date Update
1.3 20200614 - Add missing bcc parameters in the first two lines of Send-MailMessage
- Change default setting of archiveEnable2ndCopy to false as it should not be commonly enabled
- Add a tip in the comment section of the script at part 3 to make it easier to configure the parameters
1.2 20171022 - Turn journal mailbox name into a variable
- Further ensure New/Get-MailboxExportRequest job name uniqueness by naming it with current date time (in yyyyMMdd_hhmmsstt)
- Remove unused variables, scriptDir, startDateShort and endDateShort
- Improve script comments
1.1 20160712 First public release
1.0 20160314 First internal release
Welcome to support this project by buying a cup of coffee if this tool is useful to you. 😊 Thanks! If you would love the script to be further developed, you may engage professional services on one of the freelancing platforms.

References

  1. How can I move Exchange items to a PST using PowerShell?
    http://serverfault.com/questions/511610/how-can-i-move-exchange-items-to-a-pst-using-powershell

  2. MailboxExportRequest ContentFilter is “Received -ne $null” when querying by date
    http://serverfault.com/questions/591798/mailboxexportrequest-contentfilter-is-received-ne-null-when-querying-by-date

  3. Cannot get Exchange PowerShell script to run under Scheduled Tasks
    http://serverfault.com/questions/576302/cannot-get-exchange-powershell-script-to-run-under-scheduled-tasks

Comments

  1. Great Idea! thanks for that, How i can change this for take daily backups?

    ReplyDelete
    Replies
    1. Hi Enes S, thanks for your interest in the script. To clarify your question, do you mean that you want to apply the script for email messages of the previous day? (Note: this script was designed and extensively tested for email messages of the previous month only)

      To answer your question, you need to (at least):
      1. Configure $endDate and $startDate (required for New-MailboxExportRequest cmdlet to export to PST)
      2. Configure $searchStartDate and $searchEndDate (required for Search-Mailbox cmdlet to delete exported email messages)
      3. Update the content of the email message to be sent after the process.

      I have updated (reorganized) the script and the blog post a bit in the hopes that it will be more readable and 'tweakable' in order to use for other purposes.

      I have tried not to miss any key things. Please bare with me if I do. :)

      Delete
  2. We have some very large journaling mailboxes that we've been racking our brains trying to figure out what to do with to stop the sprawl. We're on Exchange 2016 Standard, so we're limited on our database count. This script has made it really easy for us to dig out emails by month and save them off to PST that we can store out on second tier storage for archive. Thanks for this!

    ReplyDelete
    Replies
    1. Thanks for sharing your experience with the script on Exchange 2016 Standard!

      Since there are newer Exchange Server major releases now, I will consider better naming the title of this post so that people using those versions may still benefit from it. (If you or anyone have done any readaptation to fit specific use cases, that would be nice to know as well.)

      Delete
  3. Great Idea! thanks for that, How i can change this for take daily backups

    ReplyDelete
    Replies
    1. Hi Basem,

      Thanks for your question. Below are the variables you need to adjust (primarily):

      1. New-MailboxExportRequest cmdlet (handles exporting email to PST files)
      - $endDate
      - $startDate

      2. Search-Mailbox cmdlet (handles deletion of exported email)
      - $searchStartDate
      - $searchEndDate

      In case you need to further develop this script, consider hiring an expert through freelancing marketplaces. By coincidence, I just wrote an article on the topic.

      Delete
  4. Hello wandersick,

    I use your script from couple of years. Its GREAT and do GREAT job. Thank you very much!!!
    I`m not good in scripting but because I have some issues with it I make modifications.
    It runs every 10 days as it keep at least 10 days history in Journal mailbox and in my case it make 10GB .pst achives.
    And because New-MailboxExportRequest -ContentFilter cant work with dates with localization other from "en-US" I added it temporally for session /Exchange 2013, Server 2012R2/
    And after exporting the .pst file is stay locked sometimes for a few more minutes, so I added a check before start coping to secondary location.

    I don't know if it's convenient to share the changes here, if you find them useful. Excuse me if it's not appropriate.
    Thanks again!
    ...
    I cant post ... too big... share in google drive:
    https://drive.google.com/file/d/1OqVNfsTFRIWrrl0MBIu93CWOQZbzcvG4/view?usp=sharing

    ReplyDelete
    Replies
    1. Hello connann2,

      I am glad to see you successfully implement the script in a Windows Server with a locale other than en-US and contribute your solution for that (along with improvements like checking whether exported archive file is locked and enabling ExcludeDumpster)

      Thanks for sharing your experience! In the future, I may integrate your changes into the main script so that others can be benefited. (I will credit you for that of course. Kindly let me know in case that is not OK, and feel free to let me know how you want to be credited, e.g. an URL and a name if not 'connann2'.)

      P.S. I would suggest using a service like GitHub Gist for posting code, or even better, fork the GitHub repository and then share yours. :)

      Have a good day!

      Delete
    2. Hello, wandersick,

      Thank you for the reply. Don't worry about credit my name, I'll be happy if you find something useful from my modifications. I still use your work for free :)

      I forgot to mention that I saw a problem with the Search-Mailbox and New-MailboxExportRequest functions - one uses GMT time and the other local time. And so there is a difference of several hours between the limit for archived and deleted emails. So I replaced endDate = (Get-Date "00:00:00") with
      $ endDate = (Get-Date [TimeZoneInfo] :: Local) .BaseUtcOffset.ToString () ...
      This may be a local problem, I'm GMT + 2 hours.

      Thank you again!

      Delete
    3. That's good to know.

      Thanks for the improvement you have brought to the script again!

      Delete
    4. Hello, wandersick.
      Big thank's for your script!
      Default script is worked. But if I changed to run this script with another dates script end with error "Second file copy verification failed."
      I didn't change default $archiveEnable2ndCopy = $false
      Do you help me?

      Delete
    5. Could you please try configuring a secondary copy by setting $archiveEnable2ndCopy = $true and configure a UNC path to store the secondary copy by setting $archiveFileDir2ndCopy (refer to the example in the script)? Would it work after doing so?

      Delete

Post a Comment