Dynamic Management CSP

Dynamic Management is a CSP available in Windows 10 1703 onward. It give the capability to modify the state of a device based on a context.

Windows 10 allows you to manage devices differently depending on location, network, or time. For example, managed devices can have cameras disabled when at a work location, the cellular service can be disabled when outside the country to avoid roaming charges, or the wireless network can be disabled when the device is not within the corporate building or campus. Once configured, these settings will be enforced even if the device can’t reach the management server when the location or network changes. The Dynamic Management CSP enables configuration of policies that change how the device is managed in addition to setting the conditions on which the change occurs.

Why this page

The current documentation of the CSP is fairly incomplete and the example while accurate do not work out of the box. There is no indication on what is the level of context and how the context rules are build together. Also there is no indication on which settings can be applied or not.

CSP description

While the main documentation cover some of it, I will list all the node with more explanation and example on how this could leverage in UEM. Main documentation: https://learn.microsoft.com/en-us/windows/client-management/mdm/dynamicmanagement-csp

NotificationsEnabled

When at True, this will display a notification to the end user that the device context changed. The end user will see this notification.

ActiveList

The management server can interrogate to know which context are currently triggered/active. Useful in case of server notification to check whether the device still have this context, and if yes then the admin may have configured a rules to trigger some actions against it ( like our compliance engine )

Contexts

Give the complete list of all the contexts currently registered on the device.

ContextID

Name of the context, it have to be unique on the device, there is no limit on the number of context per device as far as I can tell.

SignalDefinition

XML defining the context. Need to be escaped or in CDATA. It “signal” the CSP to apply the SettingsPack. The signal are not documented and there is 2 example on the CSP page which give pointer but nothing giving the real potential. Read SignalDefinition Node section for detailed information.

SettingsPack

XML containing the settings to apply for the particular context when it becomes active. When the context become inactive it restore the previous state. Enhance the fact that there is no remove profile.

The SettingsPack are filtered, not every command are available, the whitelist is protected from modification even for SYSTEM and stored in SOFTWARE\Microsoft\Windows\DynamicManagement\Policy.

On 22H2 and insiders, the following list :

  • Config/Browser/FirstRunURL
  • Config/Camera/AllowCamera
  • Config/Connectivity/AllowCellularData
  • Config/DeviceLock/EnforceLockScreenAndLogonImage
  • Config/Experience/AllowCortana
  • Config/Wifi/AllowWifi

This whitelist limit extremely the application of this CSP while the signal definition on the other hand makes it a very powerful CSP.

The command need to be encapsulated between SyncML and SyncBody nodes, then everything need to be escaped or in CDATA.

<SyncML>
 <SyncBody>
  <Replace>
   <CmdID>1001</CmdID>
    <Item>
     <Target>
      <LocURI>./Vendor/MSFT/Policy/Config/Experience/AllowCortana</LocURI>
     </Target>
     <Meta>
      <Format xmlns="syncml:metinf">int</Format>
     </Meta>
     <Data>0</Data>
    </Item>
   </Replace>
  <Final/>
 </SyncBody>
</SyncML>

SettingsPackResponse

Allow the server to retrieve the status of the application of the SettingPack

They are the same value as the ones returned to the server when deploying a profile, they are listed by the OMA-DM protocol. Each settings have it’s own CmdID so the management server can know exactly which setting is failing giving a high level of detail for troubleshooting.

Most common:

  • 200: OK
  • 404: CSP Not found / Wrong SKU
  • 500: Error applying the settings.

ContextStatus

Retrieve the status of a specific context. It run an Int with the following values:

  • 1: Context Active – Settings Applied and Enforced
  • 2: Context Inactive – Settings not applied
  • 3: Context Error – SettingsPackResponse should give more information on what is the real status.

Altitude

Define the priority order on other context. Valid value are sizeof(int) on Windows which is 4 bytes which is from -2147483647 to 2147483647. The higher the altitude the higher the priority (e.g: altitude -2 is lower than altitude 10)

AlertsEnabled

In case the context can’t be applied for whatever reason, the server can be notified in order to take action.

