Microsoft Previews userConfiguration Graph API

UserConfiguration API Manages Exchange Folder Associated Items

On January 28, 2026, Microsoft launched the preview (beta) of the UserConfiguration Graph API. A userConfiguration object is a Folder Associated Item (FAI), a hidden MAPI item stored in Exchange Server and Exchange Online folders. FAIs have been in Exchange for many years. In the Exchange protocol documentation, FAIs are defined as:

A collection of Message objects that are stored in a Folder object and are typically hidden from view by email applications. An FAI Message object is used to store a variety of settings and auxiliary data, including forms, views, calendar options, favorites, and category lists.

In this context, userConfiguration objects are used to store user settings for applications like the Calendar and OWA. This usage leads to the name persistent application settings, which is how the Exchange Web Services (EWS) documentation refers to FAIs.

You can access FAIs in mailboxes using utilities like MFCMAPI. Figure 1 shows an example of an FAI from the associated items table for the Calendar folder.

Viewing a calendar settings FAI item through MFCMAPI.

UserConfiguration Graph API.
Figure 1: Viewing a calendar settings FAI item through MFCMAPI

Eradication of EWS Requires Access to FAIs

Why is a Graph API for FAIs important? The answer lies in Microsoft’s campaign to eradicate EWS from Exchange Online by October 2026. Applications that use EWS to store their settings in mailboxes need a replacement API to continue reading and updating settings in FAIs.

A user mailbox setting Graph API already exists to get and update settings like work hours and timezone used by Outlook. However, the API offers incomplete coverage of all settings and is limited to Microsoft applications. The API is not much use to ISVs with applications that depend on FAIs to hold application settings. This is the target audience for the userConfiguration API.  

Example – Retrieving FAI Settings Stored Serialized XML

Access to configuration settings items requires the MailboxConfigItem.Read permission. Calendar work hours are stored in serialized XML. When retrieved, the Graph outputs the options as a Base64-encoded string, which must be decoded. For example:

("https://graph.microsoft.com/beta/users/{0}/mailFolders/Calendar/userConfigurations/WorkHours" -f $UserId)
[array]$Data = Invoke-MgGraphRequest -URI $Uri -Method Get -OutputType PSObject
[string]$Base64Convert = [Text.Encoding]::Utf8.GetString([Convert]::FromBase64String($Data.xmldata))

The same result can be gained by running the Get-MgBetaUserMailFolderUserConfiguration cmdlet from the Microsoft Graph PowerShell SDK (I used version 2.34).

$Data = Get-MgBetaUserMailFolderUserConfiguration -MailFolderId Calendar -UserConfigurationId WorkHours -UserId $UserId

To extract the work hours settings, the information stored in the decoded XML must be parsed. Here’s some code to extract and populate a PowerShell object with the settings:

# Parse calendar settings from the XML data
[xml]$doc = $Base64Convert

$ns = New-Object System.Xml.XmlNamespaceManager($doc.NameTable)
$ns.AddNamespace('w','WorkingHours.xsd')

$root = $doc.SelectSingleNode('//w:WorkHoursVersion1',$ns)

$tz = $root.SelectSingleNode('w:TimeZone',$ns)
$tzName = $tz.SelectSingleNode('w:Name',$ns).InnerText
$tzBias = [int]$tz.SelectSingleNode('w:Bias',$ns).InnerText

$std = $tz.SelectSingleNode('w:Standard',$ns)
$stdBias = [int]$std.SelectSingleNode('w:Bias',$ns).InnerText
$stdChange = $std.SelectSingleNode('w:ChangeDate',$ns)
$stdChangeDate = $stdChange.SelectSingleNode('w:Date',$ns).InnerText
$stdChangeTime = $stdChange.SelectSingleNode('w:Time',$ns).InnerText
$stdChangeDayOfWeek = $stdChange.SelectSingleNode('w:DayOfWeek',$ns).InnerText

$dst = $tz.SelectSingleNode('w:DaylightSavings',$ns)
$dstBias = [int]$dst.SelectSingleNode('w:Bias',$ns).InnerText
$dstChange = $dst.SelectSingleNode('w:ChangeDate',$ns)
$dstChangeDate = $dstChange.SelectSingleNode('w:Date',$ns).InnerText
$dstChangeTime = $dstChange.SelectSingleNode('w:Time',$ns).InnerText
$dstChangeDayOfWeek = $dstChange.SelectSingleNode('w:DayOfWeek',$ns).InnerText

