Outlook Automation- Move emails – Powershell

Hi Readers,

Today, I am sharing another script in Outlook Automation Category.

This is script is customized and is environment specific but can be referenced for doing outlook automatons.

Requirement:-

In a folder there are Messages received from Monitoring solution (open alert & Closed alert), each Message has unique element evenid.

Script should go thru all the messages, grab them that have closed/ open (both status) for an event , after that move those emails to some other folder.

The only thing that remains in current folder should be open alerts.

So here is the script, I am including reg key as well that stops outlook popup that says (An external program is trying to access)

Download he script from below link:

http://gallery.technet.microsoft.com/scriptcenter/Outlook-Automation-Move-6efe7cce

Script is multithreaded for faster processing (4 jobs run at ones)

run outlook.bat file, it will result in below Popup:

fill the values (working folder is where all alerts arrive & target folder is where we want to move the alerts that have closed / open “both status” )

Hit ok, processing will begin:

email body example:

Please change the below details at the top of script so that you will be getting error email if script fails

$smtpServer = “smtpserver”

$from = “OutlookautomationScript@labtest.com”

$to = “Vikas.Sukhija@labtest.com”

PowerShell
##################################################################################### 
#             Author: Vikas Sukhija 
#             Date:- 03/07/2014 
#           Description:- read emailbody,extract eventid , find duplicate  
#            & move to another folder  
#                       Prerequisites :- Powershell/Outlook 
##################################################################################### 

###############################Logs################################################## 
$date = get-date -format d 
$date = $date.ToString().Replace(“/”, “-”) 
$time = get-date -format t 
$time = $time.ToString().Replace(":", "-") 
$time = $time.ToString().Replace(" ", "") 

$log1 = ".\Logs" + "\" + "Processed_1" + $date + "_.log" 
$log2 = ".\Logs" + "\" + "Processed_2" + $date + "_.log" 

$logs = ".\Logs" + "\" + "Powershell" + $date + "_" + $time + "_.txt" 

$smtpServer = "smtpserver" 
$from = "OutlookautomationScript@labtest.com" 
$to = "Vikas.Sukhija@labtest.com" 

#########################Creating custom Button###################################### 
function button ($title,$mailbx, $WF, $TF) { 

[void][System.Reflection.Assembly]::LoadWithPartialName( "System.Windows.Forms")  
[void][System.Reflection.Assembly]::LoadWithPartialName( "Microsoft.VisualBasic")  

    $form = New-Object "System.Windows.Forms.Form"; 
    $form.Width = 500; 
    $form.Height = 150; 
    $form.Text = $title; 
    $form.StartPosition = [System.Windows.Forms.FormStartPosition]::CenterScreen; 

    $textLabel1 = New-Object "System.Windows.Forms.Label"; 
    $textLabel1.Left = 25; 
    $textLabel1.Top = 15; 

    $textLabel1.Text = $mailbx; 

    $textLabel2 = New-Object "System.Windows.Forms.Label"; 
    $textLabel2.Left = 25; 
    $textLabel2.Top = 50; 

    $textLabel2.Text = $WF; 

    $textLabel3 = New-Object "System.Windows.Forms.Label"; 
    $textLabel3.Left = 25; 
    $textLabel3.Top = 85; 

    $textLabel3.Text = $TF; 

    $textBox1 = New-Object "System.Windows.Forms.TextBox"; 
    $textBox1.Left = 150; 
    $textBox1.Top = 10; 
    $textBox1.width = 200; 

    $textBox2 = New-Object "System.Windows.Forms.TextBox"; 
    $textBox2.Left = 150; 
    $textBox2.Top = 50; 
    $textBox2.width = 200; 

    $textBox3 = New-Object "System.Windows.Forms.TextBox"; 
    $textBox3.Left = 150; 
    $textBox3.Top = 90; 
    $textBox3.width = 200; 

    $defaultValue = "" 
    $textBox1.Text = $defaultValue; 
    $textBox2.Text = $defaultValue; 
    $textBox3.Text = $defaultValue; 

    $button = New-Object "System.Windows.Forms.Button"; 
    $button.Left = 360; 
    $button.Top = 85; 
    $button.Width = 100; 
    $button.Text = "Ok"; 

    $eventHandler = [System.EventHandler]{ 
    $textBox1.Text; 
    $textBox2.Text; 
    $textBox23.Text; 
    $form.Close();}; 

    $button.Add_Click($eventHandler) ; 

    $form.Controls.Add($button); 
    $form.Controls.Add($textLabel1); 
    $form.Controls.Add($textLabel2); 
    $form.Controls.Add($textLabel3); 
    $form.Controls.Add($textBox1); 
    $form.Controls.Add($textBox2); 
    $form.Controls.Add($textBox3); 
    $ret = $form.ShowDialog(); 
    return  $textBox1.Text, $textBox2.Text, $textBox3.Text 
} 

$return= button "Enter Folders" "Enter mailbox" "Working Folder" "Target Folder" 

############################################################################# 

#Start-Transcript -Path $logs  

$mbx = $return[0]   
$fold = $return[1] 
$tfold = $return[2] 

Write-host "Mailbox is $mbx" -foregroundcolor Green 
Write-host "Wokring folder $fold" -foregroundcolor Green 
Write-host "Target folder $tfold" -foregroundcolor Green 

$date1 = get-date 
add-content $log2 "$date1 - Script Started"  
#############################outlook Call############################################# 