<Alert>
  <CmdID>4</CmdID>
  <Data>1226</Data>
  <Item>
    <Source>
      <LocURI>./Device/Vendor/MSFT/DynamicManagement/Contexts/MyContextID</LocURI>
    </Source>
    <Meta>
      <Type xmlns="syncml:metinf">Reversed-Domain-Name:com.microsoft.mdm.dynamicmanagement.failedtoapply</Type>
    </Meta>
    <Data>MyContextID</Data>
  </Item>
</Alert>

SignalDefinition Node

The schema are not documented by Microsoft for some reason even with multiple ask in the CSP page comment. This section detail the schema and how to retrieve them from the DLL.

Area

There is 6 areas covered by NaturalAuth.dll:

How Signals works

Signals use different area of Windows to be able to achieve the required purpose.

How to retrieve the XML schema

The XML schema are embedded in the following DLL: naturalauth.dll located in the System32 Folder.

CSP use enterprisecsps.dll then call Dynamo::NaturalAuth::IsValidRuleDefinition(ushort const *,ushort * *) to validate the rules received against the schema.

This call naturalauth.dll which then call a parser to know which plugin to use essentially each plugin is a extended version of the generic plugin with specific attributes. The list of plugin is the areas listed above.

When the parser run it validate against the schema, the schema are stored inside the DLL in the .data and .rdata.
We can use IDA to extract the schemas, the following screenshot show the list of variable used to store the XML Schema.

XML Schema

I’ve uploaded them on my GitHub

https://github.com/CamilleDebay/Misc/tree/main/Dynamic%20Management%20CSP

How to create rules

The rules definition can be nested and is defined by the Rule XMLNS. The logic can be represented as follow. Signals can be Wifi, IP Configuration, Time, CDF or Geo Location

Example

There is couple of example on the CSP page, here’s more advanced one in terms of rules, the rules can be very complex.

“From Monday to Friday, between 08 and 18 each day at Company UK Head Office or Company HQ”

<rule schemaVersion="1.0">
    <and>
        <signal type="time">
            <weekly> <!-- Work Week-->
                <mon startTime="08:00:00" endTime="18:00:00"/>
                <tue startTime="08:00:00" endTime="18:00:00"/>
                <wed startTime="08:00:00" endTime="18:00:00"/>
                <thu startTime="08:00:00" endTime="18:00:00"/>
                <fri startTime="08:00:00" endTime="18:00:00"/>
            </weekly>
        </signal>
        <or>
            <signal type="geoloc"> <!--Company UK Head Office-->
                <latitude>51.898013</latitude<
                <longitude>-1.522644</longitude>
                <radiusInMeters>50</radiusInMeters>
            </signal>
            <signal type="geoloc"> <!-- Company HQ -->
                <latitude>19.607161</latitude<
                <longitude>-155.247048</longitude>
                <radiusInMeters>200</radiusInMeters>
            </signal>
        </or>
    </and>
</rule>

“From Monday to Friday, between 08 and 18 each day at Company UK Head Office or Company HQ or Company France”

<rule schemaVersion="1.0">
    <and>
        <signal type="time">
            <weekly> <!-- Work Week-->
                <mon startTime="08:00:00" endTime="18:00:00"/>
                <tue startTime="08:00:00" endTime="18:00:00"/>
                <wed startTime="08:00:00" endTime="18:00:00"/>
                <thu startTime="08:00:00" endTime="18:00:00"/>
                <fri startTime="08:00:00" endTime="18:00:00"/>
            </weekly>
        </signal>
        <or>
            <signal type="geoloc"> <!--Company UK Head Office-->
                <latitude>51.898013</latitude<
                <longitude>-1.522644</longitude>
                <radiusInMeters>50</radiusInMeters>
            </signal>
            <signal type="geoloc"> <!--Company France-->
                <latitude>48.864560</latitude<
                <longitude>2.30888</longitude>
                <radiusInMeters>30</radiusInMeters>
            </signal>
            <signal type="geoloc"> <!-- Company HQ -->
                <latitude>19.607161</latitude<
                <longitude>-155.247048</longitude>
                <radiusInMeters>200</radiusInMeters>
            </signal>
        </or>
    </and>
</rule>

“From Monday to Friday, between 08 and 18 each day at Company UK or Company HQ or Company France and Wifi SSID Is Company_Internal or Company_Guest”

