I am trying to create an appointment in a resource mailbox in Exchange Online using the EWS (Exchange Web Services) API.
I am authenticating with EWS using a O365 global admin account.
I am then impersonating the organiser, and then binding to the mailbox calendar folder. I have setup the appropriate management roles/scopes for this.
When I create the appointment the organiser appears as the room mailbox account, not the impersonated account. I cannot see what I am doing wrong...
I have used a variety of sources to get me as far as I have:
The code below successfully creates an appointment in the $roomMailbox calendar, although the organiser is set as room mailbox, not the organiser I am trying to impersonate...
Any guidance much appreciated.
using namespace Microsoft.Exchange.WebServices.Data
Set-StrictMode -Version 5.1
$ErrorActionPreference = 'Stop'
function Connect-EWS
{
[CmdletBinding()]
Param
(
[Parameter(Mandatory=$false)]
[System.Management.Automation.PSCredential]$Credential
)
try
{
[void][Reflection.Assembly]::LoadFile("C:\Program Files\Microsoft\Exchange\Web Services\2.0\Microsoft.Exchange.WebServices.dll")
}
catch
{
throw "Could not import Microsoft Exchange web services library: $($_.Exception.Message)"
}
try
{
$ews = [ExchangeService]::New()
}
catch
{
throw "Could not create Microsoft.Exchange.WebServices.Data.ExchangeService object: $($_.Exception.Message)"
}
if($credential)
{
$ews.Credentials = $Credential.GetNetworkCredential()
}
else
{
$ews.UseDefaultCredentials = $true
}
$validateRedirectionUrlCallback = {
Param([String]$Url)
if($Url -eq "https://autodiscover-s.outlook.com/autodiscover/autodiscover.xml")
{
return $true
}
else
{
return $false
}
}
try
{
$ews.AutodiscoverUrl($Credential.UserName,$validateRedirectionUrlCallback)
}
catch
{
throw "Autodiscover failed: $($_.Exception.Message)"
}
return $ews
}
function New-Appointment
{
Param
(
[Parameter(Mandatory = $true)]
[String]$Organiser
,
[Parameter(Mandatory = $true)]
[String]$RoomMailbox
,
[Parameter(Mandatory = $true)]
[DateTime]$Start
,
[Parameter(Mandatory = $true)]
[DateTime]$End
,
[Parameter(Mandatory = $true)]
[String]$Subject
,
[Parameter(Mandatory = $true)]
[String]$Location
)
try # Resolve the organiser ID
{
[Void]$ews.ResolveName($Organiser,[ResolveNameSearchLocation]::DirectoryOnly, $false)
}
catch
{
throw "Could not resolve Organiser identity: $Organiser : $($_.Exception.Message)"
}
try # Attempt to enable impersonation as the organiser
{
$ews.ImpersonatedUserId = [ImpersonatedUserId]::New([ConnectingIdType]::SmtpAddress, $Organiser)
}
catch
{
throw "Could not impersonate user $Organiser : $($_.Exception.Message)"
}
try # Create a new appointment object
{
$appointment = [Appointment]::New($ews)
}
catch
{
throw "Could not create appointment object: $($_.Exception.MEssage)"
}
# Add each of the properties below associated values into the appointment object
$setProperties = 'Start','End','Subject','Location'
foreach($p in $setProperties)
{
$appointment.$p = Get-Variable $p -ValueOnly
}
try # Set the folder ID as the calendar of the room mailbox
{
$folderId = [FolderId]::New([WellKnownFolderName]::Calendar, $RoomMailbox)
}
catch
{
throw "Could not generate target calendar folder id: $($_.Exception.Message)"
}
try # Try and bind the EWS connection to the folder
{
$folder = [Folder]::Bind($ews, $folderId)
}
catch
{
throw "Could not bind to user $($folderId.FolderName) $($_.Exception.Message)"
}
try # Save the appointment
{
$appointment.Save($folderId, [SendInvitationsMode]::SendToAllAndSaveCopy)
}
catch
{
throw "Could not save appointment as organiser: $Organiser : $($_.Exception.Message)"
}
}
if(!$credential)
{
$credential = Get-Credential -UserName $globalAdminUPN -Message "Please enter O365 credentials for user $globalAdminUPN"
}
$Organiser = '[email protected]'
$RoomMailbox = '[email protected]'
$Start = '01/02/2019 22:00'
$End = '01/02/2019 23:00'
$Subject = 'Test Appointment'
$Location = 'Test Location'
$ews = Connect-EWS -Credential $credential
try
{
New-Appointment -Organiser $Organiser `
-RoomMailbox $RoomMailbox `
-Start $Start `
-End $End `
-Subject $Subject `
-Location $Location
}
catch
{
Write-Host "ERROR: $($_.Exception.Message)" -ForegroundColor Red
}