Skip to content

Instantly share code, notes, and snippets.

@tomohulk
Last active March 3, 2021 01:57
Show Gist options
  • Save tomohulk/e92ff6e8d85862cb0e8a5b69774e38b3 to your computer and use it in GitHub Desktop.
Save tomohulk/e92ff6e8d85862cb0e8a5b69774e38b3 to your computer and use it in GitHub Desktop.
Converts a AppLocker Policy XML input to individual objects.
#requires -Version 5.1
<#PSScriptInfo
.Version
1.0
.Guid
90d2876dc-04e4-4f2d-b765-e288bc84456c
.Author
Thomas J. Malkewitz @tomohulk
.Tags
Applocker, Xml
.ProjectUri
https://gist.github.com/tomohulk/e92ff6e8d85862cb0e8a5b69774e38b3
#>
<#
.SYNOPSIS
Converts an AppLocker Policy XML input to individual objects.
.DESCRIPTION
Converts an AppLocker Policy XML input, which can be generated with Get-AppLockerPolicy, and parses the output xml into individual, usable and readable objects.
Also converts the target UserOrGroupSid to the corresponding Name.
.INPUTS
System.String
System.XmlDocument
Generate Xml output using the Get-AppLockerPolicy cmdlet.
.OUTPUTS
System.Object
This technically returns a System.AppLockerRule, but as that class doesn't exist in the default scope, that would throw and error.
.EXAMPLE
PS C:\> Get-AppLockerPolicy -Effective -Xml | ConvertFrom-AppLockerPolicyXml
.EXAMPLE
PS C:\> ConvertFrom-AppLockerPolicyXml -Xml (Get-AppLockerPolicy -Local -Xml)
.NOTES
This cmdlet uses custom Class Definitions to "Cast" the XML objects, So WMI 5.1 is required.
.LINK
https://tomohulk.github.io
.LINK
https://docs.microsoft.com/en-us/powershell/module/applocker/get-applockerpolicy?view=win10-ps
#>
[CmdletBinding()]
[OutputType(
[Object]
)]
param (
[Parameter(
Mandatory = $true,
ValueFromPipeline = $true
)]
[Xml]
$Xml
)
begin {
#region Class Definitions
class AppLockerRule {
[String]$Id
[String]$Name
[String]$Description
[String]$Type
[String]$EnforcementMode
[String]$UserOrGroup
[String]$Action
[Object[]]$Conditions
[Object[]]$Exceptions
AppLockerRule([String]$enforcementMode, [String]$type, [Object]$object) {
$this.Id = $object.Id
$this.Name = $object.Name
$this.Description = $object.Description
$this.Type = $type
$this.UserOrGroup = $this.ConvertFromSid($object.UserOrGroupSid)
$this.EnforcementMode = $enforcementMode
$this.Action = $object.Action
$this.Conditions = switch ($object.Conditions.ChildNodes.Name) {
"FilePublisherCondition" {
[FilePublisherCondition]::new($object.Conditions.FilePublisherCondition)
}
"FilePathCondition" {
[FilePathCondition]::new($object.Conditions.FilePathCondition)
}
"FileHashCondition" {
foreach ($hash in $object.Conditions.FileHashCondition.FileHash) {
[FileHashCondition]::new($hash)
}
}
}
$this.Exceptions = switch ($object.Exceptions.ChildNodes.Name) {
"FilePublisherCondition" {
[FilePublisherCondition]::new($object.Exceptions.FilePublisherCondition)
}
"FilePathCondition" {
[FilePathCondition]::new($object.Exceptions.FilePathCondition)
}
"FileHashCondition" {
foreach ($hash in $object.Exceptions.FileHashCondition.FileHash) {
[FileHashCondition]::new($hash)
}
}
}
}
[String]ConvertFromSid([String]$Sid) {
if ($Sid -eq "S-1-1-0") {
$returnValue = "Everyone"
} else {
try {
$returnValue = ([System.Security.Principal.SecurityIdentifier]"$Sid").Translate([System.Security.Principal.NTAccount]).Value
} catch {
$returnValue = [String]::Empty
}
}
return $returnValue
}
}
class FilePublisherCondition {
[String]$ConditionType
[String]$PublisherName
[String]$ProductName
[String]$BinaryName
[String]$BinaryVersionLowSection
[String]$BinaryVersionHighSection
FilePublisherCondition([Object]$object) {
$this.ConditionType = $object.Name
$this.PublisherName = $object.PublisherName
$this.ProductName = $object.ProductName
$this.BinaryName = $object.BinaryName
$this.BinaryVersionLowSection = $object.BinaryVersionRange.LowSection
$this.BinaryVersionHighSection = $object.BinaryVersionRange.HighSection
}
}
class FilePathCondition {
[String]$ConditionType
[String]$Path
FilePathCondition([Object]$object) {
$this.ConditionType = $object.Name
$this.Path = $object.Path
}
}
class FileHashCondition {
[String]$ConditionType
[String]$Type
[String]$Data
[String]$SourceFileName
[String]$SourceFileLength
FileHashCondition([Object]$object) {
$this.ConditionType = $object.Name
$this.Type = $object.Type
$this.Data = $object.Data
$this.SourceFileName = $object.SourceFileName
$this.SourceFileLength = $object.SourceFileLength
}
}
#endregion Class Definitions
}
process {
foreach ($fileType in @("Appx", "Dll", "Exe", "Msi", "Script")) {
$rules = $Xml.AppLockerPolicy.SelectNodes("//RuleCollection[@Type='$fileType']")
foreach ($ruleType in @("FilePublisherRule", "FilePathRule", "FileHashRule")) {
foreach ($rule in @($rules.$ruleType)) {
[AppLockerRule]::new($rules.EnforcementMode, $rules.Type, $rule)
}
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment