none
exchange 2010 EWS - retrieving the body text of an appouintment RRS feed

  • Question

  • Hi All,

    I hope someone out there can help me with this one... OK... first a little background as to what I am attempting

    I have  written an app in PowerShell to work with System Centre Service Manager (2010) which looks at scheduled tasks for engineers and adds them into their outlook calendar, so they have all the call details on their phones - will also allow managewrs to send updates and new work to them easily.  I have used EWS to create these entries like this...

    $Appointment = New-Object Microsoft.Exchange.WebServices.Data.Appointment -ArgumentList $service  
    #Set Start Time  
    $Appointment.Start = $incident.Scheduled
    #Set End Time  
    $Appointment.End = ($Appointment.Start).AddMinutes(30)
    #Set Subject  
    $Appointment.Subject = $incident.SourceObject.DisplayName 
    #Set the Location  
    $Appointment.Location = $incident.sitename   
    #Set Reminder
    $Appointment.ReminderMinutesBeforeStart = 30
    #Set any Notes  
    $Appointment.Body = $incident.firstline+"<br>"+$incident.postcode+"<br>
    <b>Affected User:   </b>"+$incident.affecteduser +"<br>
    <b>About Config Item:  </b>"+$incident.RelatedItems+"<br><br>
    <b><u>Description:</u></b><br>
    "+     $incident.SourceObject.Values.Item(25).value+"<br><br>
    <b><u>Call Logs:</u></b><br>
    "+     $incident.logs
    #Create Appointment will save to the default Calendar  
    $Appointment.Save($folderid)

    What I wanted to do was allow the engineers to update this calendar appointment on the go and for this to and for this to feed back into service manager.  I can retrieve the calendar appointment - again using EWS - but the "body" field is always blank.

    So the question...

    if the body of the appointment is not in the Body field, where is and how do I get to it? 

    below is how I retrieve the appointment

    thanks in advance...

    Ed

    $global:CalendarFolder = [Microsoft.Exchange.WebServices.Data.CalendarFolder]::Bind($service,$folderid)
                
                $cvCalendarview = new-object Microsoft.Exchange.WebServices.Data.CalendarView($today,$1week,2000)
                $cvCalendarview.PropertySet = new-object Microsoft.Exchange.WebServices.Data.PropertySet([Microsoft.Exchange.WebServices.Data.BasePropertySet]::FirstClassProperties)
                $global:CalendarResult = $CalendarFolder.FindAppointments($cvCalendarview) <# |select Start, subject, End, Location, body, LastModifiedTime #> |?{$_.subject -like 'IR*'}
    ### filter to a single appointment
    $CalApp =   $CalendarResult |?{$_.subject -like $incident.SourceObject.DisplayName }
    ###
    #
    #   $CalApp.body is blank  


    Ed

    Tuesday, August 20, 2013 10:03 AM

