Home > OS >  Save attachments and move e-mails from shared box in PowerShell
Save attachments and move e-mails from shared box in PowerShell

Time:04-12

I have a question on Powershell. What I'm trying to do is looping through the inbox of a shared (group) mailbox, if the e-mail comes from a set of 2 sender names then save the CSV Attachments to a specific folder and then move the e-mail to another sub-folder of inbox. I managed this morning to make it work for the loop-save attachment part on one sender's name, but then somehow broke the code (on the first foreach loop). Plus, I am not able to run the "move e-mail" part.

Here's the code I got:

#define outlook object and ask to pick folder
$outlook = New-Object -comobject outlook.application
$mapi = $outlook.GetNamespace("MAPI")
$fldr = $mapi.PickFolder()
$DestFolder = "\\MAIBOXNAME\Inbox\01.Reports"
#use i as counter to define filenumber to save PendingOrders
$i = 1
$fldr.Items| foreach  {$fldr.Items.Sender.Name -like "Name1" - or $fldr.Items.Sender.Name -like "Name2"
    $year = $fldr.Items.ReceivedTime.ToString("yyyy")
    $month = $fldr.Items.ReceivedTime.ToString("MM")
    $fdate = $fldr.Items.ReceivedTime.ToString("yyyy.MM.dd")
    $fpath = "Path\02.Daily Files\"   $year   '\'   $year   '.'   $month   '\'   $fdate
    #loop through attachments to find CSV extension - if found, save file to target path with the counter in the name and update the counter
    $fldr.Items.Attachments|foreach {
        $_.Filename
        If ($_.filename.Contains("CSV")) {                    
            $fname = $_.filename           
            $_.saveasfile((Join-Path $fpath  "00$i $fname"))
            $i = $i   1 
        }
    $_.Move($DestFolder)
    }
}

Could you please assist me in finalising this?

Thanks a lot!!

CodePudding user response:

Never loop through all items in a folder - it is like having a SELECT clause in SQL without a WHERE clause. Use Items.Restrict or Items.Find/FindNext with a query @SQL=("http://schemas.microsoft.com/mapi/proptag/0x0C1A001F" LIKE '%Name1%') OR ("http://schemas.microsoft.com/mapi/proptag/0x0C1A001F" LIKE '%Name1%') (the DASL name is for the PR_SENDER_NAME MAPI property.

Secondly, I am not a PS expert, but your syntax is off - $fldr.Items.ReceivedTime is invalid: ReceivedTime is a property on the MailItem object (returned from the Items collection), not on the Items collection itself.

CodePudding user response:

This works as expected. it's not sexy, but it works :)

#define outlook object and ask to pick folder
$outlook = New-Object -comobject outlook.application
$mapi = $outlook.GetNamespace("MAPI")
$fldr = $mapi.Stores['xxxxxxxxxx'].GetRootFolder().Folders("Inbox")
$DestFolder = $mapi.Stores['xxxxxxxxxx'].GetRootFolder().Folders("Inbox").Folders("01.Reports")
$delFile = 1
$fldr.Items| 
    Where-Object{$_.SenderName -eq "Name1" -or $_.SenderName -eq "Name2"} |
    ForEach-Object{
            $year = $_.ReceivedTime.ToString("yyyy")
            $month = $_.ReceivedTime.ToString("MM")
            $fdate = $_.ReceivedTime.ToString("yyyy.MM.dd")
            #Find newest csv file in folder and use it as counter, if empty start from 1
            $fpath = "SomePath\"   $year   '\'   $year   '.'   $month   '\'   $fdate
            #create temporary csv file to start archiving xls file from 1
            New-Item -Path (Join-Path $fpath "00.csv") -ItemType File
            if ($delFile -ne 1) {
                Remove-Item (Join-Path $fpath "00.csv")
            } 
            $delFile = $delFile  1
            $filter="*CSV"
            $lastCsv= Get-ChildItem -Path $fpath -Filter $filter | Sort-Object LastAccessTime -Descending | Select-Object -First 1
            if ($lastCsv) { 
                $i = [int]$lastCsv.name.substring(0,3)   1
            } 
            else { 
                $i = [int]1
            }
            #loop through attachments to find CSV extension - if found, save file to target path with the counter in the name and update the counter
            $_.Attachments|foreach {
                $_.FileName
                If ($_.FileName.Contains("CSV")) {                    
                    $fname = $_.FileName           
                    $i = '{0:d3}' -f  $i
                    $_.SaveAsFile((Join-Path $fpath  "$i $fname"))
                    $i = [int]$i   1
                }
            }
        $_.Move($DestFolder)
    }
  • Related