EWS Script to Export Calendar Items to a CSV file via PowerShell

Scenario:  You need a script to export the calendar items of a mailbox into a CSV file.

Solution: Use the script below to export the calendar items of a mailbox into a CSV file.  Please note that the date range has a 2 year/1000 appointment max.  Depending on the number of items in the calendar between your date range, you may have to adjust the date range to accommodate the 1000 item limit. Also, give yourself full access to the mailbox you are querying. I used a section of Glen’s script because he nailed the attendee’s query. Props to Glen!

#Declare Variables
$EWSDLL = "C:Program FilesMicrosoftExchange ServerV15BinMicrosoft.Exchange.WebServices.dll"
$MBX = "teststeve@domain.com"
$EWSURL = "https://Ex2013Svr1.domain.com/EWS/Exchange.asmx"
$StartDate = (Get-Date).AddDays(-60)
$EndDate = (Get-Date)  

#Binding of the calendar of the Mailbox and EWS
Import-Module -Name $EWSDLL
$mailboxname = $MBX
$service = new-object Microsoft.Exchange.WebServices.Data.ExchangeService([Microsoft.Exchange.WebServices.Data.Exchangeversion]::exchange2013)
$service.Url = new-object System.Uri($EWSURL)
$folderid= new-object Microsoft.Exchange.WebServices.Data.FolderId([Microsoft.Exchange.WebServices.Data.WellKnownFolderName]::Calendar,$MailboxName) 
$Calendar = [Microsoft.Exchange.WebServices.Data.Folder]::Bind($service,$folderid)  
$Recurring = new-object Microsoft.Exchange.WebServices.Data.ExtendedPropertyDefinition([Microsoft.Exchange.WebServices.Data.DefaultExtendedPropertySet]::Appointment, 0x8223,[Microsoft.Exchange.WebServices.Data.MapiPropertyType]::Boolean); 
$psPropset= new-object Microsoft.Exchange.WebServices.Data.PropertySet([Microsoft.Exchange.WebServices.Data.BasePropertySet]::FirstClassProperties)  
$psPropset.RequestedBodyType = [Microsoft.Exchange.WebServices.Data.BodyType]::Text;

$RptCollection = @()

$AppointmentState = @{0 = "None" ; 1 = "Meeting" ; 2 = "Received" ;4 = "Canceled" ; }

#Define the calendar view  
$CalendarView = New-Object Microsoft.Exchange.WebServices.Data.CalendarView($StartDate,$EndDate,1000)    
$fiItems = $service.FindAppointments($Calendar.Id,$CalendarView)
if($fiItems.Items.Count -gt 0){
 $type = ("System.Collections.Generic.List"+'`'+"1") -as "Type"
 $type = $type.MakeGenericType("Microsoft.Exchange.WebServices.Data.Item" -as "Type")
 $ItemColl = [Activator]::CreateInstance($type)
 foreach($Item in $fiItems.Items){
foreach($Item in $fiItems.Items){      
 $rptObj = "" | Select StartTime,EndTime,Duration,Type,Subject,Location,Organizer,Attendees,AppointmentState,Notes,HasAttachments,IsReminderSet
 $rptObj.StartTime = $Item.Start  
 $rptObj.EndTime = $Item.End  
 $rptObj.Duration = $Item.Duration
 $rptObj.Subject  = $Item.Subject   
 $rptObj.Type = $Item.AppointmentType
 $rptObj.Location = $Item.Location
 $rptObj.Organizer = $Item.Organizer.Address
 $rptObj.HasAttachments = $Item.HasAttachments
 $rptObj.IsReminderSet = $Item.IsReminderSet
 $aptStat = "";
 $AppointmentState.Keys | where { $_ -band $Item.AppointmentState } | foreach { $aptStat += $AppointmentState.Get_Item($_) + " "}
 $rptObj.AppointmentState = $aptStat 
 $RptCollection += $rptObj
 foreach($attendee in $Item.RequiredAttendees){
  $atn = $attendee.Address + "; "  
  $rptObj.Attendees += $atn
 foreach($attendee in $Item.OptionalAttendees){
  $atn = $attendee.Address + "; "  
  $rptObj.Attendees += $atn
 foreach($attendee in $Item.Resources){
  $atn = $attendee.Address + "; "  
  $rptObj.Resources += $atn
 $rptObj.Notes = $Item.Body.Text
#Display on the screen
 "Start:   " + $Item.Start  
 "Subject: " + $Item.Subject 
#Export to a CSVFile
$RptCollection |  Export-Csv -NoTypeInformation -Path "c:temp$MailboxName-CalendarCSV.csv"


3 thoughts on “EWS Script to Export Calendar Items to a CSV file via PowerShell”

  1. Hi,

    I am getting the below error when i run this script to export calendar of my own mailbox. What mistake i am doing?

    PS C:\O365> .\Caldata.ps1
    Exception calling “Bind” with “2” argument(s): “The request failed. The remote server returned an error: (401) Unauthorized.”
    At C:\O365\Caldata.ps1:14 char:1
    + $Calendar = [Microsoft.Exchange.WebServices.Data.Folder]::Bind($servi …
    + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    + CategoryInfo : NotSpecified: (:) [], MethodInvocationException
    + FullyQualifiedErrorId : ServiceRequestException

    Exception calling “FindAppointments” with “2” argument(s): “The element at position 0 is invalid
    Parameter name: parentFolderIds”
    At C:\O365\Caldata.ps1:26 char:1
    + $findItems = $service.FindAppointments($Calendar.Id,$CalendarView)
    + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    + CategoryInfo : NotSpecified: (:) [], MethodInvocationException
    + FullyQualifiedErrorId : ArgumentException



    1. It looks like you may be having permission issues when trying to run: $Calendar = [Microsoft.Exchange.WebServices.Data.Folder]::Bind($service,$folderid). Try giving the account you are using to run the script Full Mailbox Permissions to the mailbox you are trying to attach to: add-mailboxpermission -user -accessrights fullaccess -automapping $false


      1. Hi,

        Yes i do have full access permission and as well as impersonation permission. But still getting the same error message.

        Is there something to do with the certificate services while connecting to EWS?

        Also is it possible to integrate the number of attendees count in the script?


Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s

%d bloggers like this: