Table of Contents
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.

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.