Warm tip: This article is reproduced from stackoverflow.com, please click
outlook powershell

Outlook Emails ReceivedTime Out of Order in Powershell

发布于 2020-03-27 10:20:24

Longtime lurker and first-time poster, so I'll try to be as specific as possible here!

The goal of a script I am writing is to grab a start and end date from an excel file and use that range to pull the most recent email from Outlook that lies within that range. The information within these emails is then used to make a report in a spreadsheet.

The script works as intended EXCEPT for the fact that there are certain dates whose ReceivedTime property is out of order and it winds up grabbing the earliest possible entry instead of the latest.

If I type $Emails.ReceivedTime into the console, it will show them out of order which is causing the issue. If I type $Emails.ReceivedTime | sort, the issue goes away. My problem is that no matter where I've tried plugging this into my script, it will just hang and never finish execution.

Function GetEmails ()
{
    Add-Type -Assembly "Microsoft.Office.Interop.Outlook"
    $Outlook = New-Object -ComObject Outlook.Application
    $Namespace = $Outlook.GetNameSpace("MAPI")
    $Inbox = $Namespace.Folders.Item('UsernameHere').Folders.Item('Inbox').Items
    return $Inbox
}

Function GetXYZ($Emails) {

    $XYZ = $null
    foreach($Email in $Emails) {   
        if ($Email.SenderEmailAddress -ne $null -and $Email.SenderEmailAddress.Contains('xyz@123.com')) {  
            if (($Email.ReceivedTime -le $end_date) -and ($Email.ReceivedTime -ge $start_date)) {  

                $XYZ = New-Object psobject -Property @{'Sender' = $Email.SenderEmailAddress; 'Time' = $Email.ReceivedTime; 'Body' = $Email.Body}                  
            }

        }
    }

    #Split the body of the email into an array and remove whitespace from the array.
    $Array = $XYZ.Body.Split("`r`n",[System.StringSplitOptions]::RemoveEmptyEntries)

    #Create an array of numeric values only
    $numArray = @()
    $numArray += $Array -replace '[^.0-9]'

    $junk1, [int]$Item1, [int]Item2, [int]$Item3, $junk2 = $numArray

    return New-Object psobject -Property @{'Name' = 'XYZ'; 'Time' = $XYZ.Time; 'Item1' = $Item1.toString("N0"); 'Item2' = $Item2.toString("N0"); 'Item3' = $Item3.toString("N0")}
}


$Emails = GetEmails

GetXYZ($Emails)

#Rest of the code runs here to do things unrelated to my problem...

This is the first 10 email ReceivedTimes currently:

Thursday, May 23, 2019 7:22:19 AM

Thursday, May 23, 2019 6:55:07 AM

Thursday, May 23, 2019 6:22:18 AM

Thursday, May 23, 2019 6:03:07 AM

Thursday, May 23, 2019 6:02:21 AM

Thursday, May 23, 2019 5:22:17 AM

Thursday, May 23, 2019 4:22:03 AM

Thursday, May 23, 2019 3:55:07 AM

Thursday, May 23, 2019 3:22:18 AM

Thursday, May 23, 2019 3:01:33 AM

This is what the first 10 lines SHOULD be:

Wednesday, April 3, 2019 9:00:07 AM

Thursday, April 4, 2019 9:00:04 AM

Friday, April 5, 2019 9:00:08 AM

Saturday, April 6, 2019 5:03:22 AM

Saturday, April 6, 2019 5:11:22 AM

Saturday, April 6, 2019 5:22:29 AM

Saturday, April 6, 2019 7:08:59 AM

Saturday, April 6, 2019 8:11:08 AM

Saturday, April 6, 2019 8:55:45 AM

Saturday, April 6, 2019 9:00:02 AM

If I left out anything important here please feel free to let me know, and thanks in advance!

Questioner
whitehudson
Viewed
98
Dmitry Streblechenko 2019-07-04 00:10

If you never call Items.Sort, you should not expect any particular order. In your particular case, if you want the Items collection to be sorted on the ReceivedTime property, you should call Items.Sort("[ReceivedTime]", true).

Also, as Eugene mentioned, if you are only processing a subset of items, teh filtering must be done on the server side - use Items.Restrict or Items.Find/FindNext. IN your particular case, Items.Restrict would probably be more appropriate.