In part 1 of my blog, I explained step by step how to get started with application control in a simple way. In this part of my blog, I'm going to discuss how to use the company portal in Intune as a managed installer. The benefit of this is that you don't have to adjust the application control policies every time. There is one limitation though, that is only .EXE files can be installed, .MSI files are not supported.
The managed installer works as follows. When an application (.EXE) is downloaded and/or installed from the company portal, these files are tagged. The "tag" uses an NTFS feature called extended attributes to store that data. The managed installer is an implementation mix of Microsoft AppLocker settings & Windows Defender Application Control.
Read about the managed installer .EXE only: Allow apps deployed with a WDAC managed installer (Windows)
Application | Microsoft Defender Application Control (WDAC) |
Weblink |
Microsoft Endpoint Manager admin center |
Topic | Windows Defender Application Control - Intune |
After reading all the Microsoft documentation, I came across an article that it was possible to use managed installers. Unfortunately, the documentation is not very detailed and I had to rely on the Internet to figure it out myself. I even read on a blog that managed installer only works in conjunction with SCCM. So this is not the case, otherwise I would not write this blog.
WDAC Policy - Configure Policy Template | Windows Defender Application Control Wizard |
Powershell Script - Managed installer |
Local Machine PowerShell |
Intune Configuration - Intune PowerShell | Local Machine PowerShell |
Upload Powershell to Intune | Microsoft Endpoint Manager admin center |
Windows Event Log - Application Control events | Local Machine |
WDAC Policy - Disable Script Enforcement
Windows Defender Application control - App
Since Constrained Language is so limited the script I use to set everything up for the managed installer is blocked. The solution to this is simple: add these scripts (or better, your code signing authority that signed them) to your application control policy. This will allow your approved scripts to run in Full Language mode.
Below is the describe from the Microsoft website.
This option disables script enforcement options. Unsigned PowerShell scripts and interactive PowerShell are no longer restricted to Constrained Language Mode. NOTE: This option is required to run HTA files, and is only supported with the Windows 10 May 2019 Update (1903) and higher. Using it on earlier versions of Windows 10 is not supported and may have unintended results.
WDAC Policy - Managed installer
Windows Defender Application control - App
This option needs little explanation. Without turning this option on, the managed installer will not work.
Below is the describe from the Microsoft website.
Use this option to automatically allow applications installed by a software distribution solution, such as Microsoft Endpoint Configuration Manager, that has been defined as a managed installer.
Powershell Script - Managed installer
Local Machine PowerShell
The following components are integrated in this script.
Information from the Microsoft Website: Allow apps deployed with a WDAC managed installer (Windows)
param ( [switch] $CheckComplianceOnly = $False ) # Variables [System.Int32]$policyBinaryTimeoutSeconds = 300 [System.Int32]$waitBatchSeconds = 5 [System.Int32]$maxWaitSeconds = 300 [string]$miPolicyBinaryPathRoot = "$env:windir\System32" if(-not ([Environment]::Is64BitProcess)) { $miPolicyBinaryPathRoot = "$env:windir\Sysnative" } [string]$miPolicyBinaryPath = Join-Path -Path $miPolicyBinaryPathRoot -ChildPath "AppLocker\ManagedInstaller.AppLocker" [string]$SccmMiPolicy = @" <AppLockerPolicy Version="1"> <RuleCollection Type="Appx" EnforcementMode="NotConfigured" /> <RuleCollection Type="Dll" EnforcementMode="AuditOnly"> <FilePathRule Id="86f235ad-3f7b-4121-bc95-ea8bde3a5db5" Name="Dummy Rule" Description="Dummy Rule" UserOrGroupSid="S-1-1-0" Action="Deny"> <Conditions> <FilePathCondition Path="%OSDRIVE%\ThisWillBeBlocked.dll" /> </Conditions> </FilePathRule> <RuleCollectionExtensions> <ThresholdExtensions> <Services EnforcementMode="Enabled" /> </ThresholdExtensions> <RedstoneExtensions> <SystemApps Allow="Enabled" /> </RedstoneExtensions> </RuleCollectionExtensions> </RuleCollection> <RuleCollection Type="Exe" EnforcementMode="AuditOnly"> <FilePathRule Id="9420c496-046d-45ab-bd0e-455b2649e41e" Name="Dummy Rule" Description="Dummy Rule" UserOrGroupSid="S-1-1-0" Action="Deny"> <Conditions> <FilePathCondition Path="%OSDRIVE%\ThisWillBeBlocked.exe" /> </Conditions> </FilePathRule> <RuleCollectionExtensions> <ThresholdExtensions> <Services EnforcementMode="Enabled" /> </ThresholdExtensions> <RedstoneExtensions> <SystemApps Allow="Enabled" /> </RedstoneExtensions> </RuleCollectionExtensions> </RuleCollection> <RuleCollection Type="ManagedInstaller" EnforcementMode="Enabled"> <FilePublisherRule Id="70104ed1-5589-4f29-bb46-2692a86ec089" Name="MICROSOFT.MANAGEMENT.SERVICES.INTUNEWINDOWSAGENT.EXE version 1.39.200.2 or greater in MICROSOFT® INTUNE™ from O=MICROSOFT CORPORATION, L=REDMOND, S=WASHINGTON, C=US" Description="" UserOrGroupSid="S-1-1-0" Action="Allow"> <Conditions> <FilePublisherCondition PublisherName="O=MICROSOFT CORPORATION, L=REDMOND, S=WASHINGTON, C=US" ProductName="MICROSOFT® INTUNE™" BinaryName="MICROSOFT.MANAGEMENT.SERVICES.INTUNEWINDOWSAGENT.EXE"> <BinaryVersionRange LowSection="1.38.300.1" HighSection="*" /> </FilePublisherCondition> </Conditions> </FilePublisherRule> </RuleCollection> <RuleCollection Type="Msi" EnforcementMode="NotConfigured" /> <RuleCollection Type="Script" EnforcementMode="NotConfigured" /> </AppLockerPolicy> "@ function MergeAppLockerPolicy([string]$policyXml) { $policyFile = '.\AppLockerPolicy.xml' $policyXml | Out-File $policyFile Write-Host "Merging and setting AppLocker policy" Set-AppLockerPolicy -XmlPolicy $policyFile -Merge -ErrorAction SilentlyContinue Remove-Item $policyFile } function VerifyCompliance([xml]$policy) { $result = $false $miNode = $policy.AppLockerPolicy.ChildNodes | Where-Object{$_.Type -eq 'ManagedInstaller'} if(-not $miNode) { Write-Host('Policy does not contain any managed installers') } else { $ccmexecNode = $miNode.ChildNodes | Where-Object{($_.LocalName -eq 'FilePublisherRule') -and ($_.Name -eq 'MICROSOFT.MANAGEMENT.SERVICES.INTUNEWINDOWSAGENT.EXE version 1.39.200.2 or greater in MICROSOFT® INTUNE™ from O=MICROSOFT CORPORATION, L=REDMOND, S=WASHINGTON, C=US')} if(-not $ccmexecNode) { Write-Host('Policy does not have Intune managed installer policy.') } else { { $result = $true } } } return $result } # Execution flow starts here # Get and load the current effective AppLocker policy try { [xml]$effectivePolicyXml = Get-AppLockerPolicy -Effective -Xml -ErrorVariable ev -ErrorAction SilentlyContinue } catch { Write-Error('Get-AppLockerPolicy failed. ' + $_.Exception.Message) exit 10 } # Check if it contains MI policy and if the MI policy has rules for Intune try { $compliant = VerifyCompliance($effectivePolicyXml) } catch { Write-Error('Failed to verify AppLocker policy compliance. ' + $_.Exception.Message) exit 12 } if($compliant) { Write-Host("AppLocker policy is compliant") exit 0 } Write-Host("AppLocker policy is not compliant") if($CheckComplianceOnly) { exit 2 } # Start services Write-Host 'Starting services' [Diagnostics.Process]::Start("$env:windir\System32\sc.exe","start gpsvc") [Diagnostics.Process]::Start("$env:windir\System32\appidtel.exe","start -mionly") [System.Int32]$waitedSeconds = 0 # Check service state, wait up to 1 minute while($waitedSeconds -lt $maxWaitSeconds) { Start-Sleep -Seconds $waitBatchSeconds $waitedSeconds += $waitBatchSeconds if(-not ((Get-Service AppIDSvc).Status -eq 'Running')) { Write-Host 'AppID Service is not fully started yet.' continue } if(-not ((Get-Service appid).Status -eq 'Running')) { Write-Host 'AppId Driver Service is not fully started yet.' continue } if(-not ((Get-Service applockerfltr).Status -eq 'Running')) { Write-Host 'AppLocker Filter Driver Service is not fully started yet.' continue } break } if (-not ($waitedSeconds -lt $maxWaitSeconds)) { Write-Error 'Time-out on waiting for services to start.' exit 1 } # Set the policy try { MergeAppLockerPolicy($SccmMiPolicy) } catch { Write-Error('Failed to merge AppLocker policy. ' + $_.Exception.Message) exit 14 } # Wait for policy update if(test-path $miPolicyBinaryPath) { $previousPolicyBinaryTimeStamp = (Get-ChildItem $miPolicyBinaryPath).LastWriteTime Write-Host ('There is an existing ManagedInstaller policy binary (LastWriteTime: {0})' -f $previousPolicyBinaryTimeStamp.ToString('yyyy-MM-dd HH:mm')) } if($previousPolicyBinaryTimeStamp) { $action = 'updated' $condition = '$previousPolicyBinaryTimeStamp -lt (Get-ChildItem $miPolicyBinaryPath).LastWriteTime' } else { $action = 'created' $condition = 'test-path $miPolicyBinaryPath' } Write-Host "Waiting for policy binary to be $action" $startTime = get-date while(-not (Invoke-Expression $condition)) { Start-Sleep -Seconds $waitBatchSeconds if((new-timespan $startTime $(get-date)).TotalSeconds -ge $policyBinaryTimeoutSeconds) { Write-Error "Policy binary has not been $action within $policyBinaryTimeoutSeconds seconds" exit 1 } } Write-Host ('Policy binary was created after {0:mm} minutes {0:ss} seconds' -f (new-timespan $startTime $(get-date))) # Check compliance again try { [xml]$effectivePolicyXml = Get-AppLockerPolicy -Effective -Xml -ErrorVariable ev -ErrorAction SilentlyContinue } catch { Write-Error('Get-AppLockerPolicy failed. ' + $_.Exception.Message) exit 10 } # Check if it contains MI policy and if the MI policy has rules for Intune try { $compliant = VerifyCompliance($effectivePolicyXml) } catch { Write-Error('Failed to verify AppLocker policy compliance. ' + $_.Exception.Message) exit 12 } if($compliant -eq $false) { Write-Error("AppLocker policy is not compliant") exit 1 } Write-Host 'AppLocker with Managed Installer for Intune successfully enabled'
Intune Configuration - Intune PowerShell
PowerShell
Following the steps below you can add this PowerShell script to Intune
Information from the Microsoft Website: Allow apps deployed with a WDAC managed installer (Windows)
Windows Event Log - Application Control events
Events
I recommend activating the following event logs if not already done. For the managed installer, event log 3090 is of interest
reg add hklm\system\currentcontrolset\control\ci -v TestFlags -t REG_DWORD -d 0x100
reg add hklm\system\currentcontrolset\control\ci -v TestFlags -t REG_DWORD -d 0x300
For all information about the logs, I refer you to Microsoft: Understanding Application Control event IDs (Windows)
When you subscribe to the blog, we will send you an e-mail when there are new updates on the site so you wouldn't miss them.