$outlook = new-object -com outlook.application; 
$ns = $outlook.GetNameSpace("MAPI"); 
$inbox = $ns.Folders.Item($mbx).folders.Item($fold) 
$messages = $inbox.items 
$totalemail = $messages.count 
write-host "Total Messages to process $totalemail"  -foregroundcolor green 
$date1 = get-date 
add-content $log2 "$date1 - Total Messages to process $totalemail"  
$messcount = $messages.count 
$countprocessed1 = 0 
$openmess = @() 
$compeventid =@() 
$countprocessed = 0 

#########################Find messages with Closed Event ID######################## 

foreach($message in $messages){ 
$msubject = $message.subject 
write-host $msubject -foregroundcolor blue 
if($msubject -like "*CLOSED*") 
        { 
        $mBody = $message.body 
        $mBodySplit = $mBody -split "Event ID:" 
        $toaddress1=$mBodySplit[1] 
        $eventid = $toaddress1 -split "Monitoring Category:" 
        $eventid = $eventid[0].trim() 
        write-host $eventid -foregroundcolor green 
        $compeventid += $eventid 
        }         
} 

$couev = $compeventid.count 
write-host "Total Eventid to process $couev"  -foregroundcolor Red 
$date1 = get-date 
add-content $log2 "$date1 - Total Eventid to process $couev"  

############################Add the Event id in temporary file#################### 

if ($compeventid -ne $null) 
{ 
foreach($eid in $compeventid){ 
Write-host "adding $eid to file" -foregroundcolor yellow 
add-content  $log1 $eid 
} 
} 

if((test-path $log1) -eq $false) 
{ 
new-item $log1 -type file 

} 
#####Get eventids in variable from file & move them to processed folder########### 
##################Multi threading has been used for faster processing############# 
##################4 threads run at the same time################################## 

$compeventid1 = get-content $log1 

foreach($evid in $compeventid1){ 

Start-Job -ScriptBlock { 
        $count = 0 
    $outlook = new-object -com outlook.application; 
    $ns = $outlook.GetNameSpace("MAPI"); 
    $inbox = $ns.Folders.Item($($args[0])).folders.Item($($args[1])) 
    $messages = $inbox.items 
    foreach($message in $messages){ 
    $mBody = $message.body 
    $mBodySplit = $mBody -split "Event ID:" 
    $toaddress1=$mBodySplit[1] 
    $eventid = $toaddress1 -split "Monitoring Category:" 
    $eventid = $eventid[0].trim() 
        if($eventid -eq $($args[2])) 
         { 
    $MoveTarget = $ns.Folders.Item($($args[0])).folders.Item($($args[3])) 
    [void]$message.Move($MoveTarget) 
        $count = $count + 1 
        if($count -eq "2") 
         { 
        break 
         } 
         } 

      }  
   } -ArgumentList $mbx,$fold,$evid,$tfold 

 While((Get-Job -State 'Running').Count -ge 4) 
    { 
        Start-Sleep -Milliseconds 10 
    } 
} 
########################################################################################### 
##################Run ones more to check if all items are processed######################## 

timeout 5 

foreach($evid in $compeventid1){ 
    $outlook = new-object -com outlook.application; 
    $ns = $outlook.GetNameSpace("MAPI"); 
    $inbox = $ns.Folders.Item($mbx).folders.Item($fold) 
    $messages = $inbox.items 
         foreach($message in $messages){ 

            $mBody = $message.body 
            $mBodySplit = $mBody -split "Event ID:" 
            $toaddress1=$mBodySplit[1] 
            $eventid = $toaddress1 -split "Monitoring Category:" 
            $eventid = $eventid[0].trim() 
                if($eventid -eq $evid)  
                 { 
                $MoveTarget = $ns.Folders.Item($mbx).folders.Item($tfold) 
                [void]$message.Move($MoveTarget) 
                        $countprocessed = $countprocessed + 1 

                 } 
     } 
} 

#######if script has processed all items than it will thro message for not executing it again#### 
#######Script needs to be excuted till it echo's that no more run is required#################### 
########Reason is :- False/positive during the run############################################### 

if(($countprocessed -eq 0) -or ($countprocessed -eq $null)) 
{ 
write-host "Total Messages to be Move $countprocessed - No need to run the script again" -foregroundcolor Red 
[System.Windows.Forms.MessageBox]::Show("No need to run the script again") 
$date1 = get-date 
add-content $log2 "$date1 - Total Messages to Move $countprocessed - No need to run the script again" 
if((test-path $log1) -eq $true) 
{ 
move-item $log1 .\logs\Processed_old -force 
} 
} 
else 
{ 
write-host "Total Messages Moved $countprocessed" -foregroundcolor Blue 
[System.Windows.Forms.MessageBox]::Show("PLEASE Run the script again") 
$date1 = get-date 
add-content $log2 "$date1 - Total Messages Moved $countprocessed" 
} 

$date1 = get-date 
add-content $log2 "$date1 - Script finished the Run" 
###########################Report Errors###################################################### 

if ($error -ne $null) 
{ 
$msg = new-object Net.Mail.MailMessage 
$msg.From = $from 
$msg.To.Add($to) 
$smtp = new-object Net.Mail.SmtpClient($smtpServer) 
$msg.Subject = "Outlook Script Error" 
$msg.Body = $error 
$smtp.Send($msg) 
} 
#Stop-Transcript 
#####################################END################################################

Regards

Sukhija Vikas

Advertisements

2 thoughts on “Outlook Automation- Move emails – Powershell

  1. I’ve tried used this as a base to make my own version (totally new to Powershell). It works, but I need it to process a shared mailbox instead of my own. How can I change that?
    Thanks,
    Fredrik

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s