14 KiB
title, description, ms.author, ms.topic, ms.prod, ms.technology, author, ms.reviewer, ms.date
title | description | ms.author | ms.topic | ms.prod | ms.technology | author | ms.reviewer | ms.date |
---|---|---|---|---|---|---|---|---|
ApplicationControl CSP | The ApplicationControl CSP allows you to manage multiple Windows Defender Application Control (WDAC) policies from an MDM server. | dansimp | article | w10 | windows | dansimp | jsuther1974 | 09/10/2020 |
ApplicationControl CSP
The table below shows the applicability of Windows:
Edition | Windows 10 | Windows 11 |
---|---|---|
Home | Yes | Yes |
Pro | Yes | Yes |
Windows SE | No | Yes |
Business | Yes | Yes |
Enterprise | Yes | Yes |
Education | Yes | Yes |
Windows Defender Application Control (WDAC) policies can be managed from an MDM server, or locally by using PowerShell via the WMI Bridge through the ApplicationControl configuration service provider (CSP). The ApplicationControl CSP was added in Windows 10, version 1903. This CSP provides expanded diagnostic capabilities and support for multiple policies (introduced in Windows 10, version 1903). It also provides support for rebootless policy deployment (introduced in Windows 10, version 1709). Unlike the AppLocker CSP, the ApplicationControl CSP correctly detects the presence of no-reboot option and consequently doesn't schedule a reboot.
Existing Windows Defender Application Control (WDAC) policies deployed using the AppLocker CSP's CodeIntegrity node can now be deployed using the ApplicationControl CSP URI. Although, WDAC policy deployment via the AppLocker CSP will continue to be supported, all new feature work will be done in the ApplicationControl CSP only.
The following example shows the ApplicationControl CSP in tree format.
./Vendor/MSFT
ApplicationControl
----Policies
--------Policy GUID
------------Policy
------------PolicyInfo
----------------Version
----------------IsEffective
----------------IsDeployed
----------------IsAuthorized
----------------Status
----------------FriendlyName
------------Token
----------------TokenID
----Tokens
--------ID
------------Token
------------TokenInfo
----------------Status
------------PolicyIDs
----------------Policy GUID
----TenantID
----DeviceID
./Vendor/MSFT/ApplicationControl
Defines the root node for the ApplicationControl CSP.
Scope is permanent. Supported operation is Get.
ApplicationControl/Policies
An interior node that contains all the policies, each identified by their globally unique identifier (GUID).
Scope is permanent. Supported operation is Get.
ApplicationControl/Policies/Policy GUID
The ApplicationControl CSP enforces that the "ID" segment of a given policy URI is the same GUID as the policy ID in the policy blob. Each Policy GUID node contains a Policy node and a corresponding PolicyInfo node.
Scope is dynamic. Supported operation is Get.
ApplicationControl/Policies/Policy GUID/Policy
This node is the policy binary itself, which is encoded as base64.
Scope is dynamic. Supported operations are Get, Add, Delete, and Replace.
Value type is b64. Supported value is a binary file, converted from the policy XML file by the ConvertFrom-CIPolicy cmdlet.
Default value is empty.
ApplicationControl/Policies/Policy GUID/PolicyInfo
An interior node that contains the nodes that describe the policy indicated by the GUID.
Scope is dynamic. Supported operation is Get.
ApplicationControl/Policies/Policy GUID/PolicyInfo/Version
This node provides the version of the policy indicated by the GUID. Stored as a string, but when parsing uses a uint64 as the containing data type.
Scope is dynamic. Supported operation is Get.
Value type is char.
ApplicationControl/Policies/Policy GUID/PolicyInfo/IsEffective
This node specifies whether a policy is loaded by the enforcement engine and is in effect on a system.
Scope is dynamic. Supported operation is Get.
Value type is bool. Supported values are as follows:
- True—Indicates that the policy is loaded by the enforcement engine and is in effect on a system.
- False—Indicates that the policy isn't loaded by the enforcement engine and isn't in effect on a system. This value is the default value.
ApplicationControl/Policies/Policy GUID/PolicyInfo/IsDeployed
This node specifies whether a policy is deployed on the system and is present on the physical machine.
Scope is dynamic. Supported operation is Get.
Value type is bool. Supported values are as follows:
- True—Indicates that the policy is deployed on the system and is present on the physical machine.
- False—Indicates that the policy isn't deployed on the system and isn't present on the physical machine. This value is the default value.
ApplicationControl/Policies/Policy GUID/PolicyInfo/IsAuthorized
This node specifies whether the policy is authorized to be loaded by the enforcement engine on the system. If not authorized, a policy can't take effect on the system.
Scope is dynamic. Supported operation is Get.
Value type is bool. Supported values are as follows:
- True—Indicates that the policy is authorized to be loaded by the enforcement engine on the system.
- False—Indicates that the policy isn't authorized to be loaded by the enforcement engine on the system. This value is the default value.
The following table provides the result of this policy based on different values of IsAuthorized, IsDeployed, and IsEffective nodes:
IsAuthorized | IsDeployed | IsEffective | Resultant |
---|---|---|---|
True | True | True | Policy is currently running and is in effect. |
True | True | False | Policy requires a reboot to take effect. |
True | False | True | Policy requires a reboot to unload from CI. |
False | True | True | Not Reachable. |
True | False | False | *Not Reachable. |
False | True | False | *Not Reachable. |
False | False | True | Not Reachable. |
False | False | False | *Not Reachable. |
* denotes a valid intermediary state; however, if an MDM transaction results in this state configuration, the END_COMMAND_PROCESSING
will result in a fail.
ApplicationControl/Policies/Policy GUID/PolicyInfo/Status
This node specifies whether the deployment of the policy indicated by the GUID was successful.
Scope is dynamic. Supported operation is Get.
Value type is integer. Default value is 0 = OK.
ApplicationControl/Policies/Policy GUID/PolicyInfo/FriendlyName
This node provides the friendly name of the policy indicated by the policy GUID.
Scope is dynamic. Supported operation is Get.
Value type is char.
Microsoft Endpoint Manager Intune Usage Guidance
For customers using Intune standalone or hybrid management with Microsoft Endpoint Configuration Manager to deploy custom policies via the ApplicationControl CSP, refer to Deploy Windows Defender Application Control policies by using Microsoft Intune.
Generic MDM Server Usage Guidance
In order to use the ApplicationControl CSP without using Intune, you must:
- Know a generated policy's GUID, which can be found in the policy xml as
<PolicyID>
or<PolicyTypeID>
for pre-1903 systems. - Convert the policies to binary format using the
ConvertFrom-CIPolicy
cmdlet in order to be deployed. The binary policy may be signed or unsigned. - Create a policy node (a Base64-encoded blob of the binary policy representation) using the
certutil -encode
command-line tool.
Below is a sample certutil invocation:
certutil -encode WinSiPolicy.p7b WinSiPolicy.cer
An alternative to using certutil would be to use the following PowerShell invocation:
[Convert]::toBase64String($(Get-Content -Encoding Byte -ReadCount 0 -Path <bin file>))
Deploy Policies
To deploy a new base policy using the CSP, perform an ADD on ./Vendor/MSFT/ApplicationControl/Policies/Policy GUID/Policy using the Base64-encoded policy node as {Data}. Refer to the Format section in the Example 1 below.
To deploy base policy and supplemental policies:
- Perform an ADD on ./Vendor/MSFT/ApplicationControl/Policies/Policy GUID/Policy using the Base64-encoded policy node as {Data} with the GUID and policy data for the base policy.
- Repeat for each base or supplemental policy (with its own GUID and data).
The following example shows the deployment of two base policies and a supplemental policy (which already specifies the base policy it supplements and doesn't need that reflected in the ADD).
Example 1: Add first base policy
<Add>
<CmdID>1</CmdID>
<Item>
<Target>
<LocURI>./Vendor/MSFT/ApplicationControl/Policies/{Base1GUID}/Policy</LocURI>
</Target>
<Meta>
<Format xmlns="syncml:metinf">b64</Format>
</Meta>
<Data> {Base1Data} </Data>
</Item>
</Add>
Example 2: Add second base policy
<Add>
<CmdID>1</CmdID>
<Item>
<Target>
<LocURI>./Vendor/MSFT/ApplicationControl/Policies/{Base2GUID}/Policy</LocURI>
</Target>
<Meta>
<Format xmlns="syncml:metinf">b64</Format>
</Meta>
<Data> {Base2Data} </Data>
</Item>
</Add>
Example 3: Add supplemental policy
<Add>
<CmdID>1</CmdID>
<Item>
<Target>
<LocURI>./Vendor/MSFT/ApplicationControl/Policies/{Supplemental1GUID}/Policy</LocURI>
</Target>
<Meta>
<Format xmlns="syncml:metinf">b64</Format>
</Meta>
<Data> {Supplemental1Data} </Data>
</Item>
</Add>
Get policies
Perform a GET using a deployed policy's GUID to interrogate/inspect the policy itself or information about it.
The following table displays the result of Get operation on different nodes:
Nodes | Get Results |
---|---|
./Vendor/MSFT/ApplicationControl/Policies/Policy GUID/Policy | raw p7b |
./Vendor/MSFT/ApplicationControl/Policies/Policy GUID/PolicyInfo/Version | Policy version |
./Vendor/MSFT/ApplicationControl/Policies/Policy GUID/PolicyInfo/IsEffective | Is the policy in effect |
./Vendor/MSFT/ApplicationControl/Policies/Policy GUID/PolicyInfo/IsDeployed | Is the policy on the system |
./Vendor/MSFT/ApplicationControl/Policies/Policy GUID/PolicyInfo/IsAuthorized | Is the policy authorized on the system |
./Vendor/MSFT/ApplicationControl/Policies/Policy GUID/PolicyInfo/Status | Was the deployment successful |
./Vendor/MSFT/ApplicationControl/Policies/Policy GUID/PolicyInfo/FriendlyName | Friendly name per the policy |
An example of Get command is:
<Get>
<CmdID>1</CmdID>
<Item>
<Target>
<LocURI>./Vendor/MSFT/ApplicationControl/Policies/{PolicyGUID}/Policy</LocURI>
</Target>
</Item>
</Get>
Delete policies
Rebootless Deletion
Upon deletion, policies deployed via the ApplicationControl CSP are removed from the system but stay in effect until the next reboot. In order to functionally do a rebootless delete, first replace the existing policy with an Allow All policy (found at C:\Windows\schemas\CodeIntegrity\ExamplePolicies\AllowAll.xml) and then delete the updated policy. This sequence will immediately prevent anything from being blocked and fully deactive the policy on the next reboot.
Unsigned Policies
To delete an unsigned policy, perform a DELETE on ./Vendor/MSFT/ApplicationControl/Policies/Policy GUID/Policy.
Signed Policies
Note
A signed policy by default can only be replaced by another signed policy. Hence, performing a DELETE on ./Vendor/MSFT/ApplicationControl/Policies/Policy GUID/Policy isn't sufficient to delete a signed policy.
To delete a signed policy:
- Replace it with a signed update allowing unsigned policy.
- Deploy another update with unsigned Allow All policy.
- Perform delete.
An example of Delete command is:
<Delete>
<CmdID>1</CmdID>
<Item>
<Target>
<LocURI>./Vendor/MSFT/ApplicationControl/Policies/{PolicyGUID}/Policy</LocURI>
</Target>
</Item>
</Delete>
PowerShell and WMI Bridge Usage Guidance
The ApplicationControl CSP can also be managed locally from PowerShell or via Configuration Manager's task sequence scripting by using the WMI Bridge Provider.
Setup for using the WMI Bridge
-
Convert your WDAC policy to Base64.
-
Open PowerShell in Local System context (through PSExec or something similar).
-
Use WMI Interface:
$namespace = "root\cimv2\mdm\dmmap" $policyClassName = "MDM_AppControl_Policies" $policyBase64 = …
Deploying a policy via WMI Bridge
Run the following command. PolicyID is a GUID that can be found in the policy xml, and should be used here without braces.
New-CimInstance -Namespace $namespace -ClassName $policyClassName -Property @{ParentID="./Vendor/MSFT/ApplicationControl/Policies";InstanceID="<PolicyID>";Policy=$policyBase64}
Querying all policies via WMI Bridge
Get-CimInstance -Namespace $namespace -ClassName $policyClassName