<rule schemaVersion="1.0">
    <and>
        <signal type="time">
            <weekly> <!-- Work Week-->
                <mon startTime="08:00:00" endTime="18:00:00"/>
                <tue startTime="08:00:00" endTime="18:00:00"/>
                <wed startTime="08:00:00" endTime="18:00:00"/>
                <thu startTime="08:00:00" endTime="18:00:00"/>
                <fri startTime="08:00:00" endTime="18:00:00"/>
            </weekly>
        </signal>
        <or>
            <signal type="geoloc"> <!--Company UK Head Office-->
                <latitude>51.898013</latitude<
                <longitude>-1.522644</longitude>
                <radiusInMeters>50</radiusInMeters>
            </signal>
            <signal type="geoloc"> <!--Company France-->
                <latitude>48.864560</latitude<
                <longitude>2.30888</longitude>
                <radiusInMeters>30</radiusInMeters>
            </signal>
            <signal type="geoloc"> <!-- Company HQ -->
                <latitude>19.607161</latitude<
                <longitude>-155.247048</longitude>
                <radiusInMeters>200</radiusInMeters>
            </signal>
        </or>
        <or>
            <signal type="wifi"> <!-- Company_Internal SSID -->
                <ssid>Company_Internal</ssid>
            </signal>
            <signal type="wifi"> <!-- Company_Guest SSID -->
                <ssid>Company_Guest</ssid>
            </signal>
        </or>
    </and>
</rule>

“From Monday to Friday, between 08 and 18 each day at Company UK or Company HQ or Company France and Wifi SSID Is Company_Internal with DNSSuffixes company.com and company.corp or SSID is Company_Guest”

<rule schemaVersion="1.0">
    <and>
        <signal type="time">
            <weekly> <!-- Work Week-->
                <mon startTime="08:00:00" endTime="18:00:00"/>
                <tue startTime="08:00:00" endTime="18:00:00"/>
                <wed startTime="08:00:00" endTime="18:00:00"/>
                <thu startTime="08:00:00" endTime="18:00:00"/>
                <fri startTime="08:00:00" endTime="18:00:00"/>
            </weekly>
        </signal>
        <or>
            <signal type="geoloc"> <!--Company UK Head Office-->
                <latitude>51.898013</latitude<
                <longitude>-1.522644</longitude>
                <radiusInMeters>50</radiusInMeters>
            </signal>
            <signal type="geoloc"> <!--Company France-->
                <latitude>48.864560</latitude<
                <longitude>2.30888</longitude>
                <radiusInMeters>30</radiusInMeters>
            </signal>
            <signal type="geoloc"> <!-- Company HQ -->
                <latitude>19.607161</latitude<
                <longitude>-155.247048</longitude>
                <radiusInMeters>200</radiusInMeters>
            </signal>
        </or>
        <or>
            <and>
                <signal type="wifi"> <!-- Company_Internal SSID -->
                    <ssid>Company_Internal</ssid>
                </signal>
                <signal type="ipConfig">
                    <dnsSuffix>company.com</dnsSuffix>
                    <dnsSuffix>company.corp</dnsSuffix>
                </signal>
            </and>
            <signal type="wifi"> <!-- Company_Guest SSID -->
                <ssid>Company_Guest</ssid>
            </signal>
        </or>
    </and>
</rule>

Troubleshooting

Settings are stored in the registry

  • SOFTWARE\Microsoft\DynamicManagement\{Enrollment GUID}
    • Contexts contain all the contexts, each context have it own key based on the name defined in the SyncML.
      • {ContextID}
        • Altitude: REG_DWORD
        • SettingsPack: REG_SZ
        • SettingsPackResponse: REG_SZ
        • SignalDefinition: REG_SZ
        • StateName: REG_QWORD – WNF state name
        • Status: REG_DWORD – Context Status
        • RulesID
          • RuleID: REG_QWORD – incremented every time a new context is added.
      • States: Current active context
        • {ID}
          • ContextID: REG_SZ
          • Data: REG_BINARY
          • DataType: REG_DWORD
          • NodeUri: REG_SZ
          • Operation: REG_DWORD
          • VarType:REG_DWROD