Reading/Writing M365 Admin contacts - outlook

An administrator for a Microsoft 365 domain can create external contacts that are visible to users within that domain. Those contacts can be seen in the M365 Outlook client under "Directory->All Contacts" or "Directory->Default Global Address list".
I need to use EWS to read and create these contacts. As a first step I'm just trying to read them, using FindFolder, against MsgFolderRoot of a user. Unfortunately the only contact folders that show up are the ones defined for the user in question, not the external contacts created by the Admin. There are several contact folder classes that seem promising, such as "OrganizationalContacts" and "ExternalContacts" but there are no entries in those folders.
I could also use Graph for this if the capability is there. Any help on this problem would be appreciated.

Directory contacts exist in the Directory eg Azure AD or the local AD onPrem neither EWS or Graph can create these type of contacts then only thing automatable that can do that is https://learn.microsoft.com/en-us/powershell/module/exchange/new-mailcontact?view=exchange-ps
For reading Directory contacts the Graph is a better option it has a supportable endpoint via https://learn.microsoft.com/en-us/graph/api/resources/orgcontact?view=graph-rest-1.0. EWS can do this via FindPeople but it's not documented and requires that you know the addressbook guid which isn't available via EWS.

Related

Errors accessing Shared/Room Calendars through Microsoft Graph API

I'm making an application that requires access to the shared/room-resource calendars in an Office 365 instance, using non-admin accounts. I've registered an app (in the Microsoft Application Registration Portal) using the V2 endpoint and Auth Code Grant. This successfully allows me to log in, and gives me a functional token with the Calendars.ReadWrite.Shared scope. With this token, I can retrieve my own calendars, and calendars that have been explicitly shared with me (and therefore added to my list of calendars). All of this is doable with just the normal Calendars.ReadWrite scope.
However, I get errors when requesting access to any other shared calendars, like the room calendars. Here's an example. If I make a GET call to https://graph.microsoft.com/beta/users/my-own-email#business.com/calendars it successfully returns a list of my calendars. If I make a GET call to https://graph.microsoft.com/beta/users/meetingroom1.4#business.com/calendars I get a 404 (Not Found) Error. The same error occurs for any other user, not just meeting rooms. Note that I can see these calendars when I'm logged into Office 365 online with the same account.
A different error occurs if I ask for events not calendars. If I make a GET call to https://graph.microsoft.com/beta/users/meetingroom1.4#business.com/events, I get a 500 (Internal Server) Error.
I've checked all the other threads I can find on the issue, and this one from November How to access shared calendars from Office REST API? says there's some kind of blocking issue on Microsoft's end. It's using the Office REST API rather than Graph, but on the back-end the APIs call the same stuff. Is this issue still about? Alternatively, am I missing some further permissions? I tried adding quite a few different permissions on top of Calendars.ReadWrite.Shared, but none of them fixed it. Is there a correct combination?
Thanks so much for any help, and let me know if any other info would be useful for diagnosis.
So if anyone else happens to be interested in this, I figured out a way to access room resource calendars without using the Calendars.ReadWrite.Shared permission. This allows you to use just the Calendars.ReadWrite permission to access the room resources, by moving them into the list of calendars of the email you're authenticating with. However, it will only work for specific accounts that you share the calendars with, so won't be usable in apps that have to work for any account. This is good enough for my use-case, but may not be for yours.
First, find or make an account that is a delegate to, and has full access to, the room resource calendar you want to use. On that account click 'Open another mailbox' in the dropdown list under your profile image.
Open another mailbox location
In the pop-up that follows, put in the email address of the room resource calendar that you want to use.
Then, on the new page that opens (which should be the Office account of the room resource calendar):
Navigate to the calendar page
Click 'Share'
Share the default calendar with the account you plan to authenticate with.
Then log into that 'authentication' account, check its email for the notification of the shared calendar, and click 'accept'. What this will do is move the calendar into the authenticated account's list of calendars, meaning you can access it with just a call to the https://graph.microsoft.com/v1.0/me/calendars endpoint. You'll have to repeat it for every calendar you want to be able to access, sadly.

Is it possible to be a delegate with create, update and delete own permissions but not read in exchange 2010

