0
votes

I'm trying to load set of extended properties into calendar appointment object in other to report and manipulate them. However, I've been having trouble with this. Whenever it gets to the line where it needs to load the extended properties, I get this error: "Exception calling "Load" with "1" argument(s): "Custom properties cannot be specified using property tags". The GUID and Id/Name combination must be used instead"

The line I'm having problems with is: $apApointment.Load($psPropset);

The whole code is below. Any help is appreciated. By the way, I'm still a beginner with EWS. Thanks

Report = @()
$MailboxList = Read-Host "Enter path to txt file where users are saved."


$StartDate = Get-Date 1/1/2013
$EndDate = Get-Date 4/1/2013

#$StartDate = new-object System.DateTime(2014, 08, 27)
#$EndDate = new-object System.DateTime(2015, 02, 28)
	

#Logon to Exchange Web Service with default credentials	
	Add-Type -Path "C:\Program Files\Microsoft\Exchange\Web Services\2.2\Microsoft.Exchange.WebServices.dll"
    $sid = [System.Security.Principal.WindowsIdentity]::GetCurrent().User.Value
    $user = [ADSI]"LDAP://<SID=$sid>"        
    $service = New-Object Microsoft.Exchange.WebServices.Data.ExchangeService -ArgumentList ([Microsoft.Exchange.WebServices.Data.ExchangeVersion]::Exchange2010_SP2)
    $service.AutodiscoverUrl($user.Properties.mail)
	
Write-Progress -Activity "Preparing" -Status "Retrieving mailbox list" -PercentComplete 0

$Mailboxes = cat $MailboxList | get-mailbox

$Count = $Mailboxes.Count


