functions/Export-GCECalendarToCSV.ps1
function Export-GCECalendarToCSV { [CmdletBinding()] <# .SYNOPSIS Exports Calendar events from an Microsoft365 Mailbox Calendar to a CSV file using the Microsoft Graph API and the Microsoft Graph Powershell SDK .DESCRIPTION Exports Calendar events from an Microsoft365 Mailbox Calendar to a CSV file using the Microsoft Graph API Microsoft Graph Powershell SDK. This script requires you make a connection to the Microsoft Graph first using any of the methods outlined in https://learn.microsoft.com/en-us/powershell/microsoftgraph/get-started?view=graph-powershell-1.0 .PARAMETER MailboxName A description of the MailboxName parameter. .PARAMETER StartTime Start Time to Start searching for Appointments to Export .PARAMETER EndTime End Time to End searching for Appointments to Export .PARAMETER TimeZone Used to Outlook Prefer header (uses local by default) .PARAMETER FileName File to Export the Calendar Appointments to .EXAMPLE Export the last years Calendar appointments to a CSV Export-GCECalendarToCSV -MailboxName gscales@datarumble.com -StartTime (Get-Date).AddYears(-1) -EndTime (Get-Date) -FileName c:\export\lastyear.csv #> param ( [Parameter(Position = 1, Mandatory = $true)] [String] $MailboxName, [Parameter(Position = 2, Mandatory = $true)] [datetime] $StartTime, [Parameter(Position = 3, Mandatory = $true)] [datetime] $EndTime, [Parameter(Position = 4, Mandatory = $false)] [String] $TimeZone, [Parameter(Position = 5, Mandatory = $true)] [String] $FileName ) Process { $Events = Export-GCECalendar -MailboxName $MailboxName -StartTime $StartTime -EndTime $EndTime -TimeZone $TimeZone $Events | Export-Csv -NoTypeInformation -Path $FileName Write-Verbose("Exported to " + $FileName) } } function Export-GCECalendar { [CmdletBinding()] param ( [Parameter(Position = 1, Mandatory = $true)] [String] $MailboxName, [Parameter(Position = 2, Mandatory = $true)] [datetime] $StartTime, [Parameter(Position = 3, Mandatory = $true)] [datetime] $EndTime, [Parameter(Position = 4, Mandatory = $false)] [String] $TimeZone ) Process { $rptCollection = @() if ([String]::IsNullOrEmpty($TimeZone)) { $TimeZone = [TimeZoneInfo]::Local.Id; } $AppointmentState = @{0 = "None" ; 1 = "Meeting" ; 2 = "Received" ; 4 = "Canceled" ; } $headers = @{ "Prefer" = "outlook.timezone=`"" + $TimeZone + "`", outlook.body-content-type='text'" } $queryStartTime = $StartTime.ToUniversalTime().ToString("yyyy-MM-ddTHH:mm:ssZ") $queryEndTime = $EndTime.ToUniversalTime().ToString("yyyy-MM-ddTHH:mm:ssZ") $events = Get-MgUserCalendarView -UserId $MailboxName -Headers $headers -StartDateTime $queryStartTime -EndDateTime $queryEndTime -PageSize 500 -All -ExpandProperty "SingleValueExtendedProperties(`$filter=(Id eq 'Integer {00062002-0000-0000-C000-000000000046} Id 0x8213') or (Id eq 'Integer {00062002-0000-0000-C000-000000000046} Id 0x8217'))" foreach ($CalendarEvent in $events) { Expand-ExtendedProperties -Item $CalendarEvent $rptObj = "" | Select StartTime, EndTime, Duration, Type, Subject, Location, Organizer, Attendees, Resources, AppointmentState, Notes, HasAttachments, IsReminderSet $rptObj.HasAttachments = $false; $rptObj.IsReminderSet = $false $rptObj.StartTime = ([DateTime]$CalendarEvent.Start.dateTime).ToString("yyyy-MM-dd HH:mm") $rptObj.EndTime = ([DateTime]$CalendarEvent.End.dateTime).ToString("yyyy-MM-dd HH:mm") $rptObj.Duration = $CalendarEvent.AppointmentDuration $rptObj.Subject = $CalendarEvent.Subject $rptObj.Type = $CalendarEvent.type $rptObj.Location = $CalendarEvent.Location.displayName $rptObj.Organizer = $CalendarEvent.organizer.emailAddress.address $aptStat = ""; $AppointmentState.Keys | where { $_ -band $CalendarEvent.AppointmentState } | foreach { $aptStat += $AppointmentState.Get_Item($_) + " " } $rptObj.AppointmentState = $aptStat if ($CalendarEvent.hasAttachments) { $rptObj.HasAttachments = $CalendarEvent.hasAttachments } if ($CalendarEvent.IsReminderSet) { $rptObj.IsReminderSet = $CalendarEvent.IsReminderSet } foreach ($attendee in $CalendarEvent.attendees) { if ($attendee.type -eq "resource") { $rptObj.Resources += $attendee.emailaddress.address + " " + $attendee.type + " " + $attendee.status.response + ";" } else { $atn = $attendee.emailaddress.address + " " + $attendee.type + " " + $attendee.status.response + ";" $rptObj.Attendees += $atn } } $rptObj.Notes = $CalendarEvent.Body.content $rptCollection += $rptObj } return $rptCollection } } function Expand-ExtendedProperties { [CmdletBinding()] param ( [Parameter(Position = 1, Mandatory = $false)] [psobject] $Item ) process { if ($Item.singleValueExtendedProperties -ne $null) { foreach ($Prop in $Item.singleValueExtendedProperties) { Switch ($Prop.Id) { "Integer {00062002-0000-0000-c000-000000000046} Id 0x8213" { Add-Member -InputObject $Item -NotePropertyName "AppointmentDuration" -NotePropertyValue $Prop.Value -Force } "Integer {00062002-0000-0000-c000-000000000046} Id 0x8217" { Add-Member -InputObject $Item -NotePropertyName "AppointmentState" -NotePropertyValue $Prop.Value -Force } } } } } } |