Access original subject of meeting in Resource calendar - exchange-server

I'm trying to set up a system that displays calendar items from a resource calendar on a web page using Exchange 2007 and EWS (Exchange Web Services).
I've managed to get access to the calendars of the resources, but when getting the items in the calendars, the subject of each calendar item is not the original subject used when someone created the meeting request and invited the resource, but rather the Username on the account that created the the meeting request eg. if I do something like:
List<CalendarItemType> items =
Calendar.GetCalendarItems("mr1#litwareinc.com",
Calendar.GetNextWeekView(),
binding);
if (items.Count > 0)
{
Console.WriteLine(string.Format("Calendar opened - fetched {0} items",
items.Count));
Console.WriteLine("===================================");
foreach (var item in items)
{
Console.WriteLine();
Console.WriteLine(item.Subject);
Console.WriteLine("----------------------------------------");
Console.WriteLine("\tOrganizer: " + item.Organizer.Item.Name);
Console.WriteLine();
Console.WriteLine("\tStart: " + item.Start.ToString("dd-MM-yyyy HH:mm"));
Console.WriteLine("\tSlut: " + item.Start.ToString("dd-MM-yyyy HH:mm"));
}
}
Where Calendar.GetCalendarItems, is a method that fetches the calendar items of the resource denoted by the first argument, the Calendar.GetNextWeekView() is a static method that creates a CalendarView spanning the next week from today's date, and the binding is set up to use an account with delegate access to the resource mailbox.
The item.Subject comes out as Administrator if the Administrator account was used to book the resource.
Does anyone know how to remedy this - do I need to make some kind of special property access, or fetch another type of item or what?
Regards
Jesper Hauge

Figured this one out - when I started looking outside the code.
Answer lies in resource configuration rather than access code.
If you want to have the subject of the meeting reflect the original subject. Make sure the resource has set the setting properties DeleteSubject and AddOrganizerToSubject to false. It can be achieved with the following shell command:
Set-MailboxCalendarSettings resourcename -DeleteSubject 0 -AddOrganizerToSubject 0
Regards
Jesper Hauge

Related

Cant create Microsoft Teams online meetings for some users (Defaults to OnlineMeetingProvider.Unknown) via Graph Api

I have 5 users, they all look the same in Office 365 (from what I can see anyway) and have Teams Exploratory licences. I am able to create online meetings (OnlineMeetingProvider="teamsForBusiness" and IsOnlineMeeting=true) for 2 of them. For the other 3 users it doesn't error but doesn't create an online meeting (creates an event?), the response OnlineMeetingProvider is "unknown" and the OnlineMeeting is null. It is the same code so has to be a setting somewhere (all i do is change the id of the user).
The code used to create the request:
// Create client
var graphServiceClient = CreateGraphClient();
// Build event
var newEvent = new Event()
{
Subject = subject,
Body = new ItemBody() { ContentType = BodyType.Text, Content = body },
Start = startDate,
End = endDate,
IsOnlineMeeting = true,
Attendees = attendees == null ? null : GetAttendees(attendees),
OnlineMeetingProvider = OnlineMeetingProviderType.TeamsForBusiness
};
The erroneous response:
Anyone have any idea what is going on?
Had the same problem, I had to add these permissions to the app I was using to create the meeting events:
TeamSettings.Read.All, TeamSettings.ReadWrite.All
As soon as I added them, isOnlineMeeting was correctly set to true, and onlineMeetingProvider was set to teamsForBusiness, as specified in the request.
onlineMeetingUrl is always null, but it's possible to get the meeting url from the "onlineMeeting.joinUrl" property, which is automatically populated by the API.
UPDATE:
As #lokusking pointed out, even if this is correct, it looks like it does not completely solve the problem. According to my tests, creating a Team event for a new user and getting isOnlineMeeting=true and onlineMeeting properly populated in the response will work only a couple of hours after the user account is created. Note that even with a fresh user the event IS created, just those properties won't contain the right values.
You can change an existing event to make it available as an online meeting, by setting isOnlineMeeting to true, and onlineMeetingProvider to one of the online meeting providers supported by the parent calendar. The response includes the updated event with the corresponding online meeting information specified in the onlineMeeting property.
https://learn.microsoft.com/en-us/graph/outlook-calendar-online-meetings?tabs=http#example-update-a-meeting-to-make-it-available-as-an-online-meeting