Answers

  • For anyone looking to do this and stumbling on this thread... I finally had a little moment to have another look at this, and here is the answer...  there is a fair bit of other info in there too, which may help out if you are struggling.

    $today = get-date -Hour 1
    $1week = (get-date -Hour 23).AddDays(9)
    ### gets the Mailbox
    $global:service = New-Object Microsoft.Exchange.WebServices.Data.ExchangeService([Microsoft.Exchange.WebServices.Data.ExchangeVersion]::Exchange2010_SP2)
    $global:windowsIdentity = [System.Security.Principal.WindowsIdentity]::GetCurrent()
    $global:sidbind = "LDAP://<SID=" + $windowsIdentity.user.Value.ToString() + ">"
    $global:aceuser = [ADSI]$sidbind
    $global:service.AutodiscoverUrl($aceuser.mail.ToString())
    ### gets the calendar
    $global:folderid = new-object Microsoft.Exchange.WebServices.Data.FolderId([Microsoft.Exchange.WebServices.Data.WellKnownFolderName]::Calendar,$MailboxName)
    $global:CalendarFolder = [Microsoft.Exchange.WebServices.Data.CalendarFolder]::Bind($service,$folderid)
    $cvCalendarview = new-object Microsoft.Exchange.WebServices.Data.CalendarView($today,$1week,2000)
    ### fetches the standard calendar appointment info back - which you can filter and select the bits you need if you like
    $cvCalendarview.PropertySet = new-object Microsoft.Exchange.WebServices.Data.PropertySet([Microsoft.Exchange.WebServices.Data.BasePropertySet]::FirstClassProperties)
    $global:CalendarResult = $CalendarFolder.FindAppointments($cvCalendarview) <# |select Start, subject, End, Location, body, LastModifiedTime  |?{$_.subject -like 'IR*'}#>
             
    ## find folder and items for update and delete
    $fvFolderView =  New-Object Microsoft.Exchange.WebServices.Data.FolderView(1000)  
    $fvFolderView.Traversal = [Microsoft.Exchange.WebServices.Data.FolderTraversal]::Shallow;  
    $SfSearchFilter = new-object Microsoft.Exchange.WebServices.Data.SearchFilter+IsEqualTo([Microsoft.Exchange.WebServices.Data.FolderSchema]::DisplayName,"MoveDestination")  
    $findFolderResults = $CalendarFolder.FindFolders($SfSearchFilter,$fvFolderView)  
            
    ### gets calendar items       
    $global:ivItemView =  New-Object Microsoft.Exchange.WebServices.Data.ItemView(1000) 
    $Global:fiItems = $service.FindItems($CalendarFolder.Id,$ivItemView) 
            
    ## create new appointment
    $Appointment = New-Object Microsoft.Exchange.WebServices.Data.Appointment -ArgumentList $service  
    #Set Start Time  
    $Appointment.Start = $xxx
    #Set End Time  
    $Appointment.End = $xxx
    #Set Subject  
    $Appointment.Subject =  $xxx
    #Set the Location  
    $Appointment.Location =  $xxx
    #Set Reminder
    $Appointment.ReminderMinutesBeforeStart = $xxx
    #Set any Notes  
    $Appointment.Body = $xxx
    $Appointment.Save($folderid)
    ### delete an item
    ## Item Deleted -= $itemDel is an item where the displayname of that item matches the subject of an appointment
    $DelItem = $fiItems |? {$_.subject -eq $itemdel.SourceObject.DisplayName}
    $DelItem.Delete([Microsoft.Exchange.WebServices.Data.DeleteMode]::SoftDelete)
    ### retrieve the body of the appointment
    ### At this point I have filtered out a single appointment from the results of above
    $CalApp =   $CalendarResult |?{$_.subject -like $incident.SourceObject.DisplayName }
    ### get tehj body for that one appointment
        # create a new property set
        $PropertySet = New-Object Microsoft.Exchange.WebServices.Data.PropertySet([Microsoft.Exchange.WebServices.Data.BasePropertySet]::FirstClassProperties)
        # tell it you want teh body as text
        $PropertySet.RequestedBodyType = [Microsoft.Exchange.WebServices.Data.BodyType]::Text
        #load that info into the appointment
        $CalApp.Load($PropertySet)
        #return the body to another variable
         $bodyText= $CalApp.Body.toString()


    Ed


    • Marked as answer by EdShep Thursday, December 19, 2013 12:10 PM
    • Edited by EdShep Thursday, December 19, 2013 12:11 PM code block not formated correctly
    Thursday, December 19, 2013 12:10 PM

