Exporting to Vcards from Get-EXORecipient and Get-User in the EXO V3 module and why it might be important
Last week I started writing about contact management as its one of those things that’s been around for years and there are always questions about. Contact Management endpoints are a bit of a thorny affair the whole process is very mature in age, so when new ideas or features evolve they can lag a lot. That makes developing around these a bit of a dark path of missing or underwhelming documentation and sometimes not a great end to end experience for developers or consumers of those apps, or the long dark tea time of innovation.
In 2024 what is important about contact data ?
Contact management data and apps are one of those entrenched functions so experienced people use it in a specific way that’s probably not going to change while new generations may squeak around the edges or just fall inline with the way things are done. So what you get is little investment from any service providers (Microsoft, Google and Meta) in making it better or providing the means (eg updated API endpoints) for start-ups or established 3rd party developers to do something new in the space (let’s face it large companies are poor citizens generally to their own demise). In the generative AI era we are in at the moment what we are talking about here is data enrichment which means taking all your data (contacts and associated information in this case), feeding it into a model and then using that model to provide new features that are hopefully of some use to someone (making the world a better place). Eg maybe you feed in all the Contact photos in your model to learn about all the facial features or other photo characteristics background, what they wear or addresses and localities. You can start doing things like showing the people in my address list that are in 10 km of this location where I’m putting on this event.
At this point some people are probably screaming Co-Pilot (and a small number maybe Graph Data connect) and given that is a solution for some people and some things maybe you can even do currently if you can get the correct prompt. But like everything its always at a cost which for anything new is always a barrier to entry and also there at least two different fundamental approaches. Eg Co-Pilot and OpenAI are pretty opaque in the way they go about things while open source eg llama and open source/local give you freedom to work/design how you want. Its a pretty good example of top down (enterprise developed down to small company) vs bottom up which means your features and enrichments comes from start-ups or indie development. Its debateable but more successful innovations come from the later IME (Open AI itself is a case in point).
A good example of a feature that needs an API to make it something has to be coloured contact categories https://techcommunity.microsoft.com/blog/microsoft_365blog/new-improved-contacts-in-outlook-on-the-web/3639773 in the new Outlook UI (and getting rid of contact folders). It’s actually a really good idea but no endpoint exists for anybody programmatically create/edit/delete to one of these contact categories (there is for mail categories but this doesn’t work) . So there is no ability of for any developers to provide an enriched contacts experience using this feature and their own process be it AI or other. So you just have toggle to new and old contact experience and no real pull momentum.
Sources for Courses
If you want to do some meaningful enrichment your going to need data, if your just working at the user level then your API options are limited to the Graph not the end of the world but it has its limitations. If you can elevate to an Admin or RBAC rights to use the Exocmdlets then you have the ability to get a more raw directory view of data at scale. This is important when you want to deal with all the recipient objects in your o365 tenant eg currently get-exorecipient can return up to 28 different types of recipients here is a small but not complete list
DiscoveryMailbox
DynamicDistributionGroup , MailNonUniversalGroup, MailUniversalDistributionGroup,MailUniversalSecurityGroup
EquipmentMailbox
GroupMailbox
GuestMailUser
MailContact, MailUser
PublicFolder
RemoteEquipmentMailbox, RemoteRoomMailbox, RemoteSharedMailbox
RoomMailbox
SchedulingMailbox
SharedMailbox
TeamMailbox
UserMailbox
For a number of these type of recipients interacting with them via the Public Graph API’s is hard if not impossible unless you know the email address (for example userpurpose in the MailboxSettings in Graph has only 6 recipient types https://learn.microsoft.com/en-us/graph/api/resources/mailboxsettings?view=graph-rest-1.0#userpurpose-values). So the Exocmdlets can give you a lot better discover ability to do a quick dump/sync and analyse and working of that data. Vcards are widely adopted data format for contact sharing so for the example script for this post I took all the relevant vcard data and made that accessible in the export.
Exporting photos
Since Microsoft removed get-userphoto the only way you can do this is using the Microsoft Graph so for this In the example scripts I employed the Microsoft Graph Powershell SDK and Invoke-mgGraph request and then change the request endpoint depending if the recipient type is a group mailbox. Exporting the photo is an optional switch in the script.
Heading for Hybrid using the Graph and Exocmdlets together
The exocmdlets aren’t a solution in themselves more an adjunct to one eg some intricacies of Get-ExoRecipient so while this cmdlet is great at giving you access to the non User Mailboxes and Contact resources its not the best for when you have a user or Contact as it doesn’t return a lot of user detail properties like the street address (while it does return the city and country). For this I included another script that does a vcard export using Get-User which provides more of that detail. There is also a lot more information on a user and other recipient objects that you can retrieve via the profile endpoint in Graph eg /users/profile. So if you want to export just the EquipmentMailbox’s then Get-ExoRecipient is a great way of getting a list of EquipmentMailboxes you can then include in a Batch Profile requests against the Graph.
These two scripts I’ve talked about are available on GitHub
and
https://github.com/gscales/Powershell-Scripts/blob/master/Graph101/GraphSDK/Export-UserToVcard.ps1