Question

ORIGINAL POST:

Goal: an email is sent to a service account every day from a source. Take the csv file it gives me and put it in a folder for the DBA guy.

Without further adieu, here is my current script:

#define variables
$datestamp = (get-date).AddDays(-1).ToString("MMddyyyy")
$datestamp = $datestamp.ToString()
$path = "C:\MyPath"
$dest = "C:\MyPath\Archive" 
$file = "MyFile.csv"

#create outlook session
$objOutlook   = New-Object -Com Outlook.Application
$inbox   = $objOutlook.Session.GetDefaultFolder(6)

$inbox.Items.Restrict("[UnRead] = True" -and "[SenderEmailAddress] = 'SomePlace@SomeDomain.net'") | select -Expand Attachments | % 
{
    for ($i = $_.Count; $i; $i--) 
    {
      $_.Item($i).SaveAsFile("C:\MyPath\$($_.Item($i).FileName)")
      $_.Parent.Unread = $false
    }
} 

if (Test-Path "C:\MyPath\*.csv")
{
    if(((Get-ChildItem C:\MyPath | Measure-Object ).Count) -gt '1' )
        {
            Send-MailMessage –SmtpServer "server.domain.com" –From "PoorITGuy@domain.com" -To "PoorITGuy@domain.com" -Subject " FAIL" -Body "FAILED. Too many valid items from mailbox.
                $objOutlook.quit()
            [System.Runtime.Interopservices.Marshal]::ReleaseComObject($objOutlook) 
                throw "Too many items to get."  
        }
    else
        {
         Get-ChildItem $path\*.csv | foreach {Copy-Item $_ "C:\MyPath\$"}
         Copy-Item C:\MyPath\*.csv  "$path\$file"
         Copy-Item C:\MyPath\*.csv "$dest\${datestamp}_$file"

            if(Test-Path "$dest\$file")
            {
                Send-MailMessage –SmtpServer "server.domain.com" –From "PoorITGuy@domain.com"   -To "PoorITGuy@domain.com" -Subject "some message”
                #cleanup - remove all files from base directory, clean mailbox, close out com object.
                Remove-Item "$path\*.csv"
                $inbox.Items | select | %
                {
                    for ($i = $_.Count; $i; $i--) 
                    {
                     $_.Item($i).Delete
                    }
                        }
                $objOutlook.quit()
                [System.Runtime.Interopservices.Marshal]::ReleaseComObject($objOutlook)
            }
            else
            {
                Send-MailMessage –SmtpServer "server.domain.com"  –From "PoorITGuy@domain.com" -To "PoorITGuy@domain.com" -Subject " failure" -Body "File manipulation failure."    
                $objOutlook.quit()
                [System.Runtime.Interopservices.Marshal]::ReleaseComObject($objOutlook)
                    throw "File manipulation failure."
            }

        }
}
else
{
        Send-MailMessage –SmtpServer "server.domain.com"  –From "PoorITGuy@domain.com" -To PoorITGuy@domain.com -Subject "FAIL" -Body "No item mailbox."
                $objOutlook.quit()
               [System.Runtime.Interopservices.Marshal]::ReleaseComObject($objOutlook)
                throw "No item to get in inbox."  
}

What doesn't work:

$inbox.Items.Restrict("[UnRead] = True" -and "[SenderEmailAddress] =  'SomePlace@SomeDomain.net'") | select -Expand Attachments | % 

It seems that you cannot restrict the comObject Outlook.Application with more than one filter.

I've done a ton of searching on this and cannot find an answer on how to best perform this task in lieu of this. But I want my script to be spam-proof, so it needs to know that it is sent from the expected sender AND it needs to be unread only (see error catching right below)

In addition, I'm not certain if this would work:

$inbox.Items | select | %
                    {
                        for ($i = $_.Count; $i; $i--) 
                        {
                         $_.Item($i).Delete
                        }
                            }

Also would like input on the script itself. Any input to make it more efficient would be appreciated.

Was it helpful?

Solution

The correct code (lots of syntax errors on the above prevented it from doing what I wanted to)

#define variables
$datestamp = (get-date).AddDays(-1).ToString("MMddyyyy")
$datestamp = $datestamp.ToString()

$path = "C:\MyPath"
$dest = "C:\MyPath\Archive" 
$importpath = "C:\MyPath\Import"
$file = "MyFile.csv"

$folderExclude = "C:\MyPath\Archive"

#create outlook session
$objOutlook   = New-Object -Com Outlook.Application
$inbox   = $objOutlook.Session.GetDefaultFolder(6)



$inbox.Items.Restrict("[Unread] = True AND [SenderEmailAddress] = 'SomePlace@SomeDomain.net'") | select -Expand Attachments | % {
    for ($i = $_.Count; $i; $i--) {
      $_.Item($i).SaveAsFile("\\server\MyPath\$($_.Item($i).FileName)")
      $_.Parent.Unread = $false
    }
} 

if (Test-Path "C:\MyPath\*.csv") {
    if(((Get-ChildItem C:\MyPath -Include "*.csv" | Measure-Object ).Count) -gt '1' ) {
            Send-MailMessage -SmtpServer smtpserver.mydomain.com -From Powershell@mydomain.com -To someguy@mydomain.com -Subject "FAIL" -Body "FAILED. Too many items from PSAutomationSrv mailbox."
                $objOutlook.quit()
            [System.Runtime.Interopservices.Marshal]::ReleaseComObject($objOutlook) 
                throw "Too many items to get."  
        }
    else {
         Copy-Item C:\MyPath\*.csv  "$importpath\$file"
         Copy-Item C:\MyPath\*.csv "$dest\${datestamp}_$file"

            if(Test-Path "$dest\${datestamp}_$file") {
                Send-MailMessage -SmtpServer smtpserver.mydomain.com -From Powershell@mydomain.com -To someguy@mydomain.com -Subject " successful" -Body "Date is: ${datestamp} File name is: ${dest}\${file}"
                #cleanup - remove all files from base directory, clean mailbox, close out com object.
                Remove-Item $path\*.csv
                $objOutlook.quit()
                [System.Runtime.Interopservices.Marshal]::ReleaseComObject($objOutlook)
            }
            else {
                Send-MailMessage -SmtpServer smtpserver.mydomain.com -From Powershell@mydomain.com -To someguy@mydomain.com -Subject " import - failure" -Body "File manipulation failure." 
                $objOutlook.quit()
                [System.Runtime.Interopservices.Marshal]::ReleaseComObject($objOutlook)
                    throw "File manipulation failure."
            }           
        }
}
else {
        Send-MailMessage -To -SmtpServer smtpserver.mydomain.com -From Powershell@mydomain.com -To someguy@mydomain.com -Subject "FAIL" -Body "FAILED. No item in mailbox."
                $objOutlook.quit()
            [System.Runtime.Interopservices.Marshal]::ReleaseComObject($objOutlook)
                throw "No item to get in inbox."  
}

Notes - I had some code in excess.

Get-ChildItem $path\*.csv | foreach {Copy-Item $_ "C:\MyPath\$"}

is incorrect syntax, and unnecessary since the script already knows it is just manipulating one file anyway.

For deleting the inbox I would need to use Export-Mailbox it seems, which I do not want to do; as the service account performing this function is NOT an exchange admin nor do I want it to be. I'm just going to manually delete the inbox periodically or have the exchange guy do it on his end.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top