Skip to content

Commit e43ccd9

Browse files
authored
Replaces xml parser with a bit better parser
Replaces xml parser with a parser that is a bit better, ConvertFrom-XML.
1 parent 8ec4709 commit e43ccd9

File tree

1 file changed

+117
-36
lines changed

1 file changed

+117
-36
lines changed

Powershell/Get-PolicyDefinition.ps1

+117-36
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,96 @@ function Get-PolicyDefinition {
1212
[string[]]
1313
$Class
1414
)
15-
begin {}
15+
begin {
16+
function ConvertFrom-XML {
17+
[CmdletBinding()]
18+
param
19+
(
20+
[Parameter(Mandatory = $true, ValueFromPipeline)]
21+
[System.Xml.XmlNode]$node, #we are working through the nodes
22+
[string]$Prefix = '', #do we indicate an attribute with a prefix?
23+
$ShowDocElement = $false #Do we show the document element?
24+
)
25+
# Source: https://www.red-gate.com/simple-talk/blogs/convert-from-xml/
26+
process {
27+
#if option set, we skip the Document element
28+
if ($node.DocumentElement -and !($ShowDocElement))
29+
{ $node = $node.DocumentElement }
30+
$oHash = [ordered] @{ } # start with an ordered hashtable.
31+
#The order of elements is always significant regardless of what they are
32+
write-verbose "calling with $($node.LocalName)"
33+
if ($null -ne $node.Attributes) {
34+
#if there are elements
35+
# record all the attributes first in the ordered hash
36+
$node.Attributes | ForEach-Object {
37+
$oHash.$($Prefix + $_.FirstChild.parentNode.LocalName) = $_.FirstChild.value
38+
}
39+
}
40+
# check to see if there is a pseudo-array. (more than one
41+
# child-node with the same name that must be handled as an array)
42+
$node.ChildNodes | #we just group the names and create an empty
43+
#array for each
44+
Group-Object -Property LocalName | Where-Object { $_.count -gt 1 } | Select-Object Name |
45+
ForEach-Object {
46+
write-verbose "pseudo-Array $($_.Name)"
47+
$oHash.($_.Name) = @() <# create an empty array for each one#>
48+
};
49+
foreach ($child in $node.ChildNodes) {
50+
#now we look at each node in turn.
51+
write-verbose "processing the '$($child.LocalName)'"
52+
$childName = $child.LocalName
53+
if ($child -is [system.xml.xmltext]) {
54+
# if it is simple XML text
55+
write-verbose "simple xml $childname";
56+
$oHash.$childname += $child.InnerText
57+
}
58+
# if it has a #text child we may need to cope with attributes
59+
elseif ($child.FirstChild.Name -eq '#text' -and $child.ChildNodes.Count -eq 1) {
60+
write-verbose "text";
61+
if ($null -ne $child.Attributes) {
62+
#hah, an attribute
63+
<#we need to record the text with the #text label and preserve all
64+
the attributes #>
65+
$aHash = [ordered]@{ };
66+
$child.Attributes | ForEach-Object {
67+
$aHash.$($_.FirstChild.parentNode.LocalName) = $_.FirstChild.value
68+
}
69+
#now we add the text with an explicit name
70+
$aHash.'#text' += $child.'#text'
71+
$oHash.$childname += $aHash
72+
}
73+
else {
74+
#phew, just a simple text attribute.
75+
$oHash.$childname += $child.FirstChild.InnerText
76+
}
77+
}
78+
elseif ($null -ne $child.'#cdata-section') {
79+
# if it is a data section, a block of text that isnt parsed by the parser,
80+
# but is otherwise recognized as markup
81+
write-verbose "cdata section";
82+
$oHash.$childname = $child.'#cdata-section'
83+
}
84+
elseif ($child.ChildNodes.Count -gt 1 -and
85+
($child | Get-Member -MemberType Property).Count -eq 1) {
86+
$oHash.$childname = @()
87+
foreach ($grandchild in $child.ChildNodes) {
88+
$oHash.$childname += (ConvertFrom-XML $grandchild)
89+
}
90+
}
91+
else {
92+
# create an array as a value to the hashtable element
93+
if ($oHash.$childname -is [System.Management.Automation.PSParameterizedProperty]) {
94+
$oHash.$childname = $oHash.$childname, (ConvertFrom-XML $child)
95+
}
96+
else {
97+
$oHash.$childname += (ConvertFrom-XML $child)
98+
}
99+
}
100+
}
101+
$oHash
102+
}
103+
}
104+
}
16105
process {
17106
$PolicyDefPath = Join-Path -Path $env:SystemRoot -ChildPath "PolicyDefinitions" | Resolve-Path | Get-Item -ErrorAction Stop
18107
$LangPath = Join-Path -Path $PolicyDefPath -ChildPath $(Get-WinSystemLocale).Name | Resolve-Path | Get-Item -ErrorAction Stop
@@ -37,59 +126,51 @@ function Get-PolicyDefinition {
37126
}
38127
}
39128
}
40-
129+
if ($PSBoundParameters.ContainsKey('Debug')) {
130+
$DebugPreference = 'Stop'
131+
}
41132
# Loop through each policy
42133
foreach ($Policy in $Policies) {
134+
$htPolicy = ConvertFrom-XML $Policy
43135
if (
44136
$(
45137
$PSBoundParameters.ContainsKey('Name') -and
138+
$PSBoundParameters.ContainsKey('Class') -and
139+
$(
140+
$(
141+
$htPolicy.Name -like $Name -or
142+
$htPolicy.Name -in $Name
143+
) -and
144+
$(
145+
$htPolicy.class -like $Class -or
146+
$htPolicy.class -in $Class
147+
)
148+
)
149+
) -or
150+
$(
151+
$PSBoundParameters.ContainsKey('Name') -and
152+
-not $PSBoundParameters.ContainsKey('Class') -and
46153
$(
47-
$Policy.Name -like $Name -or
48-
$Policy.Name -in $Name
154+
$htPolicy.Name -like $Name -or
155+
$htPolicy.Name -in $Name
49156
)
50157
) -or
51158
$(
52159
$PSBoundParameters.ContainsKey('Class') -and
160+
-not $PSBoundParameters.ContainsKey('Name') -and
53161
$(
54-
$Policy.class -like $Class -or
55-
$Policy.class -in $Class
162+
$htPolicy.class -like $Class -or
163+
$htPolicy.class -in $Class
56164
)
57165
) -or
58166
$(
59167
-not $PSBoundParameters.ContainsKey('Name') -and
60168
-not $PSBoundParameters.ContainsKey('Class')
61169
)
62170
) {
63-
[System.Collections.Generic.List[string]]$defaultDisplaySet = 'Name', 'Class', 'DisplayName', 'Key'
64-
$out = [PSCustomObject]@{
65-
Name = $Policy.Name
66-
Class = $Policy.class
67-
DisplayName = $($lang | Where-Object { $_.id -like $($Policy.displayName -replace "\`$\(string\." -replace "\)") }).text
68-
ExplainText = $($lang | Where-Object { $_.id -like $($Policy.explainText -replace "\`$\(string\." -replace "\)") }).text
69-
Key = $Policy.key
70-
}
71-
72-
if ($Policy.elements) {
73-
$out | Add-Member -Name Elements -Value $Policy.elements -MemberType NoteProperty
74-
$defaultDisplaySet.Add('Elements')
75-
}
76-
if ($Policy.policyDefinitions.policies.policy.enabledValue) {
77-
$out | Add-Member -Name EnabledValue -Value $Policy.policyDefinitions.policies.policy.enabledValue -MemberType NoteProperty
78-
$defaultDisplaySet.Add('EnabledValue')
79-
}
80-
if ($Policy.policyDefinitions.policies.policy.disabledValue) {
81-
$out | Add-Member -Name DisabledValue -Value $Policy.policyDefinitions.policies.policy.disabledValue -MemberType NoteProperty
82-
$defaultDisplaySet.Add('DisabledValue')
83-
}
84-
if (-not $out.Elements -and -not $out.EnabledValue) {
85-
$out | Add-Member -Name IsBoolean -Value $true -MemberType NoteProperty
86-
$defaultDisplaySet.Add('IsBoolean')
87-
}
88-
89-
$defaultDisplayPropertySet = New-Object System.Management.Automation.PSPropertySet('DefaultDisplayPropertySet', [string[]]$defaultDisplaySet)
90-
$PSStandardMembers = [System.Management.Automation.PSMemberInfo[]]@($defaultDisplayPropertySet)
91-
$out | Add-Member MemberSet PSStandardMembers $PSStandardMembers
92-
$out
171+
$htPolicy.displayName = $($lang | Where-Object { $_.id -like $($htPolicy.displayName -replace "\`$\(string\." -replace "\)") }).text
172+
$htPolicy.explainText = $($lang | Where-Object { $_.id -like $($htPolicy.explainText -replace "\`$\(string\." -replace "\)") }).text
173+
$htPolicy
93174
}
94175
}
95176
}

0 commit comments

Comments
 (0)