Search folder for unread emails in inbox not including subfolders

I would like to make a search folder for unread emails in the inbox which does not look into subfolders in the inbox.
Right now I have 5-10 subfolders which are automatically filled with news emails from different sources( using ordinary rules), and then I use the top level of the inbox folder as a kind of important email folder. I would like to make a search folder which finds the unread emails in the top level of the inbox folder but ignores everything in the subfolders.
Outlook version: 1808 (I think). It is part of MS office 365 but it does run locally.
You need to use the Application.AdvancedSearch method which performs a search based on a specified DAV Searching and Locating (DASL) search string. The AdvancedSearch method and related features in the Outlook object model do not create a Search Folder that will appear in the Outlook user interface. However, you can use the Save method of the Search object that is returned to create a Search Folder that will appear in the Search Folders list in the Outlook user interface.
The key benefits of using the AdvancedSearch method in Outlook are:
The search is performed in another thread. You don’t need to run another thread manually since the AdvancedSearch method runs it automatically in the background.
Possibility to search for any item types: mail, appointment, calendar, notes etc. in any location, i.e. beyond the scope of a certain folder. The Restrict and Find/FindNext methods can be applied to a particular Items collection (see the Items property of the Folder class in Outlook).
Full support for DASL queries (custom properties can be used for searching too). You can read more about this in the Filtering article in MSDN. To improve the search performance, Instant Search keywords can be used if Instant Search is enabled for the store (see the IsInstantSearchEnabled property of the Store class).
You can stop the search process at any moment using the Stop method of the Search class.
string scope = "Inbox";
string filter = "[UnRead] = true";
Outlook.Search advancedSearch = null;
Outlook.MAPIFolder folderInbox = null;
Outlook.MAPIFolder folderSentMail = null;
Outlook.NameSpace ns = null;
try
{
ns = OutlookApp.GetNamespace("MAPI");
folderInbox = ns.GetDefaultFolder(Outlook.OlDefaultFolders.olFolderInbox);
scope = "\'" + folderInbox.FolderPath "\'";
advancedSearch = OutlookApp.AdvancedSearch(
scope, filter, false, advancedSearchTag );
advancedSearch.Save();
}
catch(Exception ex)
{
MessageBox.Show(ex.Message, "An eexception is thrown");
}
finally
{
if(advancedSearch!=null) Marshal.ReleaseComObject(advancedSearch);
if (folderSentMail != null) Marshal.ReleaseComObject(folderSentMail);
if (folderInbox != null) Marshal.ReleaseComObject(folderInbox);
if (ns != null) Marshal.ReleaseComObject(ns);
}
In the search box type "Read:unread" without quotes
Once located in the folder where you want to search, in the App Outlook Office 365 you can find the filter of unread emails, like this in the following image.

Open a shared calendar that is not a Default Calendar in Outlook 2013