I have a service account that I want to be able to access another users calendar through the ews api in such a way that it can create appointments, update appointments they have created and delete appointments they have created but NOT be able to read all items on the users calendar.
This appears to be possible in office 365 (see screenshot) but is it possible with Exchange 2010? If so how?
Sure the image you have posted is just the Folder permissions from Outlook these permission are the same from Exchange 2007 to Office365. The two ways you can set permission pro-grammatically like you have shown is first use one of the Mailbox Access API's like Mapi or EWS and set the Folder permission eg https://msdn.microsoft.com/en-us/library/office/dn641962(v=exchg.150).aspx
Or you can use the Exchange Management Shell and Add-MailboxFolderPermissions https://blogs.technet.microsoft.com/ilvancri/2009/11/24/exchange-2010-and-then-there-is-the-long-awaited-cmdlet-add-mailboxfolderpermission/ this can be a better approach as it just requires delegated admin rights via an RBAC role where setting the folder permission via EWS because it uses a User API would require the account setting those permissions to be the Mailbox owner, have been delegate Full Access rights on the Mailbox (eg add-mailboxpermission) or use Impersonation.

How to Create Global Contacts Directory for Microsoft Exchange Server?

I have a requirement from one of our Clients where he wants
to Create a Global Contacts Directory in Microsoft Exchange Server.
Let, me explain this. Suppose, there is some Company say "X".
And, it has some Employees. Each Employee will have his/her contacts in their mailing list. So, the Global Contacts Directory
should consists of All the Contacts of these Employees. And it should Also
Sync them.
Is this feasible enough is what i want to know and if Yes, How?
Out of the box? No. Is using a PF folder or a shared mailbox an option? Each user can have his/her own contacts folder.

Pushing contacts to Users' Phone Contacts (Exchange Server 2007)

We have users in our company that have smart phones (Android/Windows Phone mix)and put their contacts in their Exchange account. It is a unified group of users that just need the phone numbers for each other (with a considerably high turnaround for employees in this position as well). I am looking to get a list of contact names/phone numbers to be automatically pushed to (and updated, if possible) their Exchange contact lists. Previously we have been logging in with their account into a computer, opening Outlook, then loading a csv with the contacts on there. The issue is how time consuming it is, given that amount of turnaround on those users. Thanks in advance!
To create a Contact in a users Mailbox you will need access to that contacts folder in that mailbox so you either need to create a Service Account and give that account rights to the folder via something like Add-MailboxFolderPermission or get the user to delegate the access themselves if they are sensitive to security changes or use EWS impersonation.
Once you have rights to the users Contacts folder then you could automate the process of the CSV import using EWS and Powershell here are a few sample scripts
https://gallery.technet.microsoft.com/scriptcenter/Using-Powershell-to-import-14bef4b8
http://blogs.technet.com/b/bill_long/archive/2010/04/23/importing-public-folder-contacts-from-a-csv-file.aspx
http://gsexdev.blogspot.com.au/2010/04/flexible-exchange-contact-creation.html
Cheers
Glen

access exchange 2003 calendars with vs2005+

I'm looking for a way to access Exchange 2003 calendars to add appointments. I'm hoping to use an admin account and impersonate each user to add appointments which i'm pulling from an oracle database. I've seen lots of examples for Exchange 2000 using cdox.dll which are exactly what I'm looking for but not an equivalent for 2003. I have Exchange management tools installed on the development workstation. Would I be able to download cdox.dll and use that?
Examples/links are greatly appreciated. Thanks.
This is the same problem I'm banging my head against....
You can work with calendars using webdav:
http://golemlab.wordpress.com/2009/09/13/php-owa-2003-calendar-fun/
But to impersonate a user you need an admin account with access to his calendar folder.
From what I understand there is no way to set defaults permissions just for calendars that are not created yet.
Also please note that the Calendar folder name is dependant on the user client language (ex: "Calendar" for a user with an english outlook, "Calendario" for italians).
You can set permissions on existing calendars using a lot of different tools:
pfdavadmin is a microsoft endorsed one:
http://www.itexperience.net/2008/10/22/set-calendar-permissions-with-pfdavadmin/
or you can try setperm:
http://www.amset.info/exchange/folderpermissions.asp
there are also some commercial products like folder permission manager:
http://www.symprex.com/products/folder-permissions-manager/
What I'd really wished was the possibility to set defaults calendar permissions on a server level , but this looks really not possible.

Resources