{"id":3327,"date":"2019-10-31T17:20:51","date_gmt":"2019-10-31T16:20:51","guid":{"rendered":"https:\/\/www.lieben.nu\/liebensraum\/?p=3327"},"modified":"2019-10-31T17:20:51","modified_gmt":"2019-10-31T16:20:51","slug":"using-exchange-web-service-with-powershell-to-remove-calendar-appointments-without-notification","status":"publish","type":"post","link":"https:\/\/lieben.nu\/liebensraum\/2019\/10\/using-exchange-web-service-with-powershell-to-remove-calendar-appointments-without-notification\/","title":{"rendered":"Using Exchange Web Service with Powershell to remove calendar appointments without notification"},"content":{"rendered":"\n<figure class=\"wp-block-image size-large\"><img loading=\"lazy\" decoding=\"async\" width=\"1678\" height=\"292\" src=\"https:\/\/www.lieben.nu\/liebensraum\/wp-content\/uploads\/2019\/10\/2019-10-31-17_24_23-Remove-ObsoleteCalendarItems.ps1-Git-Visual-Studio-Code.png\" alt=\"\" class=\"wp-image-3332\" srcset=\"https:\/\/lieben.nu\/liebensraum\/wp-content\/uploads\/2019\/10\/2019-10-31-17_24_23-Remove-ObsoleteCalendarItems.ps1-Git-Visual-Studio-Code.png 1678w, https:\/\/lieben.nu\/liebensraum\/wp-content\/uploads\/2019\/10\/2019-10-31-17_24_23-Remove-ObsoleteCalendarItems.ps1-Git-Visual-Studio-Code-300x52.png 300w, https:\/\/lieben.nu\/liebensraum\/wp-content\/uploads\/2019\/10\/2019-10-31-17_24_23-Remove-ObsoleteCalendarItems.ps1-Git-Visual-Studio-Code-1024x178.png 1024w, https:\/\/lieben.nu\/liebensraum\/wp-content\/uploads\/2019\/10\/2019-10-31-17_24_23-Remove-ObsoleteCalendarItems.ps1-Git-Visual-Studio-Code-768x134.png 768w, https:\/\/lieben.nu\/liebensraum\/wp-content\/uploads\/2019\/10\/2019-10-31-17_24_23-Remove-ObsoleteCalendarItems.ps1-Git-Visual-Studio-Code-1536x267.png 1536w\" sizes=\"auto, (max-width: 1678px) 100vw, 1678px\" \/><\/figure>\n\n\n\n<p class=\"wp-block-paragraph\">While helping out a client recently something in their migration went wrong, I ran into an interesting challenge. Calendars of users were merged, many many times. The resulting duplicates that shouldn&#8217;t be in user&#8217;s calendars could be identified easily: the mailbox was neither the organiser nor invited to these calendar events.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">But how to remove them? Graph won&#8217;t allow you to do so without notifying the recipients (leading, potentially, to thousands of confused users). <\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Luckily, EWS DOES allow us to do so, and if you ever need to work with EWS (Office 365 Exchange Online) using Powershell, this code sample could come in handy \ud83d\ude42<\/p>\n\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: powershell; title: ; notranslate\" title=\"\">\nAdd-Type -Path \"C:\\Users\\jos\\Desktop\\net35\\Microsoft.Exchange.WebServices.dll\"\n\n$Service = &#x5B;Microsoft.Exchange.WebServices.Data.ExchangeService]::new()\n$Service.Credentials = &#x5B;System.Net.NetworkCredential]::new(\"admin@onedrivemapper.onmicrosoft.com\" , \"yourpassword\")\n$Service.Url = \"https:\/\/outlook.office365.com\/EWS\/Exchange.asmx\"\n\n$maxDaysIntoTheFuture = 365\n\nfunction Remove-ObsoleteCalendarItems{\n    Param(\n        $primaryEmailAddress #eg: admin@onedrivemapper.onmicrosoft.com\n    )\n\n    $folderid= new-object Microsoft.Exchange.WebServices.Data.FolderId(&#x5B;Microsoft.Exchange.WebServices.Data.WellKnownFolderName]::Calendar,$primaryEmailAddress)   \n    $Calendar = &#x5B;Microsoft.Exchange.WebServices.Data.Folder]::Bind($Service,$folderid)\n    $Recurring = new-object Microsoft.Exchange.WebServices.Data.ExtendedPropertyDefinition(&#x5B;Microsoft.Exchange.WebServices.Data.DefaultExtendedPropertySet]::Appointment, 0x8223,&#x5B;Microsoft.Exchange.WebServices.Data.MapiPropertyType]::Boolean); \n    $psPropset= new-object Microsoft.Exchange.WebServices.Data.PropertySet(&#x5B;Microsoft.Exchange.WebServices.Data.BasePropertySet]::FirstClassProperties)  \n    $psPropset.Add($Recurring)\n    $psPropset.RequestedBodyType = &#x5B;Microsoft.Exchange.WebServices.Data.BodyType]::Text;\n\n    #Define Date to Query \n    $currentDay = 0\n    while($True){\n        $StartDate = (Get-Date).AddDays($currentDay)\n        $EndDate = $StartDate.AddDays(14)  \n        $currentDay += 14\n\n        if($currentDay -gt $maxDaysIntoTheFuture){\n            break\n        }\n\n        $CalendarView = New-Object Microsoft.Exchange.WebServices.Data.CalendarView($StartDate,$EndDate,1000)    \n        $fiItems = $service.FindAppointments($Calendar.Id,$CalendarView)\n        if($fiItems.Items.Count -gt 0){\n            $type = (\"System.Collections.Generic.List\"+'`'+\"1\") -as \"Type\"\n            $type = $type.MakeGenericType(\"Microsoft.Exchange.WebServices.Data.Item\" -as \"Type\")\n            $ItemColl = &#x5B;Activator]::CreateInstance($type)\n            foreach($Item in $fiItems.Items){\n                $ItemColl.Add($Item)\n            } \n            &#x5B;Void]$service.LoadPropertiesForItems($ItemColl,$psPropset)  \n        }\n\n        foreach($Item in $fiItems.Items){  \n            if($Item.Organizer.Address -ne $primaryEmailAddress -and $Item.RequiredAttendees.Address -notcontains $primaryEmailAddress -and $Item.OptionalAttendees.Address -notcontains $primaryEmailAddress){\n                $Item.RequiredAttendees.Clear() #this also works if no one is invited\n                $Item.OptionalAttendees.Clear() #this also works if no one is invited\n                $Item.Update(&#x5B;Microsoft.Exchange.WebServices.Data.ConflictResolutionMode]::AlwaysOverwrite,&#x5B;Microsoft.Exchange.WebServices.Data.SendInvitationsOrCancellationsMode]::SendToNone)\n                $Item.Delete(&#x5B;Microsoft.Exchange.WebServices.Data.DeleteMode]::MoveToDeletedItems)\n                write-host \"deleted item $($Item.Subject) without notifying recipients\"\n            }\n        }\n    }\n}\n<\/pre><\/div>\n\n\n<p class=\"wp-block-paragraph\">The required EWS DLL&#8217;s can also be found in my git repository:<\/p>\n\n\n\n<ul class=\"wp-block-list\"><li><a href=\"https:\/\/gitlab.com\/Lieben\/assortedFunctions\/blob\/master\/Remove-ObsoleteCalendarItems.ps1\">Script code<\/a><\/li><li><a href=\"https:\/\/gitlab.com\/Lieben\/assortedFunctions\/blob\/master\/Microsoft.Exchange.WebServices.dll\">EWS DLL<\/a><\/li><li><a href=\"https:\/\/gitlab.com\/Lieben\/assortedFunctions\/blob\/master\/Microsoft.Exchange.WebServices.xml\">EWS XML<\/a><\/li><\/ul>\n\n\n\n<p class=\"wp-block-paragraph\"><\/p>\n\n\n\n<p class=\"wp-block-paragraph\"><\/p>\n","protected":false},"excerpt":{"rendered":"<p>While helping out a client recently something in their migration went wrong, I ran into an interesting challenge. Calendars of users were merged, many many times. The resulting duplicates that shouldn&#8217;t be in user&#8217;s calendars could be identified easily: the mailbox was neither the organiser nor invited to these calendar events. But how to remove &hellip; <a href=\"https:\/\/lieben.nu\/liebensraum\/2019\/10\/using-exchange-web-service-with-powershell-to-remove-calendar-appointments-without-notification\/\" class=\"more-link\">Continue reading <span class=\"screen-reader-text\">Using Exchange Web Service with Powershell to remove calendar appointments without notification<\/span> <span class=\"meta-nav\">&rarr;<\/span><\/a><\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"_crdt_document":"","footnotes":""},"categories":[18,39],"tags":[],"class_list":["post-3327","post","type-post","status-publish","format-standard","hentry","category-exchange-online","category-powershell"],"_links":{"self":[{"href":"https:\/\/lieben.nu\/liebensraum\/wp-json\/wp\/v2\/posts\/3327","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/lieben.nu\/liebensraum\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/lieben.nu\/liebensraum\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/lieben.nu\/liebensraum\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/lieben.nu\/liebensraum\/wp-json\/wp\/v2\/comments?post=3327"}],"version-history":[{"count":0,"href":"https:\/\/lieben.nu\/liebensraum\/wp-json\/wp\/v2\/posts\/3327\/revisions"}],"wp:attachment":[{"href":"https:\/\/lieben.nu\/liebensraum\/wp-json\/wp\/v2\/media?parent=3327"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/lieben.nu\/liebensraum\/wp-json\/wp\/v2\/categories?post=3327"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/lieben.nu\/liebensraum\/wp-json\/wp\/v2\/tags?post=3327"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}