All replies

  • I found this, but its all in C# and I cant work out how to translate this into powershell....

    If I cant get this working purely with powershell, I suppose I could just launch the C# from my powershell script... just I have no idea about C#... probably about time I started to learn!!!!  :)


    Ed

    Tuesday, August 20, 2013 2:19 PM
  • I haven't done much of this sort of stuff in PS, but I think the problem is that your $CalApp is still a collection. If you are sure that only one item will be present, you can probably just get the body of the first (and only) item.

    There's also the probability that FindAppointments doesn't return bodies, so you'll need to get the Id of the item, and use GetItem to bind to it.


    blog.leederbyshire.com


    Wednesday, August 21, 2013 9:40 AM
  • For anyone looking to do this and stumbling on this thread... I finally had a little moment to have another look at this, and here is the answer...  there is a fair bit of other info in there too, which may help out if you are struggling.

    $today = get-date -Hour 1
    $1week = (get-date -Hour 23).AddDays(9)
    ### gets the Mailbox
    $global:service = New-Object Microsoft.Exchange.WebServices.Data.ExchangeService([Microsoft.Exchange.WebServices.Data.ExchangeVersion]::Exchange2010_SP2)
    $global:windowsIdentity = [System.Security.Principal.WindowsIdentity]::GetCurrent()
    $global:sidbind = "LDAP://<SID=" + $windowsIdentity.user.Value.ToString() + ">"
    $global:aceuser = [ADSI]$sidbind
    $global:service.AutodiscoverUrl($aceuser.mail.ToString())
    ### gets the calendar
    $global:folderid = new-object Microsoft.Exchange.WebServices.Data.FolderId([Microsoft.Exchange.WebServices.Data.WellKnownFolderName]::Calendar,$MailboxName)
    $global:CalendarFolder = [Microsoft.Exchange.WebServices.Data.CalendarFolder]::Bind($service,$folderid)
    $cvCalendarview = new-object Microsoft.Exchange.WebServices.Data.CalendarView($today,$1week,2000)
    ### fetches the standard calendar appointment info back - which you can filter and select the bits you need if you like
    $cvCalendarview.PropertySet = new-object Microsoft.Exchange.WebServices.Data.PropertySet([Microsoft.Exchange.WebServices.Data.BasePropertySet]::FirstClassProperties)
    $global:CalendarResult = $CalendarFolder.FindAppointments($cvCalendarview) <# |select Start, subject, End, Location, body, LastModifiedTime  |?{$_.subject -like 'IR*'}#>
             
    ## find folder and items for update and delete
    $fvFolderView =  New-Object Microsoft.Exchange.WebServices.Data.FolderView(1000)  
    $fvFolderView.Traversal = [Microsoft.Exchange.WebServices.Data.FolderTraversal]::Shallow;  
    $SfSearchFilter = new-object Microsoft.Exchange.WebServices.Data.SearchFilter+IsEqualTo([Microsoft.Exchange.WebServices.Data.FolderSchema]::DisplayName,"MoveDestination")  
    $findFolderResults = $CalendarFolder.FindFolders($SfSearchFilter,$fvFolderView)  
            
    ### gets calendar items       
    $global:ivItemView =  New-Object Microsoft.Exchange.WebServices.Data.ItemView(1000) 
    $Global:fiItems = $service.FindItems($CalendarFolder.Id,$ivItemView) 
            
    ## create new appointment
    $Appointment = New-Object Microsoft.Exchange.WebServices.Data.Appointment -ArgumentList $service  
    #Set Start Time  
    $Appointment.Start = $xxx
    #Set End Time  
    $Appointment.End = $xxx
    #Set Subject  
    $Appointment.Subject =  $xxx
    #Set the Location  
    $Appointment.Location =  $xxx
    #Set Reminder
    $Appointment.ReminderMinutesBeforeStart = $xxx
    #Set any Notes  
    $Appointment.Body = $xxx
    $Appointment.Save($folderid)
    ### delete an item
    ## Item Deleted -= $itemDel is an item where the displayname of that item matches the subject of an appointment
    $DelItem = $fiItems |? {$_.subject -eq $itemdel.SourceObject.DisplayName}
    $DelItem.Delete([Microsoft.Exchange.WebServices.Data.DeleteMode]::SoftDelete)
    ### retrieve the body of the appointment
    ### At this point I have filtered out a single appointment from the results of above
    $CalApp =   $CalendarResult |?{$_.subject -like $incident.SourceObject.DisplayName }
    ### get tehj body for that one appointment
        # create a new property set
        $PropertySet = New-Object Microsoft.Exchange.WebServices.Data.PropertySet([Microsoft.Exchange.WebServices.Data.BasePropertySet]::FirstClassProperties)
        # tell it you want teh body as text
        $PropertySet.RequestedBodyType = [Microsoft.Exchange.WebServices.Data.BodyType]::Text
        #load that info into the appointment
        $CalApp.Load($PropertySet)
        #return the body to another variable
         $bodyText= $CalApp.Body.toString()


    Ed


    • Marked as answer by EdShep Thursday, December 19, 2013 12:10 PM
    • Edited by EdShep Thursday, December 19, 2013 12:11 PM code block not formated correctly
    Thursday, December 19, 2013 12:10 PM