#Go through each users found
ForEach ($Mailbox in $Mailboxes){
		$DisplayName = $Mailbox.DisplayName
#		$i = $i + 1
#		$pct = $i/$Count * 100
#		Write-Progress -Activity "Collecting mailbox details" -Status "Processing mailbox $i of $Count - $DisplayName" -PercentComplete $pct

		Try {
		$Ok = $true
		$Mailbox = (Get-Mailbox $mailbox.WindowsEmailAddress -ErrorAction Stop ).PrimarySMTPAddress}
		catch [System.Exception]{
		$Ok = $false
		}
		if ($Ok){
		#Set EWS up for impersonation of all users
		$ImpersonatedUserId = New-Object Microsoft.Exchange.WebServices.Data.ImpersonatedUserId -ArgumentList ([Microsoft.Exchange.WebServices.Data.ConnectingIdType]::SmtpAddress),$Mailbox
		$service.ImpersonatedUserId = $ImpersonatedUserId	

		#Open user folder and bind calendar folder to the EWS service. Then, set each calendar default view to 1000
		$folderid = new-object Microsoft.Exchange.WebServices.Data.FolderId([Microsoft.Exchange.WebServices.Data.WellKnownFolderName]::Calendar,$Mailbox)
		$CalendarFolder = [Microsoft.Exchange.WebServices.Data.CalendarFolder]::Bind($service,$folderid)
		$cvCalendarview = new-object Microsoft.Exchange.WebServices.Data.CalendarView($StartDate,$EndDate,1000)


		#Query the calendar and return the appointments
		$cvCalendarview.PropertySet = new-object Microsoft.Exchange.WebServices.Data.PropertySet([Microsoft.Exchange.WebServices.Data.BasePropertySet]::FirstClassProperties)
		$frCalendarResult = $CalendarFolder.FindAppointments($cvCalendarview)

		foreach ($apApointment in $frCalendarResult.Items){

			#Go through each calendar items and collect thier attributes
			
					
			$psPropset = new-object Microsoft.Exchange.WebServices.Data.PropertySet([Microsoft.Exchange.WebServices.Data.BasePropertySet]::FirstClassProperties)
			
			#Create extended properties
			$PR_SENT_REPRESENTING_NAME = new-object Microsoft.Exchange.WebServices.Data.ExtendedPropertyDefinition(0x42,[Microsoft.Exchange.WebServices.Data.MapiPropertyType]::String)
			$PR_SENDER_NAME = new-object Microsoft.Exchange.WebServices.Data.ExtendedPropertyDefinition(0xc1a,[Microsoft.Exchange.WebServices.Data.MapiPropertyType]::String)
			$dispidApptTZDefStartDisplay = new-object Microsoft.Exchange.WebServices.Data.ExtendedPropertyDefinition(0x825E,[Microsoft.Exchange.WebServices.Data.MapiPropertyType]::String)
			$dispidApptTZDefEndDisplay = new-object Microsoft.Exchange.WebServices.Data.ExtendedPropertyDefinition(0x825F,[Microsoft.Exchange.WebServices.Data.MapiPropertyType]::String)
			$ptagSentRepresentingSimpleDispName = new-object Microsoft.Exchange.WebServices.Data.ExtendedPropertyDefinition(0x4031,[Microsoft.Exchange.WebServices.Data.MapiPropertyType]::String)
			
			#Add extended properties to properties set
			$psPropset.Add($PR_SENDER_NAME);
			$psPropset.Add($PR_SENT_REPRESENTING_NAME);
			$psPropset.Add($dispidApptTZDefStartDisplay);
			$psPropset.Add($dispidApptTZDefEndDisplay);
			$psPropset.Add($ptagSentRepresentingSimpleDispName);

			#Add properties to calendar view
			$cvCalendarview.PropertySet = $psPropset;
			
			#Load properties into current appointment
			**$apApointment.Load($psPropset);**
			
			$SENDER_NAME = @()
			$SENT_REPRESENTING_NAME = @()
			$TZDefStartDisplay = @()
			$TZDefEndDisplay = @()
			$ptagSentRepSimpleName = @()
			
			$apApointment.TryGetProperty($PR_SENT_REPRESENTING_NAME, [ref] $SENT_REPRESENTING_NAME)
			$apApointment.TryGetProperty($PR_SENDER_NAME, [ref] $SENDER_NAME)
			$apApointment.TryGetProperty($dispidApptTZDefStartDisplay, [ref] $TZDefStartDisplay)
			$apApointment.TryGetProperty($dispidApptTZDefEndDisplay, [ref] $TZDefEndDisplay)
			$apApointment.TryGetProperty($ptagSentRepresentingSimpleDispName, [ref] $ptagSentRepSimpleName)

			$app = $apApointment.Subject
			$start = $apApointment.Start
			$End = $apApointment.End
			$WhenCreated = $apApointment.DateTimeCreated
			$Organizer = ($apApointment.Organizer).Address
			$Required = $apApointment.RequiredAttendees.Count
			$Recurring = $apApointment.IsRecurring

			#Prepare objects needed for reports
			$Obj = New-Object -TypeName PSObject
			$Obj | Add-Member -MemberType NoteProperty -Name MeetingSubject -Value $app
			$Obj | Add-Member -MemberType NoteProperty -Name MeetingStartTime -Value $start
			$Obj | Add-Member -MemberType NoteProperty -Name MeetingEndTime -Value $End
			$Obj | Add-Member -MemberType NoteProperty -Name WhenCreated -Value $WhenCreated
			$Obj | Add-Member -MemberType NoteProperty -Name ReoccuringMeeting -Value $Recurring
			$Obj | Add-Member -MemberType NoteProperty -Name MeetingOrganizer -Value $Organizer
			$Obj | Add-Member -MemberType NoteProperty -Name SentRepresentingName -Value $SENT_REPRESENTING_NAME
			$Obj | Add-Member -MemberType NoteProperty -Name SenderName -Value $SENDER_NAME
			$Obj | Add-Member -MemberType NoteProperty -Name RequiredAttendeeCount -Value $Required
			$Obj | Add-Member -MemberType NoteProperty -Name MailboxOwner -Value $Mailbox
			$Obj | Add-Member -MemberType NoteProperty -Name MailboxOwnerDisplay -Value $DisplayName
			$Report += $Obj
			
			Write-Host "$Mailbox Calendar is being processed"
			
			} 
		}
}

#Get all reports and save them into respective paths
$Report | Export-Csv c:\CorruptCalender.csv -NoTypeInformation
1

1 Answers

0
votes

The two properties you define $dispidApptTZDefStartDisplay and $dispidApptTZDefEndDisplay are the problem. You've defined them using a constant property tag value that is in the 0x8000 range. MAPI tags in that range are named properties, and their actual tag values aren't set (they change from mailbox to mailbox). You need to define them in terms of a property set GUID and a property ID.

The values you have are actually property ID values, not tag values. So you need to combine them with a property set GUID to have them work. The managed API actually has a constant defined for the Appointment property set, which these properties belong to, so you can change those lines to:

$dispidApptTZDefStartDisplay = new-object Microsoft.Exchange.WebServices.Data.ExtendedPropertyDefinition([Microsoft.Exchange.WebServices.Data.DefaultExtendedPropertySet]::Appointment, 0x825E,[Microsoft.Exchange.WebServices.Data.MapiPropertyType]::Binary)
$dispidApptTZDefEndDisplay = new-object Microsoft.Exchange.WebServices.Data.ExtendedPropertyDefinition([Microsoft.Exchange.WebServices.Data.DefaultExtendedPropertySet]::Appointment, 0x825F,[Microsoft.Exchange.WebServices.Data.MapiPropertyType]::Binary)

And it should clear up that error (unless I borked my Powershell syntax :))