Retrieve calendar items (Outlook API, WebDAV) displaying strange behaviour Retrieve calendar items (Outlook API, WebDAV) displaying strange behaviour vba vba

Retrieve calendar items (Outlook API, WebDAV) displaying strange behaviour


Possible cause:

  • Sort after setting IncludeRecurrences.

Here is my code of a PowerShell module that retrieves Outlook items between two dates.

And a little applet to check for changes and send an email including the agenda updates, which comes handy when you don't have mobile access to the Exchange.

Path: Documents\WindowsPowerShell\Modules\Outlook\expcal.ps1

Function Get-OutlookCalendar{  <#   .Synopsis    This function returns appointment items from default Outlook profile   .Description    This function returns appointment items from the default Outlook profile. It uses the Outlook interop assembly to use the olFolderCalendar enumeration.    It creates a custom object consisting of Subject, Start, Duration, Location    for each appointment item.   .Example    Get-OutlookCalendar |    where-object { $_.start -gt [datetime]"5/10/2011" -AND $_.start -lt `    [datetime]"5/17/2011" } | sort-object Duration    Displays subject, start, duration and location for all appointments that    occur between 5/10/11 and 5/17/11 and sorts by duration of the appointment.    The sort is the shortest appointment on top.   .Notes    NAME:  Get-OutlookCalendar    AUTHOR: ed wilson, msft    LASTEDIT: 05/10/2011 08:36:42    KEYWORDS: Microsoft Outlook, Office    HSG: HSG-05-24-2011   .Link     Http://www.ScriptingGuys.com/blog #Requires -Version 2.0 #> echo Starting... Initialize variables Add-type -assembly "Microsoft.Office.Interop.Outlook" | out-null $olFolders = "Microsoft.Office.Interop.Outlook.OlDefaultFolders" -as [type] $olCalendarDetail = "Microsoft.Office.Interop.Outlook.OlCalendarDetail" -as [type] echo ... Getting ref to Outlook and Calendar ... $outlook = new-object -comobject outlook.application $namespace = $outlook.GetNameSpace("MAPI") $folder = $namespace.getDefaultFolder($olFolders::olFolderCalendar) echo ... Calculating dates ... $now = Get-Date -Hour 0 -Minute 00 -Second 00 echo From $a To $b echo ... Getting appointments ... $Appointments = $folder.Items $Appointments.IncludeRecurrences = $true $Appointments.Sort("[Start]") echo ... Setting file names ... $oldfile = "$env:USERPROFILE\outlook-calendar.bak" echo oldfile: $oldfile $newfile = "$env:USERPROFILE\outlook-calendar.txt" echo newfile: $newfile $calfile = "$env:USERPROFILE\outlook-calendar.ics" echo calfile: $calfile echo ... Exporting calendar to $calfile ... $calendarSharing = $folder.GetCalendarExporter() $calendarSharing.CalendarDetail = $olCalendarDetail::olFullDetails $calendarSharing.IncludeWholeCalendar = $false $calendarSharing.IncludeAttachments = $false $calendarSharing.IncludePrivateDetails = $true $calendarSharing.RestrictToWorkingHours = $false $calendarSharing.StartDate = $now.AddDays(-30) $calendarSharing.EndDate = $now.AddDays(30) echo $calendarSharing $calendarSharing.SaveAsICal($calfile) echo ... Backing up $newfile into $oldfile ... if (!(Test-Path $newfile)) {  echo "" |Out-File $newfile } # Backup old export into $oldfile if (Test-Path $oldfile) {  echo "Deleting old backup file $oldfile"  del $oldfile  } echo " ... moving $newfile into $oldfile ... " move $newfile $oldfile echo "... Generating text report to file $newfile ..." $Appointments | Where-object { $_.start -gt $now -AND $_.start -lt $now.AddDays(+7) } |   Select-Object -Property Subject, Start, Duration, Location, IsRecurring, RecurrenceState  |  Sort-object Start |  Out-File $newfile -Width 100 echo "... Comparing with previous export for changes ..." $oldsize = (Get-Item $oldfile).length $newsize = (Get-Item $newfile).length if ($oldsize -ne $newsize ) {  echo "!!! Detected calendar change. Sending email..."  $mail = $outlook.CreateItem(0)  #2 = high importance email header  $mail.importance = 2  $mail.subject = $env:computername + “ Outlook Calendar“  $mail.Attachments.Add($newfile)  $mail.Attachments.Add($calfile)  $text = Get-Content $newfile | Out-String  $mail.body = “See attached file...“ + $text  #for multiple email, use semi-colon ; to separate  $mail.To = “your-email@your-mail-domain.com“  $mail.Send() } else {  echo "No changes detected in Calendar!" }} #end function Get-OutlookCalendarFunction Get-OutlookCalendarTest{ echo starting... Add-type -assembly "Microsoft.Office.Interop.Outlook" | out-null $olFolders = "Microsoft.Office.Interop.Outlook.OlDefaultFolders" -as [type] $outlook = new-object -comobject outlook.application $namespace = $outlook.GetNameSpace("MAPI") $folder = $namespace.getDefaultFolder($olFolders::olFolderCalendar) $a = Get-Date -Hour 0 -Minute 00 -Second 00 $b = (Get-Date -Hour 0 -Minute 00 -Second 00).AddDays(7) echo From $a To $b $Appointments = $folder.Items $Appointments.IncludeRecurrences = $true $Appointments.Sort("[Start]") $Appointments | Where-object { $_.start -gt $a -AND $_.start -lt $b } | Select-Object -Property IsRecurring, RecurrenceState, Subject, Start, Location} #end function Get-OutlookCalendarTest

This is the code to invoke the PowerShell function in the module:

Path: Documents\WindowsPowerShell\mono.ps1

Import-Module -Name Outlook\expcal.psm1 -Force$i=0#infinite loop for calling connect function   while(1){   $i = $i +1   Write-Output "Running task Get-OutlookCalendar ($i)"   Get-OutlookCalendar   start-sleep -seconds 300}

To run the PowerShell script, use powershell.exe. To run this on startup, a shortcut on "%APPDATA%\Microsoft\Windows\Start Menu\Programs\Startup\":

C:\Windows\System32\WindowsPowerShell\v1.0\powershell.exe -ExecutionPolicy Bypass "C:\Users\%USERNAME%\Documents\WindowsPowerShell\mono.ps1"