In the Exchange world, items (and folders) can be represented by several different identifiers, depending on the interface used. As detailed in the documentation, those unique-valued identifiers include:
- EwsId – the identifier returned in operations performed via the EWS API. For example, when you do a search for messages or enumerate folders in a mailbox, the object returned will return this value in the Id (UniqueId) property. Here’s how a sample value looks like:
AAMkADQxMTViNmEzLWViNWYtNGYxNy1iNmQ2LTZmNDVhN2Q5ZDI0NQAuAAAAAABCOIqaOs9mS5duvcGwkHhzAQAg/oCKFU2uQqU6r5NcDVwAAACcapkwAAA=
Another place where you will find the EwsId is as part of the URL when opening messages in OWA, for example:
https://outlook.office.com/owa/sharednew@michev.info/?viewmodel=ReadMessageItem&ItemID=AAMkADQxMTViNmEzLWViNWYtNGYxNy1iNmQ2LTZmNDVhN2Q5ZDI0NQBGAAAAAABCOIqaOs9mS5duvcGwkHhzBwAg%2foCKFU2uQqU6r5NcDVwAAAAAAAEMAAAg%2foCKFU2uQqU6r5NcDVwAAAKtgxPpAAA%3d
- EntryId – the MAPI identifier for the item/folder, corresponding to the binary PR_ENTRYID property. The value is Base64-encoded and looks something like this:
AAAAAEI4ipo6z2ZLl269wbCQeHMBACD+gIoVTa5CpTqvk1wNXAAAAAAAAQwAAA==
- HexEntryId – the hex-encoded representation of the EntryID. Here’s a sample value:
0000000042388A9A3ACF664B976EBDC1B0907873010020FE808A154DAE42A53AAF935C0D5C0000000000010C0000
- StoreId – the Exchange store identifier, which you can find for example in the output of Get-MailboxFolderStatistics cmdlet. Among other things, this value is used for generating folder IDs for use with the targeted collection Content search functionality. Here’s a sample value:
LgAAAABCOIqaOs9mS5duvcGwkHhzAQAg/oCKFU2uQqU6r5NcDVwAAAAAAAEMAAAB
- OwaId – as the name suggests, used by the web client. Basically an URL-safe representation of the StoreId. A sample value looks like this:
LgAAAABCOIqaOs9mS5duvcGwkHhzAQAg%2FoCKFU2uQqU6r5NcDVwAAAAAAAEMAAAB
- RestId – the default format used by the Graph API. Basically an URL-safe representation of the EntryId. Here’s an example:
AAMkADQxMTViNmEzLWViNWYtNGYxNy1iNmQ2LTZmNDVhN2Q5ZDI0NQBGAAAAAABCOIqaOs9mS5duvcGwkHhzBwAg-oCKFU2uQqU6r5NcDVwAAAAAAAEMAAAg-oCKFU2uQqU6r5NcDVwAAAKtgxPpAAA=
- RestImmutableEntryId – the ImmutableID format used by the Graph API. Sample string below:
AAkALgAAAAAAHYQDEapmEc2byACqAC-EWg0AIP6AihVNrkKlOq_TXA1cAAACrYM5GAAA
- EwsLegacyId – used by the initial EWS version and only added for completeness.
Whenever you need to convert between those values, the ConvertId method comes to help. For example, the below EWS code will convert the EwsId of an item returned via the search operation ($fiItems[0].Items[0].Id.UniqueId) to all the other Id types:
$aiItem = New-Object Microsoft.Exchange.WebServices.Data.AlternateId $aiItem.Mailbox = "sharednew@michev.info" $aiItem.UniqueId = $fiItems[0].Items[0].Id.UniqueId $aiItem.Format = [Microsoft.Exchange.WebServices.Data.IdFormat]::EWSId $aiItem.UniqueId $exchangeService.ConvertId($aiItem, [Microsoft.Exchange.WebServices.Data.IdFormat]::EntryId) $exchangeService.ConvertId($aiItem, [Microsoft.Exchange.WebServices.Data.IdFormat]::HexEntryId) $exchangeService.ConvertId($aiItem, [Microsoft.Exchange.WebServices.Data.IdFormat]::StoreId) $exchangeService.ConvertId($aiItem, [Microsoft.Exchange.WebServices.Data.IdFormat]::OwaId) AAMkADQxMTViNmEzLWViNWYtNGYxNy1iNmQ2LTZmNDVhN2Q5ZDI0NQBGAAAAAABCOIqaOs9mS5duvcGwkHhzBwAg/oCKFU2uQqU6r5NcDVwAAAAAAAEMAAAg/oCKFU2uQqU6r5NcDVwAAAKtgxPpAAA= UniqueId Mailbox IsArchive Format -------- ------- --------- ------ AAAAAEI4ipo6z2ZLl269wbCQeHMHACD+gIoVTa5CpTqvk1wNXAAAAAAAAQwAACD+gIoVTa5CpTqvk1wNXAAAAq2DE+kAAA== sharednew@michev.info False EntryId 0000000042388A9A3ACF664B976EBDC1B0907873070020FE808A154DAE42A53AAF935C0D5C0000000000010C000020FE808A154DAE42A53AAF935C0D5C000002AD8313E90000 sharednew@michev.info False HexEntryId RgAAAABCOIqaOs9mS5duvcGwkHhzBwAg/oCKFU2uQqU6r5NcDVwAAAAAAAEMAAAg/oCKFU2uQqU6r5NcDVwAAAKtgxPpAAAA sharednew@michev.info False StoreId RgAAAABCOIqaOs9mS5duvcGwkHhzBwAg%2FoCKFU2uQqU6r5NcDVwAAAAAAAEMAAAg%2FoCKFU2uQqU6r5NcDVwAAAKtgxPpAAAA sharednew@michev.info False OwaId
Now, this is all very well known. The reason for writing an article on this is the recently introduced Graph API endpoint that allows you to perform the same operation via the Graph, and in addition allows the conversion to RestId. That, and the fact that it actually helps me remember stuff, once I put it in a blog post 🙂
As with any other Graph operations, you need to run the request against the corresponding endpoint, namely /translateExchangeIds. You will need to provide a collection of identifiers to convert, and the types between the conversion should happen. Even if you have a single identifier to convert, you must provide a collection, otherwise you will get a Bad request error, so remember that. One other important thing to remember is that the Graph uses URL-safe encoding, so if you are providing an EwsId, EntryId or StoreId, you need to prepare the strings correspondingly. Finally you put it all together in as a JSON-formatted string in a POST request.
The below example takes the EntryId of the same item we used for the EWS ConvertId operation, and asks the Graph to return the EwsId. Comparing the two examples shows the exact same value, so the operation was a success. We then ask to return the ImmutableEntryId:
#Graph uses URL-safe encoding, work around it $sourceID = ("AAAAAEI4ipo6z2ZLl269wbCQeHMHACD+gIoVTa5CpTqvk1wNXAAAAAAAAQwAACD+gIoVTa5CpTqvk1wNXAAAAq2DE+kAAA==" -replace "\+","-") -replace "/","_" $countToReplace = ($sourceID.ToCharArray() | ? {$_ -eq "="}).Count $sourceID = $sourceID.TrimEnd("=") + $countToReplace $body = @{ "inputIds"= @($sourceID) "sourceIdType"= "entryId" "targetIdType"= "ewsId" } | ConvertTo-Json $res = Invoke-RestMethod -Method Post -Uri "https://graph.microsoft.com/v1.0/users/sharednew@Michev.info/translateExchangeIds" -Headers $authHeader -Verbose -ContentType "application/json" -Body $body $res.value.targetId $body = @{ "inputIds"= @($sourceID) "sourceIdType"= "entryId" "targetIdType"= "immutableEntryId" } | ConvertTo-Json $res = Invoke-RestMethod -Method Post -Uri "https://graph.microsoft.com/v1.0/users/sharednew@Michev.info/translateExchangeIds" -Headers $authHeader -Verbose -ContentType "application/json" -Body $body $res.value.targetId AAMkADQxMTViNmEzLWViNWYtNGYxNy1iNmQ2LTZmNDVhN2Q5ZDI0NQBGAAAAAABCOIqaOs9mS5duvcGwkHhzBwAg/oCKFU2uQqU6r5NcDVwAAAAAAAEMAAAg/oCKFU2uQqU6r5NcDVwAAAKtgxPpAAA= AAAAAB2EAxGqZhHNm8gAqgAvxFoNACD-gIoVTa5CpTqvk1wNXAAAAq2DORgAAA2
As with any other Graph code, you need to provide authentication headers, the corresponding operations are skipped in the above examples. For additional details, check out the official documentation.
As a last remark, the ImmutableEntryId and RestImmutableEntryId don’t seem to be supported for Folder objects, but you should be able to run other conversion operations against folders as well.
Dear Sir,
Then, how about message-ID? Can I use Message ID to locate email? Since I want get message-ID in outlook (not OWA). And then open the email in Chrome through OWA url.
Afaik that’s only available as part of the headers, so not directly exposed.
Hi Vasil Michel
Do you know a way to convert a HexEntryId to RestId by Graph-API without using EWS?
I think this is missing.
I have to convert HexEntryIds of calendar appointments provided by MAPI from Outlook to RestId to Outlook 365.
Do you have any idea.
Thanks for your response.
Armin
Hi Armin,
hast du eine Möglichkeit gefunden, HexEntryIds zu RestIds ohne EWS zu konvertieren?
Did you find a possibility to convert HexEntryIds to RestIds without the use of EWS?
Viele Grüße / Best regards
Daniel
Great post!
Wondering if it is possible to use a storeId with the translateExchangeIds endpoint. That is, use the output of Get-mailboxfolderstatistics which shows the folderID (aka storeId) and convert it to graph’s restId. Any idea if this is possible? I’ve tried several attempts but doesn’t seem storeId is supported.
Doesn’t look like they care about it: https://github.com/microsoftgraph/microsoft-graph-docs/issues/5825
Hi Vasil Michel,
Can you help me to solve this situation ?
My goal is to use the datasource odata into Excel to establish a permanent connection between my excel sheet, and an Outlook folder contact.
The connection work well for my default contact with the Ms graph URL : “https://graph.microsoft.com/v1.0/me/contacts”
But, my goal is to target another Contacts Folder. The graph URL would become :
“https://graph.microsoft.com/v1.0/me/contactFolder/{id}/childFolders/{id}/…/contacts”
I got the EntryId of this folder through an Outlook VBA.
But the datasource odata through excel doesn’t work.
Should be a question of ID format ?
How can I solve it ?
Many thanks for your response.
Stephane