$timeslot = $root.SelectSingleNode('w:TimeSlot',$ns)
$start = $timeslot.SelectSingleNode('w:Start',$ns).InnerText
$end = $timeslot.SelectSingleNode('w:End',$ns).InnerText

$workdays = $root.SelectSingleNode('w:WorkDays',$ns).InnerText

$CalendarOptions = [PSCustomObject]@{
    TimeZoneName            = $tzName
    TimeZoneBiasMinutes     = $tzBias
    StandardBiasMinutes     = $stdBias
    StandardChangeDate      = $stdChangeDate
    StandardChangeTime      = $stdChangeTime
    StandardChangeDayOfWeek = $stdChangeDayOfWeek
    DaylightBiasMinutes     = $dstBias
    DaylightChangeDate      = $dstChangeDate
    DaylightChangeTime      = $dstChangeTime
    DaylightChangeDayOfWeek = $dstChangeDayOfWeek
    WorkStart               = $start
    WorkEnd                 = $end
    WorkDays                = $workdays
}

The output object looks something like this:

TimeZoneName            : GMT Standard Time
TimeZoneBiasMinutes     : 0
StandardBiasMinutes     : 0
StandardChangeDate      : 00/10/05
StandardChangeTime      : 02:00:00
StandardChangeDayOfWeek : 0
DaylightBiasMinutes     : -60
DaylightChangeDate      : 00/03/05
DaylightChangeTime      : 01:00:00
DaylightChangeDayOfWeek : 0
WorkStart               : 09:00:00
WorkEnd                 : 18:00:00
WorkDays                : Monday Tuesday Wednesday Thursday Friday

Example – Retrieving FAI Settings from Structured Data

An FAI that uses structured data to store its information uses key-value pairs. Calendar settings are a good example of the type. To retrieve the settings, run the request and extract the structuredData property:

$Uri = ("https://graph.microsoft.com/beta/users/{0}/mailFolders/Calendar/userConfigurations/Calendar" -f $UserId)
[array]$Data = Invoke-MgGraphRequest -URI $Uri -OutputType PsObject | Select-Object -ExpandProperty structuredData

Now it’s a matter of processing each key-value pair to extract the name of the setting and its value:

ForEach ($Setting in $Data) {
    [string]$SettingName = $Setting.keyEntry.values
    [string]$SettingValue = $Setting.valueEntry.values
    Write-Host ("{0} : {1}" -f $SettingName, $SettingValue)
}
The output should be something like this:
AutomateProcessing : 1
MinimumDurationInMinutes : 0
piReminderUpgradeTime : 215747402
AllBookInPolicy : True
AllRequestOutOfPolicy : False
piAutoDeleteReceipts : False
AllowConflicts : False
AddAdditionalResponse : False
piShowWorkHourOnly : 1
AllowMultipleResources : True
piGroupCalendarShowDirectReports : True
ScheduleOnlyDuringWorkHours : False
EnforceSchedulingHorizon : True
piShowFreeItems : 0
AllRequestInPolicy : False
piRemindDefault : 15
calAssistNoiseReduction : True
piAutoProcess : True
ConflictPercentageAllowed : 0
AllowDistributionGroup : True
piGroupCalendarShowCoworkers : True
AllowRecurringMeetings : True
OLPrefsVersion : 1
piGroupCalendarShowMyDepartment : True
RemoveForwardedMeetingNotifications : True
EnforceCapacity : False
MaximumConflictInstances : 0
EnforceAdjacencyAsOverlap : False
MaximumDurationInMinutes : 1440
BookingWindowInDays : 180

No Immediate Use for Microsoft 365 Tenants

I doubt very much if a Microsoft 365 tenant administrator will find much use for the userConfiguration Graph API. However, it is a step forward in the process to eradicate EWS from Exchange Online, so it’s very welcome from that perspective, and it’s always nice to know what goes on behind the scenes…


So much change, all the time. It’s a challenge to stay abreast of all the updates Microsoft makes across the Microsoft 365 ecosystem. Subscribe to the Office 365 for IT Pros eBook to receive insights updated monthly into what happens within Microsoft 365, why it happens, and what new features and capabilities mean for your tenant.

Leave a Reply

This site uses Akismet to reduce spam. Learn how your comment data is processed.