I know this question has been sort of asked, but I have a specific issue which I haven't found the answer for. I am trying to open a shared calendar from another user and his/her calendar is NOT their default calendar.
I have tried the following:
var ns = Globals.ThisAddIn.Application.Session;
var recip = ns.CreateRecipient("me#me.com");
if (recip.Resolve())
{
var sharedCal = ns.GetSharedDefaultFolder(recip, Outlook.OlDefaultFolders.olFolderCalendar);
}
This just does not work.
I can see the shared calendar by doing the following
private void GetCalendars()
{
Outlook.CalendarModule calModule = (Outlook.CalendarModule)this.Application.ActiveExplorer().NavigationPane.Modules.GetNavigationModule(Outlook.OlNavigationModuleType.olModuleCalendar);
foreach (Outlook.NavigationGroup group in calModule.NavigationGroups)
{
Debug.WriteLine("Calandar Folders Group >>>>" + group.Name);
foreach (Outlook.NavigationFolder folder in group.NavigationFolders)
{
Debug.WriteLine("Calandar Folders: >>>>" + folder.DisplayName);
}
}
}
I just don't know how to open the calendar once I have the name. There is no way to get the ID using the steps above
In outlook, the calendar exists in the "Shared Calendars" navigation tree.
I am looking for a way to get the names of the Shared Calendars and then having the user select the shared calendar (E.g. From a dropdown box) and then opening that calendar.
I have found code on how to do everything else but not that specifically!
Can someone point me in the right direction??
Thanks!!
You cannot access that folder using the Outlook Object Model.
For a cached Exchange mailbox, the folders are cached n the primary mailbox's OST file. On the Extended MAPI level (C++ or Delphi), the folders are stored outside of the IPM tree visible to the end user. You can see the data in OutlookSpy (I am its author) - click IMsgStore | Open Root Folder | GetHierarchyTable | double click on the "Shared Data" folder | GetHierarchyTable | etc.
You can open that folder using Redemption (I am also its author - start with RDOStore.RootFolder). You can also open the online mailbox of another user using RDOSession.GetSharedMailbox and navigate to the folder in question starting with RDOStore.IPMRootFolder (returns top level folders visible to the user in that mailbox).

Exchange Managed API: Get Resources List of an appointment

I am creating a utility to get sync room calendar with my application.
They way i do is by calling syncfolderitems function for the room I want to sync.
Issue:
Since a User creates an Appointment and we are syncing room calendar thus we are not able to fetch value for Resources property. After doing some research I found that there is an extended property that can be used to find all attendees (Rooms are also attendees) of appointment.
Extended property was "PidLidAllAttendeesString".
Issue with this property is that it returns all the attendees of an appointment (Sendable and Unsendable both).
Is there any property that contains only Sendable attendees data ?
Based on [MS-OXPROPS], PidLidToAttendeesString "Contains a list of all of the sendable attendees who are also required attendees." Downloading the PDF of [MS-OXPROPS] and searching on "sendable" or "resource" might yield some other options too. Hope that helps!

How to get user details (job, title, department, location etc) using outlook EWS using his AD login ID

I need to get certain details for a user by his AD login ID.
Remember I just don't want to look into that user's contacts only. I want to look in global list and find the details (Similar details is shown when you double click the name of the person in the email message from, to, cc )
I found lot of links out there but they don't show any example for global search of user.
I tried to do something similar shown in this link
http://msdn.microsoft.com/en-us/library/jj220498(v=exchg.80).aspx
however it just within my own contacts.
Can anybody show a simple example or link for the same?
I found that ResolveName method does the trick. I can query by user's full name. I am just posting a method. I assume 'service' is already instantiated using proper domain/url/credentials
public Contact GetContactInfo(string sFullName)
{
Contact contact = null;
try
{
NameResolutionCollection allContacts = service.ResolveName(sFullName, ResolveNameSearchLocation.DirectoryOnly, true);
if (allContacts.Any())
{
contact = allContacts[0].Contact;
}
}
catch (Exception ex)
{
LogHelper.Error("Error in GetContactInfo(): ", ex);
//throw;
}
return contact;
}
Have you tried the ResolveName method?
http://msdn.microsoft.com/en-us/library/microsoft.exchange.webservices.data.exchangeservice.resolvename%28v=exchg.80%29.aspx
You can search the contacts folder and/or global address list with it. Make sure you set the boolean value to return the Contact with it.
I was looking for user's details and GetPersona is the operation.
Sharing with the concern that it may help others who are digging google & Microsoft to get user's information.
GetPersona operation
The GetPersona operation returns a set of properties that are associated with a persona.

Resources