-
Notifications
You must be signed in to change notification settings - Fork 176
AppControl Manager
AppControl Manager is a modern secure app that provides easy to use graphical user interface to manage App Control and Code Integrity on your device.
⚡What is App Control? Check Out This Article ⚡
Important
The AppControl Manager application is built publicly using a GitHub Workflow and uploaded to the GitHub release. The action uses Artifact Attestation and SBOM (Software Bill of Materials) generation to comply with the highest security standards such as SLSA level 3. The source code as well as the package is uploaded to Virus Total automatically. Also GitHub's CodeQL Advanced workflow with extended security model scans the entire repository.
Use the following PowerShell command as Admin, it will automatically download the latest MSIXBundle file from this repository's release page and install it for you.
(irm 'https://raw.githubusercontent.com/HotCakeX/Harden-Windows-Security/main/Harden-Windows-Security.ps1')+'AppControl'|iex
Please feel free to open a discussion if you have any questions about the build process, security, how to use or have feedbacks. Source code on this repository
- Windows 11 24H2
- Windows 11 23H2
- Windows 11 22H2
- Windows Server 2025
- Secure and transparent development and build process.
- Built using WinUI3 / XAML / C#.
- Built using the latest .NET.
- Powered by the WinAppSDK (formerly Project Reunion).
- Packaged with the modern MSIX format.
- Incorporates the Mica material design for backgrounds.
- Adopts the Windows 11 Fluent design system.
- Fast execution and startup time.
- 0 required dependency.
- 0 Third-party library or file used.
- 0 Telemetry or data collection.
- 0 Windows Registry changes.
- 100% clean uninstallation.
- 100% open-source and free to use.
- Natively supports X64 and ARM64 architectures.
-
Create AppControl Policy
-
Create Supplemental Policy
-
System Information
-
Configure Policy Rule Options
-
Simulation
-
Allow New Apps
-
Build New Certificate
-
Create Policy From Event Logs
-
Create Policy From MDE Advanced Hunting
-
Create Deny Policy
-
Merge App Control Policies
-
Deploy App Control Policy
-
Get Code Integrity Hashes
-
Get Secure Policy Settings
-
Update
-
Sidebar
-
Validate Policies
-
View File Certificates
More features will come very quickly in the near future.
Security is paramount when selecting any application designed to safeguard your systems. The last thing you want is a security-focused tool that inadvertently expands your attack surface or one that doesn't prioritize security at its core.
AppControl Manager is engineered with a security-first approach from the ground up. It's crafted specifically for defense teams, yet its design has been rigorously shaped with a keen awareness of potential offensive strategies, ensuring resilience against emerging threats.
-
The AppControl Manager does not rely on any 3rd party component or dependency. All the logics are built securely and specifically for the app.
-
Any file(s) the AppControl Manager ever produces, uses or expects is only from an Administrator-protected location in
C:\Program Files\WDACConfig
. -
The AppControl Manager supports process mitigations / Exploit Protections such as:
Blocking low integrity images
,Blocking remote images
,Blocking untrusted fonts
,Disabling extension points
,Export Address Filtering
,Hardware enforced stack protection
,Import Address Filtering
,Validate handle usage
,Validate stack integrity
and so on. -
The AppControl Manager always uses the latest .NET and SDK versions, ensuring all the security patches released by Microsoft will be included.
-
The entire codebase is thoroughly commented, allowing code reviewers to effortlessly examine and verify every aspect of AppControl Manager's source code.
-
AppControl Manager leverages MSAL from Microsoft to manage Microsoft 365 authentications. This industry-standard library adheres to best practices for secure authentication token management.
-
AppControl Manager operates exclusively within the "WDACConfig" directory located in the
Program Files
directory for all read and write operations. No data is accessed or modified outside this directory. This design ensures that non-elevated processes, unauthorized software, or unprivileged malware on the system cannot alter the policies you create, the certificates you generate, or the CIP binary files you deploy. -
AppControl Manager employs MediumIL (Medium Integrity Level) when running as an Administrator, ensuring that non-elevated processes cannot access its memory or attach debuggers. Given that the app handles sensitive information—such as Microsoft 365 authentication tokens stored in private variables—this design decision safeguards these tokens from unauthorized, unelevated access or tampering.
-
Administrator privileges are required for scanning Code Integrity and AppLocker logs. These scans are integral to several application functions, providing enhanced insights and enabling the generation of precise supplemental policies tailored to your needs.
-
Deploying, removing, modifying, or checking the status of policies also necessitates Administrator privileges to ensure secure and reliable execution of these operations.
The Temporary Files Are Stored in the Following Directory
C:\Program Files\WDACConfig\StagingArea
Each applicable feature of the AppControl Manager that you start using will generate a uniquely named subdirectory within the StagingArea to store its temporary files (if needed). Upon closing the application, the entire StagingArea directory, along with its contents, will be automatically deleted. These files are utilized by the application for tasks such as creating policies, storing temporary scan results, and other related functions.
The installation process for AppControl Manager is uniquely streamlined. When you execute the PowerShell one-liner command mentioned above, it initiates a file containing the AppControl
function, which serves as the bootstrapper script. This script is thoroughly documented, with detailed explanations and justifications for each step, as outlined below:
-
The latest version of the AppControl Manager MSIXBundle package is securely downloaded from the GitHub release page, where it is built publicly with full artifact attestation and SBOMs.
-
The
SignTool.exe
utility is sourced directly from Microsoft by retrieving the associated Nuget package, ensuring a trusted origin. -
A secure, on-device code-signing certificate is then generated. This certificate, managed by the Microsoft-signed
SignTool.exe
, is used to sign the MSIXBundle package obtained from GitHub. -
The private key of the certificate is non-exportable, never written on the disk and is securely discarded once signing is complete, leaving only the public key on the device to allow AppControl Manager to function properly on the system and prevent the certificate from being able to sign anything else.
-
The entire process is designed to leave no residual files. Each time the script runs, any certificates from previous executions are detected and removed, ensuring a clean system.
-
Finally, the
AppControlManager.dll
andAppControlManager.exe
files are added to the Attack Surface Reduction (ASR) exclusions to prevent ASR rules from blocking these newly released binaries. Previous version exclusions are also removed from the ASRs exclusions list to maintain a clean, streamlined setup for the user.
Here is the complete list of all of the URLs the AppControl Manager application connects to (or is mentioned in the User Interface) with proper justification for each of them.
URL | Justification |
---|---|
https://api.nuget.org/v3-flatcontainer/ | To access Microsoft NuGet repository to download SignTool.exe |
https://aka.ms/VulnerableDriverBlockList | To download the Microsoft Recommended Drivers Block List |
https://api.github.com/repos/MicrosoftDocs/windows-itpro-docs/commits | To check the latest commit details of the Microsoft Recommended Drivers Block List and display them to the user on the UI |
https://raw.githubusercontent.com/MicrosoftDocs/windows-itpro-docs/refs/heads/public/windows/security/application-security/application-control/app-control-for-business/design/applications-that-can-bypass-appcontrol.md | Source for the Microsoft Recommended User-Mode Block Rules |
https://raw.githubusercontent.com/MicrosoftDocs/windows-itpro-docs/refs/heads/public/windows/security/application-security/application-control/app-control-for-business/design/microsoft-recommended-driver-block-rules.md | Source for the Microsoft Recommended Drivers Block Rules |
https://raw.githubusercontent.com/HotCakeX/Harden-Windows-Security/refs/heads/main/AppControl%20Manager/MSIXBundleDownloadURL.txt | The file on this repository that contains the download link to the latest version of the AppControl Manager. That text file is updated via automated GitHub action workflow that securely builds and uploads the MSIXBundle package to the GitHub releases. |
https://raw.githubusercontent.com/HotCakeX/Harden-Windows-Security/refs/heads/main/AppControl%20Manager/version.txt | The latest available version of the AppControl Manager application. That text file is updated via automated GitHub action workflow that securely builds and uploads the MSIXBundle package to the GitHub releases. |
https://github.com/HotCakeX/Harden-Windows-Security/wiki/Introduction | The link that opens in the GitHub documentations page in the app via the built-in WebView 2 |
https://learn.microsoft.com/en-us/windows/security/application-security/application-control/app-control-for-business/appcontrol | The link that opens in the Microsoft documentations page in the app via the built-in WebView 2 |
https://github.com/HotCakeX/Harden-Windows-Security/releases | During the update process, this link that is for the GitHub releases will be displayed on the update page as a quick way to read the release notes |
https://github.com/HotCakeX/Harden-Windows-Security/wiki/AppControl-Manager | Will be displayed on the Update page when a new version is available and being downloaded |
https://github.com/HotCakeX/Harden-Windows-Security/issues/new/choose | Link for the "Send Feedback" button at the bottom of the about section in settings |
https://github.com/HotCakeX/Harden-Windows-Security | Mentioned in the Links section at the bottom of the About section in Settings |
https://github.com/HotCakeX/Harden-Windows-Security/wiki/AppControl-Manager | Mentioned in the Links section at the bottom of the About section in Settings |
https://spynetgirl.github.io/ | Mentioned in the Links section at the bottom of the About section in Settings |
https://www.youtube.com/@hotcakex | Mentioned in the Links section at the bottom of the About section in Settings |
https://x.com/CyberCakeX | Mentioned in the Links section at the bottom of the About section in Settings |
https://icons8.com | Mentioned in the Links section at the bottom of the About section in Settings as credit |
https://graph.microsoft.com | Used when signing into your Azure tenant for uploading policies to Intune |
-
Download this PowerShell script.
-
Have
SignTool.exe
. You can find it in here if you don't already have it. -
Download the latest MSIXBundle package of the AppControl Manager from the GitHub releases or build it from the source code yourself.
-
Start an elevated PowerShell and import the script file via
Import-Module "Path to script file"
. -
Use the following syntax to Install the AppControl Manager
AppControl -MSIXBundlePath "Path To the MSIXBundle" -SignTool "Path to signtool.exe" -Verbose
- Q: Why isn't AppControl Manager on Microsoft Store?
- A: Because Microsoft Store currently does not accept apps that require Administrator privileges to run (i.e., MediumIL).
-
Q: Why isn't the MSIXBundle pre-signed?
-
A: Because I haven't started paying for a code-signing certificate yet. Read more about signing.
- To truly trust an application, you should review its code and bless it yourself.
You can build the AppControl Manager application directly from the source code locally on your device without using any 3rd party tools in a completely automated way.
It will create the MSIXBundle file containing the X64 and ARM64 MSIX packages. You can even optionally chain it with the Bootstrapper script to sign and install the application on your system at the end.
The build process will generate complete log files and you can use the MSBuild Structured Log Viewer to inspect them.
✨ Click/Tap here to see the PowerShell code ✨
# Requires -Version 5.1
# Requires -RunAsAdministrator
$global:ErrorActionPreference = 'Stop'
# Start the stopwatch
$Stopwatch = [System.Diagnostics.Stopwatch]::StartNew()
# Install Winget if it doesn't exist
if (!(Get-Command -Name 'winget.exe' -ErrorAction Ignore)) {
# Retrieve the latest Winget release information
$WingetReleases = Invoke-RestMethod -Uri 'https://api.github.com/repos/microsoft/winget-cli/releases'
$LatestRelease = $WingetReleases | Select-Object -First 1
# Direct links to the latest Winget release assets
[string]$WingetURL = $LatestRelease.assets.browser_download_url | Where-Object -FilterScript { $_.EndsWith('.msixbundle') } | Select-Object -First 1
[string]$WingetLicense = $LatestRelease.assets.browser_download_url | Where-Object -FilterScript { $_.EndsWith('License1.xml') } | Select-Object -First 1
[string]$LatestWingetReleaseDependenciesZipURL = $LatestRelease.assets.browser_download_url | Where-Object -FilterScript { $_.EndsWith('DesktopAppInstaller_Dependencies.zip') } | Select-Object -First 1
[hashtable]$Downloads = @{
# 'Winget.msixbundle' = 'https://aka.ms/getwinget' This is updated slower than the GitHub release
'DesktopAppInstaller_Dependencies.zip' = $LatestWingetReleaseDependenciesZipURL
'Winget.msixbundle' = $WingetURL
'License1.xml' = $WingetLicense
}
$Downloads.GetEnumerator() | ForEach-Object -Parallel {
Invoke-RestMethod -Uri $_.Value -OutFile $_.Key
}
Expand-Archive -Path 'DesktopAppInstaller_Dependencies.zip' -DestinationPath .\ -Force
# Get the paths to all of the dependencies
[string[]]$DependencyPaths = (Get-ChildItem -Path .\x64 -Filter '*.appx' -File -Force).FullName
Add-AppxProvisionedPackage -Online -PackagePath 'Winget.msixbundle' -DependencyPackagePath $DependencyPaths -LicensePath 'License1.xml'
Add-AppPackage -Path 'Winget.msixbundle' -DependencyPath "$($DependencyPaths[0])", "$($DependencyPaths[1])" -ForceTargetApplicationShutdown -ForceUpdateFromAnyVersion
}
[System.String]$BranchName = "main"
[System.String]$RepoName = "Harden-Windows-Security"
[System.String]$RepoUrl = "https://github.com/HotCakeX/$RepoName/archive/refs/heads/$BranchName.zip"
[System.String]$ZipPath = [System.IO.Path]::Combine($env:TEMP, "$RepoName.zip")
[System.String]$InitialWorkingDirectory = $PWD
Invoke-WebRequest -Uri $RepoUrl -OutFile $ZipPath
Expand-Archive -Path $ZipPath -DestinationPath $InitialWorkingDirectory -Force
Remove-Item -Path $ZipPath -Force
[System.String]$AppControlManagerDirectory = [System.IO.Path]::Combine($InitialWorkingDirectory, "$RepoName-$BranchName", 'AppControl Manager')
Set-Location -Path $AppControlManagerDirectory
winget source update
winget install --id Microsoft.DotNet.SDK.9 --exact --accept-package-agreements --accept-source-agreements --uninstall-previous --force --source winget
if ($LASTEXITCODE -ne 0) { throw [System.InvalidOperationException]::New('Failed to install .NET SDK') }
# Downloads the online installer and automatically runs it and installs the build tools
# https://learn.microsoft.com/en-us/windows/apps/windows-app-sdk/set-up-your-development-environment
# https://learn.microsoft.com/en-us/visualstudio/install/workload-component-id-vs-build-tools
# https://learn.microsoft.com/en-us/visualstudio/install/use-command-line-parameters-to-install-visual-studio
# https://learn.microsoft.com/en-us/visualstudio/install/workload-component-id-vs-community
winget install --id Microsoft.VisualStudio.2022.BuildTools --exact --accept-package-agreements --accept-source-agreements --uninstall-previous --force --source winget --override '--force --wait --passive --add Microsoft.VisualStudio.Workload.ManagedDesktop --add Microsoft.VisualStudio.Workload.VCTools --add Microsoft.VisualStudio.Workload.MSBuildTools --add Microsoft.VisualStudio.Workload.UniversalBuildTools --add Microsoft.VisualStudio.ComponentGroup.WindowsAppSDK.Cs --add Microsoft.VisualStudio.Component.VC.Tools.x86.x64 --add Microsoft.VisualStudio.Component.VC.v141.x86.x64 --add Microsoft.VisualStudio.Component.Windows11SDK.26100 --includeRecommended'
if ($LASTEXITCODE -ne 0) { throw [System.InvalidOperationException]::New('Failed to install Visual Studio Build Tools') }
winget install --id Microsoft.VCRedist.2015+.x64 --exact --accept-package-agreements --accept-source-agreements --uninstall-previous --force --source winget
# Refresh the environment variables so the current session detects the new dotnet installation
$Env:Path = [System.Environment]::GetEnvironmentVariable('Path', [System.EnvironmentVariableTarget]::Machine) + ';' +
[System.Environment]::GetEnvironmentVariable('Path', [System.EnvironmentVariableTarget]::User)
Write-Host -Object "`nChecking .NET info`n`n" -ForegroundColor Magenta
dotnet --info
Write-Host -Object "`nListing installed .NET SDKs`n`n" -ForegroundColor Magenta
dotnet --list-sdks
Function Find-mspdbcmf {
# "-products *" is necessary to detect BuildTools too
[string]$VisualStudioPath = . 'C:\Program Files (x86)\Microsoft Visual Studio\Installer\vswhere.exe' -prerelease -latest -property resolvedInstallationPath -products *
[string]$BasePath = [System.IO.Path]::Combine($VisualStudioPath, 'VC', 'Tools', 'MSVC')
# Get all subdirectories under the base path
[System.String[]]$VersionDirs = [System.IO.Directory]::GetDirectories($BasePath)
# Initialize the highest version with a minimal version value.
[System.Version]$HighestVersion = [System.Version]::New('0.0.0.0')
[System.String]$HighestVersionFolder = $null
# Loop through each directory to find the highest version folder.
foreach ($Dir in $VersionDirs) {
# Extract the folder name
[System.String]$FolderName = [System.IO.Path]::GetFileName($Dir)
[System.Version]$CurrentVersion = $null
# Try parsing the folder name as a Version.
if ([System.Version]::TryParse($FolderName, [ref] $CurrentVersion)) {
# Compare versions
if ($CurrentVersion.CompareTo($HighestVersion) -gt 0) {
$HighestVersion = $CurrentVersion
$HighestVersionFolder = $FolderName
}
}
}
# If no valid version folder is found
if (!$HighestVersionFolder) {
throw [System.IO.DirectoryNotFoundException]::New("No valid version directories found in $BasePath")
}
# Combine the base path, the highest version folder, the architecture folder, and the file name.
[System.String]$mspdbcmfPath = [System.IO.Path]::Combine($BasePath, $HighestVersionFolder, 'bin', 'Hostx64', 'x64', 'mspdbcmf.exe')
if (![System.IO.File]::Exists($mspdbcmfPath)) {
throw [System.IO.FileNotFoundException]::New("mspdbcmf.exe not found at $mspdbcmfPath")
}
return $mspdbcmfPath
}
[string]$mspdbcmfPath = Find-mspdbcmf
# https://github.com/Microsoft/vswhere/wiki/Start-Developer-Command-Prompt#using-powershell
$installationPath = . 'C:\Program Files (x86)\Microsoft Visual Studio\Installer\vswhere.exe' -prerelease -latest -property installationPath
if ($installationPath -and (Test-Path -Path "$installationPath\Common7\Tools\vsdevcmd.bat" -PathType Leaf)) {
& "${env:COMSPEC}" /s /c "`"$installationPath\Common7\Tools\vsdevcmd.bat`" -no_logo && set" | ForEach-Object -Process {
$name, $value = $_ -split '=', 2
Set-Content -Path env:\"$name" -Value $value -Force
Write-Host -Object "Setting environment variable: $name=$value"
}
}
# https://learn.microsoft.com/en-us/dotnet/core/tools/dotnet-build
# https://learn.microsoft.com/en-us/visualstudio/msbuild/msbuild-command-line-reference
# https://learn.microsoft.com/en-us/visualstudio/msbuild/common-msbuild-project-properties
# Generate for X64 architecture
dotnet build 'AppControl Manager.sln' --configuration Release --verbosity minimal /p:Platform=x64
dotnet msbuild 'AppControl Manager.sln' /p:Configuration=Release /p:AppxPackageDir="MSIXOutputX64\" /p:GenerateAppxPackageOnBuild=true /p:Platform=x64 -v:minimal /p:MsPdbCmfExeFullpath=$mspdbcmfPath -bl:X64MSBuildLog.binlog
# Generate for ARM64 architecture
dotnet build 'AppControl Manager.sln' --configuration Release --verbosity minimal /p:Platform=ARM64
dotnet msbuild 'AppControl Manager.sln' /p:Configuration=Release /p:AppxPackageDir="MSIXOutputARM64\" /p:GenerateAppxPackageOnBuild=true /p:Platform=ARM64 -v:minimal /p:MsPdbCmfExeFullpath=$mspdbcmfPath -bl:ARM64MSBuildLog.binlog
Function Get-MSIXFile {
Param(
[System.String]$BasePath,
[System.String]$FolderPattern,
[System.String]$FileNamePattern,
[System.String]$ErrorMessageFolder,
[System.String]$ErrorMessageFile
)
# Get all subdirectories in the base path matching the folder pattern
[System.String[]]$Folders = [System.IO.Directory]::GetDirectories($BasePath)
[System.String]$DetectedFolder = $null
foreach ($Folder in $Folders) {
if ([System.Text.RegularExpressions.Regex]::IsMatch($Folder, $FolderPattern)) {
$DetectedFolder = $Folder
break
}
}
if (!$DetectedFolder) {
Throw [System.InvalidOperationException]::New($ErrorMessageFolder)
}
# Get the full path of the first file matching the file name pattern inside the found folder
[System.String[]]$Files = [System.IO.Directory]::GetFiles($DetectedFolder)
[System.String]$DetectedFile = $null
foreach ($File in $Files) {
if ([System.Text.RegularExpressions.Regex]::IsMatch($File, $FileNamePattern)) {
$DetectedFile = $File
break
}
}
if (!$DetectedFile) {
Throw [System.InvalidOperationException]::New($ErrorMessageFile)
}
return $DetectedFile
}
#region Finding X64 outputs
[System.String]$FinalMSIXX64Path = Get-MSIXFile -BasePath ([System.IO.Path]::Combine($PWD.Path, 'MSIXOutputX64')) -FolderPattern 'AppControl Manager_\d+\.\d+\.\d+\.\d+_Test' -FileNamePattern 'AppControl Manager_\d+\.\d+\.\d+\.\d+_x64\.msix' -ErrorMessageFolder 'Could not find the directory for X64 MSIX file' -ErrorMessageFile 'Could not find the X64 MSIX file'
[System.String]$FinalMSIXX64Name = [System.IO.Path]::GetFileName($FinalMSIXX64Path)
[System.String]$FinalMSIXX64SymbolPath = Get-MSIXFile -BasePath ([System.IO.Path]::Combine($PWD.Path, 'MSIXOutputX64')) -FolderPattern 'AppControl Manager_\d+\.\d+\.\d+\.\d+_Test' -FileNamePattern 'AppControl Manager_\d+\.\d+\.\d+\.\d+_x64\.msixsym' -ErrorMessageFolder 'Could not find the directory for X64 symbol file' -ErrorMessageFile 'Could not find the X64 symbol file'
#endregion
#region Finding ARM64 outputs
[System.String]$FinalMSIXARM64Path = Get-MSIXFile -BasePath ([System.IO.Path]::Combine($PWD.Path, 'MSIXOutputARM64')) -FolderPattern 'AppControl Manager_\d+\.\d+\.\d+\.\d+_Test' -FileNamePattern 'AppControl Manager_\d+\.\d+\.\d+\.\d+_arm64\.msix' -ErrorMessageFolder 'Could not find the directory for ARM64 MSIX file' -ErrorMessageFile 'Could not find the ARM64 MSIX file'
[System.String]$FinalMSIXARM64Name = [System.IO.Path]::GetFileName($FinalMSIXARM64Path)
[System.String]$FinalMSIXARM64SymbolPath = Get-MSIXFile -BasePath ([System.IO.Path]::Combine($PWD.Path, 'MSIXOutputARM64')) -FolderPattern 'AppControl Manager_\d+\.\d+\.\d+\.\d+_Test' -FileNamePattern 'AppControl Manager_\d+\.\d+\.\d+\.\d+_arm64\.msixsym' -ErrorMessageFolder 'Could not find the directory for ARM64 symbol file' -ErrorMessageFile 'Could not find the ARM64 symbol file'
#endregion
#region Detect and Validate File Versions
[System.Text.RegularExpressions.Regex]$versionRegexX64 = [System.Text.RegularExpressions.Regex]::New('AppControl Manager_(\d+\.\d+\.\d+\.\d+)_x64\.msix')
[System.Text.RegularExpressions.Regex]$versionRegexARM64 = [System.Text.RegularExpressions.Regex]::New('AppControl Manager_(\d+\.\d+\.\d+\.\d+)_arm64\.msix')
[System.Text.RegularExpressions.Match]$MatchX64 = $versionRegexX64.Match($FinalMSIXX64Name)
[System.Text.RegularExpressions.Match]$MatchARM64 = $versionRegexARM64.Match($FinalMSIXARM64Name)
if (!$MatchX64.Success) {
Throw [System.InvalidOperationException]::New('Could not detect version from X64 file name')
}
if (!$MatchARM64.Success) {
Throw [System.InvalidOperationException]::New('Could not detect version from ARM64 file name')
}
[System.String]$versionX64 = $MatchX64.Groups[1].Value
[System.String]$versionARM64 = $MatchARM64.Groups[1].Value
if ($versionX64 -ne $versionARM64) {
Throw [System.InvalidOperationException]::New('The versions in X64 and ARM64 files do not match')
}
# Craft the file name for the MSIX Bundle file
[System.String]$FinalBundleFileName = "AppControl Manager_$versionX64.msixbundle"
#endregion
# Creating the directory where the MSIX packages will be copied to
[System.String]$MSIXBundleOutput = [System.IO.Directory]::CreateDirectory([System.IO.Path]::Combine($AppControlManagerDirectory, 'MSIXBundleOutput')).FullName
[System.IO.File]::Copy($FinalMSIXX64Path, [System.IO.Path]::Combine($MSIXBundleOutput, $FinalMSIXX64Name), $true)
[System.IO.File]::Copy($FinalMSIXARM64Path, [System.IO.Path]::Combine($MSIXBundleOutput, $FinalMSIXARM64Name), $true)
# The path to the final MSIX Bundle file
[System.String]$MSIXBundle = [System.IO.Path]::Combine($MSIXBundleOutput, $FinalBundleFileName)
Function Get-MakeAppxPath {
[System.String]$BasePath = 'C:\Program Files (x86)\Windows Kits\10\bin'
# Get all subdirectories under the base path
[System.String[]]$VersionDirs = [System.IO.Directory]::GetDirectories($BasePath)
# Initialize the highest version with a minimal version value.
[System.Version]$HighestVersion = [System.Version]::New('0.0.0.0')
[System.String]$HighestVersionFolder = $null
# Loop through each directory to find the highest version folder.
foreach ($Dir in $VersionDirs) {
# Extract the folder name
[System.String]$FolderName = [System.IO.Path]::GetFileName($Dir)
[System.Version]$CurrentVersion = $null
# Try parsing the folder name as a Version.
if ([System.Version]::TryParse($FolderName, [ref] $CurrentVersion)) {
# Compare versions
if ($CurrentVersion.CompareTo($HighestVersion) -gt 0) {
$HighestVersion = $CurrentVersion
$HighestVersionFolder = $FolderName
}
}
}
# If no valid version folder is found
if (!$HighestVersionFolder) {
throw [System.IO.DirectoryNotFoundException]::New("No valid version directories found in $BasePath")
}
[string]$CPUArch = @{AMD64 = 'x64'; ARM64 = 'arm64' }[$Env:PROCESSOR_ARCHITECTURE]
if ([System.String]::IsNullOrWhiteSpace($CPUArch)) { throw [System.PlatformNotSupportedException]::New('Only AMD64 and ARM64 architectures are supported.') }
# Combine the base path, the highest version folder, the architecture folder, and the file name.
[System.String]$MakeAppxPath = [System.IO.Path]::Combine($BasePath, $HighestVersionFolder, $CPUArch, 'makeappx.exe')
return $MakeAppxPath
}
[System.String]$MakeAppxPath = Get-MakeAppxPath
if ([System.string]::IsNullOrWhiteSpace($MakeAppxPath)) {
throw [System.IO.FileNotFoundException]::New('Could not find the makeappx.exe')
}
# https://learn.microsoft.com/en-us/windows/win32/appxpkg/make-appx-package--makeappx-exe-#to-create-a-package-bundle-using-a-directory-structure
. $MakeAppxPath bundle /d $MSIXBundleOutput /p $MSIXBundle /o /v
if ($LASTEXITCODE -ne 0) { Throw [System.InvalidOperationException]::New("MakeAppx failed creating the MSIXBundle. Exit Code: $LASTEXITCODE") }
#Endregion
Write-Host -Object "X64 MSIX File Path: $FinalMSIXX64Path" -ForegroundColor Green
Write-Host -Object "X64 MSIX File Name: $FinalMSIXX64Name" -ForegroundColor Green
Write-Host -Object "X64 Symbols: $FinalMSIXX64SymbolPath" -ForegroundColor Green
Write-Host -Object "ARM64 MSIX File Path: $FinalMSIXARM64Path" -ForegroundColor Cyan
Write-Host -Object "ARM64 MSIX File Name: $FinalMSIXARM64Name" -ForegroundColor Cyan
Write-Host -Object "ARM64 Symbols: $FinalMSIXARM64SymbolPath" -ForegroundColor Cyan
Write-Host -Object "MSIX Bundle File Path: $MSIXBundle" -ForegroundColor Yellow
Write-Host -Object "MSIX Bundle File Name: $FinalBundleFileName" -ForegroundColor Yellow
if ($null -ne $Stopwatch) {
$Stopwatch.Stop()
$Elapsed = $Stopwatch.Elapsed
[string]$Result = @"
Execution Time:
----------------------------
Total Time : $($Elapsed.ToString('g'))
Hours : $($Elapsed.Hours)
Minutes : $($Elapsed.Minutes)
Seconds : $($Elapsed.Seconds)
Milliseconds : $($Elapsed.Milliseconds)
----------------------------
"@
Write-Host -Object $Result -ForegroundColor Cyan
}
- Create AppControl Policy
- Create Supplemental Policy
- System Information
- Configure Policy Rule Options
- Simulation
- Allow New Apps
- Build New Certificate
- Create Policy From Event Logs
- Create Policy From MDE Advanced Hunting
- Create Deny Policy
- Merge App Control Policies
- Deploy App Control Policy
- Get Code Integrity Hashes
- Get Secure Policy Settings
- Update
- Sidebar
- Validate Policies
- View File Certificates
- Introduction
- How To Generate Audit Logs via App Control Policies
- How To Create an App Control Supplemental Policy
- The Strength of Signed App Control Policies
- How To Upload App Control Policies To Intune Using AppControl Manager
- How To Create and Maintain Strict Kernel‐Mode App Control Policy
- How to Create an App Control Deny Policy
- App Control Notes
- How to use Windows Server to Create App Control Code Signing Certificate
- Fast and Automatic Microsoft Recommended Driver Block Rules updates
- App Control policy for BYOVD Kernel mode only protection
- EKUs in App Control for Business Policies
- App Control Rule Levels Comparison and Guide
- Script Enforcement and PowerShell Constrained Language Mode in App Control Policies
- How to Use Microsoft Defender for Endpoint Advanced Hunting With App Control
- App Control Frequently Asked Questions (FAQs)
- Create Bootable USB flash drive with no 3rd party tools
- Event Viewer
- Group Policy
- How to compact your OS and free up extra space
- Hyper V
- Overrides for Microsoft Security Baseline
- Git GitHub Desktop and Mandatory ASLR
- Signed and Verified commits with GitHub desktop
- About TLS, DNS, Encryption and OPSEC concepts
- Things to do when clean installing Windows
- Comparison of security benchmarks
- BitLocker, TPM and Pluton | What Are They and How Do They Work
- How to Detect Changes in User and Local Machine Certificate Stores in Real Time Using PowerShell
- Cloning Personal and Enterprise Repositories Using GitHub Desktop
- Only a Small Portion of The Windows OS Security Apparatus
- Rethinking Trust: Advanced Security Measures for High‐Stakes Systems
- Clean Source principle, Azure and Privileged Access Workstations
- How to Securely Connect to Azure VMs and Use RDP
- Basic PowerShell tricks and notes
- Basic PowerShell tricks and notes Part 2
- Basic PowerShell tricks and notes Part 3
- Basic PowerShell tricks and notes Part 4
- Basic PowerShell tricks and notes Part 5
- How To Access All Stream Outputs From Thread Jobs In PowerShell In Real Time
- PowerShell Best Practices To Follow When Coding
- How To Asynchronously Access All Stream Outputs From Background Jobs In PowerShell
- Powershell Dynamic Parameters and How to Add Them to the Get‐Help Syntax
- RunSpaces In PowerShell
- How To Use Reflection And Prevent Using Internal & Private C# Methods in PowerShell