среда, 23 января 2013 г.

Автоимпорт PST в Exchange и автоматические оповещения

В определенный момент понадобилось переехать с некой системы архивирования на архивы Excahnge. Шаг не лучший, но, к сожалению, предыдущая система архивирвоания плохо масштабировалась и имела свои недостатки.

Основной проблемой, которая встретилась при переезде оказалось перемещение почты из системы архивирования обратно в Exchange. Из-за наличия багов в работе Outlook процесс прямой выгрузки сообщений в почтовый ящик имел ненулевую вероятность остановки с ошибкой и требовал ручного продолжения. К счастью можно было выгружать архивы в PST, что было в 7-10 раз быстрее и не давало сбоев. Надо было только автоматизировать процесс импорта.

Для автоматизации импорта смотрим в папку, в которую производится экспорт ($pst_path), благо имена файлов содержат кусочек, по которому можно идентифицировать оригинальный почтовый ящик (регекс $name_match). Так как файл может активно писаться, проверяем, что последняя запись была минимум час назад.

Чтобы не запускать импорт несколько раз в имя задания пишем имя файла и преред добавлением проверяем, есть ли у нас уже задание по импорту этого файла. При завершении импорта (а так же задания экспорта и перемещения ящиков - для чего первоначально и писался скрипт) удаляем задание и файл.

Код запускается шедулером раз в 4 часа из под пользователя с правами Import-Export и User Management (вроде так...).Сам код:

####################################################################
# Завершить перемещение ящиков, отправить отчет
# об очереди и завершенных перемещениях
####################################################################

####################################
# ***         MAIN             *** #
####################################

# Excahnge connector
Add-PSSnapin Microsoft.Exchange.Management.PowerShell.E2010
$sendmail=$false
$mailsrv="192.168.0.60"

$mail_from="Script Notice <notice@contoso.ru>"
$mail_to="mailadmin@contoso.ru"

$pst_path="\\archive\export\"
$name_match="(?<surname>[a-zA-Z]+),(?<name>[a-zA-Z]+)(?<ext>(\([a-zA-Z]+\))?)_Export_\d{4}.pst$"

function init-msg() {
    return  "
        <html>
        <head>
            <style>
                table#output {
                    border-style: hidden;
                    border-width: 1px;
                    padding: 0px;
                    border-color: black;
                /*    background-color: #E1E1DF; /* Цвет фона */
                }

                table#output th{
                    border-style: solid;
                    border-width: 1px;
                    padding: 2px;
                    border-color: black;
                    background-color: #E1E1DF; /* Цвет фона */
                }

                table#output td {
                    border-style: hidden;
                    padding: 1px;
                    background-color: white; /* Цвет фона */
                }
            </style>
        </head>
        <body>
        `n"
}

#######################################
# get files from fileshare to import
$files=get-childitem $pst_path

#get files, queued for import
$import=get-mailboximportrequest | select name
$import_=@()
foreach($i in $import) {$import_+=$i.name}

#######################################
# Queue PSTs for import
$age=(get-date).addhours(-1)
foreach ($f in $files) {
    #file name matches pattern and was not written for some time - export already finished, can import
    if( $f.name -match $name_match -and $f.LastWriteTime -lt $age) {
        #is file already queued?
        if($import_ -notcontains $matches[0]) {
            $mbx=$matches["surname"]+", "+$matches["name"]
            #if contains (xxx), add it
            if($matches["ext"]) {
                $mbx+=" "+$matches["ext"]
                }
            new-MailboxImportRequest -isarchive -mailbox $mbx -filepath $f.fullname -batchname $matches[0] -name $matches[0] -ConflictResolutionOption KeepSourceItem
            }
    }
}
#######################################
# Move Request
$items=get-moverequest
if($items) {
    $msg+= "<br />Mailboxes moving:"
    $msg+= "<table id=`"output`"><tr><th>Name</th><th>Source Database</th><th>Target Database</th><th>Status</th></tr>"
    foreach($i in $items) {
        if($i.status -eq "InProgress") {
            $stats=get-MoveRequestStatistics $i.guid
            $status="Moving: "+$stats.PercentComplete+"%"
        } else {
            $status=[string]$i.status
            #complete moverequest
            if($i.status -eq "Completed") {
                remove-moverequest $i.guid -confirm:$false
            }
        }
        $msg+="<tr><td>"+$i.displayname+"</td><td>"+$i.SourceDatabase+"</td><td>"+$i.TargetDatabase+"</td><td>"+$status+"</td></tr>"
    }
    $msg+="</table>"
    
 $sendmail=$true
}  
#######################################
# Export Request
$items=Get-MailboxExportRequest
if($items) {
 $msg+="<br />Mailbox Export status:"
    $msg+= "<table id=`"output`"><tr><th>Name</th><th>Destination</th><th>Status</th></tr>"
    foreach ($item in $items) {
        if($item.status -eq "InProgress") {
            $stats=$item | get-MailboxExportRequestStatistics
            $status="Progress: "+$stats.PercentComplete+"%"
        } else {
            $status=[string]$item.status
            if($item.status -eq "Completed") {
                Remove-MailboxExportRequest $item -Confirm:$false
            }
        }
        $msg+="<tr><td>"+$item.mailbox.name+"</td><td><a href=`"file:///"+($item.filepath)+"`"></a></td><td>"+$status+"</td></tr>"
    }
    $msg+="</table>"
    $sendmail=$true
}

#######################################
# Import Request

$items=Get-MailboxImportRequest
if($items) {
 $msg+="<br />Mailbox Import status:"
    $msg+= "<table id=`"output`"><tr><th>mailbox name</th><th>Job Name</th><th>Source</th><th>Status</th></tr>"
    foreach ($item in $items) {
        if($item.status -eq "InProgress") {
            $stats=get-mailboxImportRequestStatistics $item.identity.requestguid
            $status="Progress: "+$stats.PercentComplete+"%"
        } else {
            $status=[string]$item.status
            #remove completed, remove pst
            if($item.status -eq "Completed") {
                #if importing from vault
                if($item.name -match $name_match) {
                    remove-item ($item.filepath)
                }
                remove-mailboxImportrequest $item -confirm:$false
            }
        }
        $msg+="<tr><td>"+$item.mailbox.displayname+"</td><td>"+($item.BatchName)+"</td><td><a href=`"file:///"+($item.filepath)+"`"></a></td><td>"+$status+"</td></tr>"
    }
    $msg+="</table>"
    $sendmail=$true
}

 if($sendmail) {
 $msgbody=init-msg
 $msgbody+=$msg
 $msgbody+="</body></html>"
 Send-MailMessage  -From $mail_from -to $mail_to -Subject "Статус перемещения ящиков" -Body $msgbody -BodyAsHtml -Encoding ([System.Text.Encoding]::UTF8) -SmtpServer $mailsrv
}

Комментариев нет:

Отправить комментарий