Azure Stack HCI & WDAC

4 januari 2024

Laatste update: 3 februari 2024 om 12:54

Darryl van der Peijl


Tags:

Home » Blog » Azure Stack HCI & WDAC

 

Windows Defender Application Control (WDAC) is a software-based security layer that reduces attack surface by enforcing an explicit list of software that is allowed to run. WDAC is enabled by default on Azure Stack HCI and limits the applications and the code that you can run on the core platform.

An Application Control Policy has blocked this file

When running software that is not known or signed by Microsoft you can get the error message: “An Application Control Policy has blocked this file”.
Microsoft describes in their documentation how you can create your own WDAC policies here so that you can allow 3rd party software on your nodes.
For simplicity sake, we’ve created a Powershell script that helps you create additional policies.

It will go through the following steps:

1. Ask where to store the WDAC XML policy file
2. Ask what directory to scan for software
3. Ask information on the policy
4. Set policy metadata in the XML
5. Check if there is already an existing policy with the same name + ability to remove it
6. Add the policy as ‘SupplementalPolicy’

Find the script below, save it to a .ps1 file and run it on an Azure Stack HCI node.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
[System.Reflection.Assembly]::LoadWithPartialName('Microsoft.VisualBasic')
$PolicyFilePath = [Microsoft.VisualBasic.Interaction]::InputBox("Enter the filepath where the WDAC XML will be saved", "WDAC XML filepath", "C:\WDAC\policy.xml")
if ($PolicyFilePath -notmatch ".xml"){Write-Error "filepath must end with .xml" -ErrorAction Stop}
$FilesPath = [Microsoft.VisualBasic.Interaction]::InputBox("Enter the filepath where applications are places that will be scanned", "Software filepath", "C:\Software")
$policyVersion = [Microsoft.VisualBasic.Interaction]::InputBox("Enter the version of your policy", "Policy version", "1.0.0.0")
$policyName = [Microsoft.VisualBasic.Interaction]::InputBox("Enter the name of your policy. (no spaces)", "Policy name", "CustomPolicy")
$policyID = "$policyName"+"_"+"$policyVersion"

# Create new policy by scanning directory
Write-Output "Creating new policy by scanning directory $FilesPath"
New-CIPolicy -MultiplePolicyFormat -Level Publisher -FilePath $PolicyFilePath -UserPEs -Fallback Hash -ScanPath $FilesPath -ErrorAction Stop

if (!(Test-Path $PolicyFilePath)) {
Write-Error "$PolicyFilePath not created, did you provide a correct and existing path?" -ErrorAction Stop
}

# Output results
[xml]$policyxml = Get-Content -Path $PolicyFilePath
$signers = $policyxml.SiPolicy.Signers.Signer.CertPublisher.Value

# Set Policy Version (VersionEx in the XML file)
Set-CIPolicyVersion -FilePath $PolicyFilePath -Version $policyVersion

# Set Policy Info (PolicyName, PolicyID in the XML file)
Set-CIPolicyIdInfo -FilePath $PolicyFilePath -PolicyID $policyID -PolicyName $policyName

# Validate existing policy with same name
$existingPolicyCount = (Get-ASLocalWDACPolicyInfo | where {$_.policyname -eq $policyName}).count
If ($existingPolicyCount -gt 1){

$remove = [System.Windows.Forms.MessageBox]::Show("$policyName already exists $existingPolicyCount times. Do you want to remove all?","$policyName already exists", "YesNo" , "Warning" , "Button1")

if ($remove -eq "Yes"){

$policiesToRemove = (Get-ASLocalWDACPolicyInfo | where {$_.policyname -eq $policyName})
Foreach ($policiyToRemove in $policiesToRemove) {
Write-Output "Removing policy with Guid $($policiyToRemove.policyguid)"
remove-ASWDACSupplementalPolicy -PolicyGuid $policiyToRemove.policyguid
}
}
[System.Windows.Forms.MessageBox]::Show("Policies removed. Removing policies will take effect after you restart.","Restart required", "OK" , "Info" , "Button1")
}

# Add new policy
Add-ASWDACSupplementalPolicy -Path $PolicyFilePath
Write-Output "Policy created with signers: $signers"

If you have any questions, reach out!

Gerelateerde blogs