如何提高迭代循环性能
How to improve iterative loop performance
所以我试图遍历一组数据并创建一个显示所有不同路径的结果树,我终于成功了,但它运行得非常慢,根据我的测试,这是因为循环搜索功能和最后的附加正则表达式匹配,因为该功能无法确定最终结果是否与标准 windows 匹配。如何检查根调用以过滤以 windows: 开头的结果,以及如何删除重复搜索功能。我的猜测是我可以制作一个仅包含 name/parent 值的新哈希表并使用它,但我已经玩这个概念几个小时但没有任何运气。
当前工作代码。
Function New-CategoryTree {
Param (
$Categories
)
$GetParentCategory = [ScriptBlock]::Create({
Param(
[psobject]$Category
)
#Examine the parentCategory field and see if it matches certain criteria.
Switch ($Category.parentCategory.ref) {
{ $_ -match "^windows:([a-zA-Z_\ 1-9]+)$" } { #if Parent Category matches 'Windows:*'
Return "$($Category.parentCategory.ref)$($Category.name)"
}
{ [String]::IsNullOrWhiteSpace($_) } { #If pareent
Return
}
Default {
Return ("$(& $GetParentCategory -Category ($Categories.where({$_.name -eq $Category.parentCategory.ref})))$($Category.name)")
}
}
})
New-Variable -Name Result -Value (New-Object -TypeName System.Collections.ArrayList)
New-Variable -Name NewCategories -Value (New-Object -TypeName System.Collections.ArrayList)
ForEach ($Category in $Categories) {
[Void]$NewCategories.Add((& $GetParentCategory -Category $Category))
}
ForEach ($Category in $NewCategories) {
([Regex]::Match($Category,'^windows:([a-zA-Z_\ 1-9]+)$').groups[1]).where({$_.success -eq $True}).value |ForEach-Object {[Void]$Result.Add($_)}
}
Return $Result
}
数据集
<categories>
<category name="InternetExplorer" displayName="$(string.InternetExplorer)" explainText="$(string.IE_ExplainCat)">
<parentCategory ref="windows:WindowsComponents" />
</category>
<category name="AdvancedPage" displayName="$(string.AdvancedPage)">
<parentCategory ref="InternetCPL" />
</category>
<category name="InternetCPL_Advanced_Accessibility" displayName="$(string.InternetCPL_Advanced_Accessibility)">
<parentCategory ref="AdvancedPage" />
</category>
<category name="InternetCPL_Advanced_International" displayName="$(string.InternetCPL_Advanced_International)">
<parentCategory ref="AdvancedPage" />
</category>
<category name="InternetCPL_Advanced_Security" displayName="$(string.InternetCPL_Advanced_Security)">
<parentCategory ref="AdvancedPage" />
</category>
</categories>
预期输出
WindowsComponents\InternetExplorer
WindowsComponents\RSS_Feeds
WindowsComponents\InternetExplorer\InternetCPL\AdvancedPage\InternetCPL_Advanced_Accessibility
WindowsComponents\InternetExplorer\InternetCPL\AdvancedPage\InternetCPL_Advanced_International
WindowsComponents\InternetExplorer\InternetCPL\AdvancedPage\InternetCPL_Advanced_Security
WindowsComponents\InternetExplorer\InternetCPL\InternetCPL_Connections
WindowsComponents\InternetExplorer\InternetCPL\InternetCPL_Content
WindowsComponents\InternetExplorer\InternetCPL\InternetCPL_Content\InternetCPL_Content_Certificates
WindowsComponents\InternetExplorer\InternetCPL\InternetCPL_Privacy
WindowsComponents\InternetExplorer\InternetCPL\InternetCPL_Programs
WindowsComponents\InternetExplorer\InternetSettings\Advanced\Browsing
WindowsComponents\InternetExplorer\InternetSettings\Advanced\ICWSettings
WindowsComponents\InternetExplorer\InternetSettings\Advanced\Multimedia
WindowsComponents\InternetExplorer\InternetSettings\Advanced\Printing
WindowsComponents\InternetExplorer\InternetSettings\Advanced\Searching
WindowsComponents\InternetExplorer\InternetSettings\Advanced\SignupSettings
WindowsComponents\InternetExplorer\CategoryAppCompat\ScriptPaste
WindowsComponents\InternetExplorer\InternetSettings\ComponentUpdates\HelpAbout128
WindowsComponents\InternetExplorer\InternetSettings\ComponentUpdates\UpdateCheck
WindowsComponents\InternetExplorer\CorporateSettings\CodeDownload
WindowsComponents\InternetExplorer\InternetSettings\DisplaySettings\GeneralColors
WindowsComponents\InternetExplorer\InternetSettings\DisplaySettings\LinkColors
WindowsComponents\InternetExplorer\InternetCPL\AdvancedPage
WindowsComponents\InternetExplorer\InternetCPL\IZ_SecurityPage
WindowsComponents\InternetExplorer\SecurityFeatures\IESF_CategoryNetworkProtocolLockdown\IESF_NPLRest_Category
WindowsComponents\InternetExplorer\AdminApproved
WindowsComponents\InternetExplorer\CategoryAppCompat
WindowsComponents\InternetExplorer\Channels
WindowsComponents\InternetExplorer\CorporateSettings
WindowsComponents\InternetExplorer\DeleteBrowsingHistory
WindowsComponents\InternetExplorer\InternetCPL
WindowsComponents\InternetExplorer\InternetSettings
WindowsComponents\InternetExplorer\Menus
WindowsComponents\InternetExplorer\Persistence
WindowsComponents\InternetExplorer\SecurityFeatures
WindowsComponents\InternetExplorer\Toolbars
WindowsComponents\InternetExplorer\InternetSettings\Advanced
WindowsComponents\InternetExplorer\InternetSettings\AutoCompleteCat
WindowsComponents\InternetExplorer\InternetSettings\ComponentUpdates
WindowsComponents\InternetExplorer\InternetSettings\DisplaySettings
WindowsComponents\InternetExplorer\InternetSettings\Encoding
WindowsComponents\InternetExplorer\InternetCPL\IZ_SecurityPage\IZ_InternetZone
WindowsComponents\InternetExplorer\InternetCPL\IZ_SecurityPage\IZ_InternetZoneLockdown
WindowsComponents\InternetExplorer\InternetCPL\IZ_SecurityPage\IZ_IntranetZone
WindowsComponents\InternetExplorer\InternetCPL\IZ_SecurityPage\IZ_IntranetZoneLockdown
WindowsComponents\InternetExplorer\InternetCPL\IZ_SecurityPage\IZ_LocalMachineZone
WindowsComponents\InternetExplorer\InternetCPL\IZ_SecurityPage\IZ_LocalMachineZoneLockdown
WindowsComponents\InternetExplorer\InternetCPL\IZ_SecurityPage\IZ_RestrictedSitesZone
WindowsComponents\InternetExplorer\InternetCPL\IZ_SecurityPage\IZ_RestrictedSitesZoneLockdown
WindowsComponents\InternetExplorer\InternetCPL\IZ_SecurityPage\IZ_TrustedSitesZone
WindowsComponents\InternetExplorer\InternetCPL\IZ_SecurityPage\IZ_TrustedSitesZoneLockdown
WindowsComponents\InternetExplorer\SecurityFeatures\IESF_AddOnManagement
WindowsComponents\InternetExplorer\SecurityFeatures\IESF_CategoryAJAX
WindowsComponents\InternetExplorer\SecurityFeatures\IESF_CategoryBinaryBehaviorSecurityRestriction
WindowsComponents\InternetExplorer\SecurityFeatures\IESF_CategoryConsistentMimeHandling
WindowsComponents\InternetExplorer\SecurityFeatures\IESF_CategoryInformationBar
WindowsComponents\InternetExplorer\SecurityFeatures\IESF_CategoryLocalMachineZoneLockdownSecurity
WindowsComponents\InternetExplorer\SecurityFeatures\IESF_CategoryMimeSniffingSafetyFeature
WindowsComponents\InternetExplorer\SecurityFeatures\IESF_CategoryMKProtocolSecurityRestriction
WindowsComponents\InternetExplorer\SecurityFeatures\IESF_CategoryNetworkProtocolLockdown
WindowsComponents\InternetExplorer\SecurityFeatures\IESF_CategoryObjectCachingProtection
WindowsComponents\InternetExplorer\SecurityFeatures\IESF_CategoryProtectionFromZoneElevation
WindowsComponents\InternetExplorer\SecurityFeatures\IESF_CategoryRestrictActiveXInstall
WindowsComponents\InternetExplorer\SecurityFeatures\IESF_CategoryRestrictFileDownload
WindowsComponents\InternetExplorer\SecurityFeatures\IESF_CategoryScriptedWindowSecurityRestrictions
WindowsComponents\InternetExplorer\CategoryPrivacy
WindowsComponents\InternetExplorer\CategoryAccelerators
WindowsComponents\InternetExplorer\CategoryCompatView
WindowsComponents\InternetExplorer\InternetCPL\CategoryGeneralPage
WindowsComponents\InternetExplorer\InternetCPL\CategoryGeneralPage\CategoryBrowsingHistory
首先正确处理您的 xml 数据,以便您可以与之交互:
[xml]$categories
然后就可以轻松显示了:
[xml]$categories.categories.category |
select @{l='ParentCategory';e={$_.ParentCategory.ref}},Name,Displayname
ParentCategory name
-------------- ----
windows:WindowsComponents InternetExplorer
InternetCPL AdvancedPage
AdvancedPage InternetCPL_Advanced_Accessibility
AdvancedPage InternetCPL_Advanced_International
AdvancedPage InternetCPL_Advanced_Security
根据需要进行过滤:
$filtered = [xml]$categories.categories.category |
where {$_.ParentCategory.ref -match '^windows:([a-zA-Z_\ 1-9]+)$'}
$filtered
name displayName explainText parentCategory
---- ----------- ----------- --------------
InternetExplorer $(string.InternetExplorer) $(string.IE_ExplainCat) parentCategory
并将过滤后的 xml 对象导出回字符串,添加外部节点:
$xmlout = '<categories>'+$filtered.outerxml+'</categories>'
经过几个小时的研究,我偶然发现了 'systems.collections.generic.dictionary' 属性,它让我基本上可以创建一个以 PSCustomObject 作为值的哈希表。这使我可以创建一个具有可引用名称的新对象,从而避免使用搜索功能。结合新的数据类型 + 利用 Streamreader 接收文件我的脚本 运行 从大约 3-5s 到大约 0.5s p.s。忽略我在代码中的所有评论,我正在努力围绕函数大声笑。
Function New-CategoryTree {
Param (
$Categories
)
#Scriptblock that will be used to check if the currently returned object is the root object.
$GetParentCategory = [ScriptBlock]::Create({
Param(
[Parameter(mandatory=$True)]
$Category,
[Parameter(mandatory=$True)]
$Categories
)
Switch -regex ($Category.ParentCategory) {
"^windows:([a-zA-Z_\ 1-9]+)$" { #if Category matches 'Windows:*' (a.k.a. we are done with the dive.)
Return "$($Category.ParentCategory)$($Category.DisplayName)"
}
"/^$|\s+/" { #Check if whitespace or empty.
Write-Host "Warning: This shouldn't be possible, best guess is ADMX is missconfigured. CategoryName: '$($Category.Name)'."
#This means its a root category without a parent so just return.
Return
}
Default {#If not root category, then restart the loop to dive 1 layer deeper then eventually retun with parentCategory.DisplayName\Category.DisplayName.
#If there is no valid parent category then thow a ignorable warning.
If ([String]::IsNullOrEmpty($Categories["$($Category.ParentCategory)"])) {
Write-Host "Warning: $($Category.name) has no valid parent category."
} Else {
Return ("$(& $GetParentCategory -Category $Categories["$($Category.ParentCategory)"] -Categories $Categories)$($Category.displayName)")
}
}
}
})
New-Variable -Name Results -Value (New-Object -TypeName System.Collections.Generic.List[String]) -Force
ForEach ($Category in $Categories.GetEnumerator()) {
$Results.Add((& $GetParentCategory -Category $Category.Value -Categories $Categories))
}
Return $Results
}
#Start Looping through every ADMX files.
ForEach ($File in $Script.ADMXFiles) {
#Get content of ADMX file and store results as XML
Set-Variable -Name ADMXFile -Value ([xml]((New-Object -TypeName System.IO.StreamReader -ArgumentList $File.FullName,([Text.Encoding]::Default),$False,"10000").ReadToEnd()))
New-Variable -Name Categories -Value (New-Object -TypeName 'System.Collections.Generic.Dictionary[[string], [PSCustomObject]]') -Force
$ADMXFile.policyDefinitions.categories.Category |ForEach-Object {
$Categories.add($_.name,[PSCustomObject]@{
Name = $_.name
DisplayName = ConvertFrom-StringTable -String $_.displayName -ADMX ($File.BaseName)
ParentCategory = $_.ParentCategory.ref
})
}
New-CategoryTree -Categories $Categories
}
所以我试图遍历一组数据并创建一个显示所有不同路径的结果树,我终于成功了,但它运行得非常慢,根据我的测试,这是因为循环搜索功能和最后的附加正则表达式匹配,因为该功能无法确定最终结果是否与标准 windows 匹配。如何检查根调用以过滤以 windows: 开头的结果,以及如何删除重复搜索功能。我的猜测是我可以制作一个仅包含 name/parent 值的新哈希表并使用它,但我已经玩这个概念几个小时但没有任何运气。
当前工作代码。
Function New-CategoryTree {
Param (
$Categories
)
$GetParentCategory = [ScriptBlock]::Create({
Param(
[psobject]$Category
)
#Examine the parentCategory field and see if it matches certain criteria.
Switch ($Category.parentCategory.ref) {
{ $_ -match "^windows:([a-zA-Z_\ 1-9]+)$" } { #if Parent Category matches 'Windows:*'
Return "$($Category.parentCategory.ref)$($Category.name)"
}
{ [String]::IsNullOrWhiteSpace($_) } { #If pareent
Return
}
Default {
Return ("$(& $GetParentCategory -Category ($Categories.where({$_.name -eq $Category.parentCategory.ref})))$($Category.name)")
}
}
})
New-Variable -Name Result -Value (New-Object -TypeName System.Collections.ArrayList)
New-Variable -Name NewCategories -Value (New-Object -TypeName System.Collections.ArrayList)
ForEach ($Category in $Categories) {
[Void]$NewCategories.Add((& $GetParentCategory -Category $Category))
}
ForEach ($Category in $NewCategories) {
([Regex]::Match($Category,'^windows:([a-zA-Z_\ 1-9]+)$').groups[1]).where({$_.success -eq $True}).value |ForEach-Object {[Void]$Result.Add($_)}
}
Return $Result
}
数据集
<categories>
<category name="InternetExplorer" displayName="$(string.InternetExplorer)" explainText="$(string.IE_ExplainCat)">
<parentCategory ref="windows:WindowsComponents" />
</category>
<category name="AdvancedPage" displayName="$(string.AdvancedPage)">
<parentCategory ref="InternetCPL" />
</category>
<category name="InternetCPL_Advanced_Accessibility" displayName="$(string.InternetCPL_Advanced_Accessibility)">
<parentCategory ref="AdvancedPage" />
</category>
<category name="InternetCPL_Advanced_International" displayName="$(string.InternetCPL_Advanced_International)">
<parentCategory ref="AdvancedPage" />
</category>
<category name="InternetCPL_Advanced_Security" displayName="$(string.InternetCPL_Advanced_Security)">
<parentCategory ref="AdvancedPage" />
</category>
</categories>
预期输出
WindowsComponents\InternetExplorer
WindowsComponents\RSS_Feeds
WindowsComponents\InternetExplorer\InternetCPL\AdvancedPage\InternetCPL_Advanced_Accessibility
WindowsComponents\InternetExplorer\InternetCPL\AdvancedPage\InternetCPL_Advanced_International
WindowsComponents\InternetExplorer\InternetCPL\AdvancedPage\InternetCPL_Advanced_Security
WindowsComponents\InternetExplorer\InternetCPL\InternetCPL_Connections
WindowsComponents\InternetExplorer\InternetCPL\InternetCPL_Content
WindowsComponents\InternetExplorer\InternetCPL\InternetCPL_Content\InternetCPL_Content_Certificates
WindowsComponents\InternetExplorer\InternetCPL\InternetCPL_Privacy
WindowsComponents\InternetExplorer\InternetCPL\InternetCPL_Programs
WindowsComponents\InternetExplorer\InternetSettings\Advanced\Browsing
WindowsComponents\InternetExplorer\InternetSettings\Advanced\ICWSettings
WindowsComponents\InternetExplorer\InternetSettings\Advanced\Multimedia
WindowsComponents\InternetExplorer\InternetSettings\Advanced\Printing
WindowsComponents\InternetExplorer\InternetSettings\Advanced\Searching
WindowsComponents\InternetExplorer\InternetSettings\Advanced\SignupSettings
WindowsComponents\InternetExplorer\CategoryAppCompat\ScriptPaste
WindowsComponents\InternetExplorer\InternetSettings\ComponentUpdates\HelpAbout128
WindowsComponents\InternetExplorer\InternetSettings\ComponentUpdates\UpdateCheck
WindowsComponents\InternetExplorer\CorporateSettings\CodeDownload
WindowsComponents\InternetExplorer\InternetSettings\DisplaySettings\GeneralColors
WindowsComponents\InternetExplorer\InternetSettings\DisplaySettings\LinkColors
WindowsComponents\InternetExplorer\InternetCPL\AdvancedPage
WindowsComponents\InternetExplorer\InternetCPL\IZ_SecurityPage
WindowsComponents\InternetExplorer\SecurityFeatures\IESF_CategoryNetworkProtocolLockdown\IESF_NPLRest_Category
WindowsComponents\InternetExplorer\AdminApproved
WindowsComponents\InternetExplorer\CategoryAppCompat
WindowsComponents\InternetExplorer\Channels
WindowsComponents\InternetExplorer\CorporateSettings
WindowsComponents\InternetExplorer\DeleteBrowsingHistory
WindowsComponents\InternetExplorer\InternetCPL
WindowsComponents\InternetExplorer\InternetSettings
WindowsComponents\InternetExplorer\Menus
WindowsComponents\InternetExplorer\Persistence
WindowsComponents\InternetExplorer\SecurityFeatures
WindowsComponents\InternetExplorer\Toolbars
WindowsComponents\InternetExplorer\InternetSettings\Advanced
WindowsComponents\InternetExplorer\InternetSettings\AutoCompleteCat
WindowsComponents\InternetExplorer\InternetSettings\ComponentUpdates
WindowsComponents\InternetExplorer\InternetSettings\DisplaySettings
WindowsComponents\InternetExplorer\InternetSettings\Encoding
WindowsComponents\InternetExplorer\InternetCPL\IZ_SecurityPage\IZ_InternetZone
WindowsComponents\InternetExplorer\InternetCPL\IZ_SecurityPage\IZ_InternetZoneLockdown
WindowsComponents\InternetExplorer\InternetCPL\IZ_SecurityPage\IZ_IntranetZone
WindowsComponents\InternetExplorer\InternetCPL\IZ_SecurityPage\IZ_IntranetZoneLockdown
WindowsComponents\InternetExplorer\InternetCPL\IZ_SecurityPage\IZ_LocalMachineZone
WindowsComponents\InternetExplorer\InternetCPL\IZ_SecurityPage\IZ_LocalMachineZoneLockdown
WindowsComponents\InternetExplorer\InternetCPL\IZ_SecurityPage\IZ_RestrictedSitesZone
WindowsComponents\InternetExplorer\InternetCPL\IZ_SecurityPage\IZ_RestrictedSitesZoneLockdown
WindowsComponents\InternetExplorer\InternetCPL\IZ_SecurityPage\IZ_TrustedSitesZone
WindowsComponents\InternetExplorer\InternetCPL\IZ_SecurityPage\IZ_TrustedSitesZoneLockdown
WindowsComponents\InternetExplorer\SecurityFeatures\IESF_AddOnManagement
WindowsComponents\InternetExplorer\SecurityFeatures\IESF_CategoryAJAX
WindowsComponents\InternetExplorer\SecurityFeatures\IESF_CategoryBinaryBehaviorSecurityRestriction
WindowsComponents\InternetExplorer\SecurityFeatures\IESF_CategoryConsistentMimeHandling
WindowsComponents\InternetExplorer\SecurityFeatures\IESF_CategoryInformationBar
WindowsComponents\InternetExplorer\SecurityFeatures\IESF_CategoryLocalMachineZoneLockdownSecurity
WindowsComponents\InternetExplorer\SecurityFeatures\IESF_CategoryMimeSniffingSafetyFeature
WindowsComponents\InternetExplorer\SecurityFeatures\IESF_CategoryMKProtocolSecurityRestriction
WindowsComponents\InternetExplorer\SecurityFeatures\IESF_CategoryNetworkProtocolLockdown
WindowsComponents\InternetExplorer\SecurityFeatures\IESF_CategoryObjectCachingProtection
WindowsComponents\InternetExplorer\SecurityFeatures\IESF_CategoryProtectionFromZoneElevation
WindowsComponents\InternetExplorer\SecurityFeatures\IESF_CategoryRestrictActiveXInstall
WindowsComponents\InternetExplorer\SecurityFeatures\IESF_CategoryRestrictFileDownload
WindowsComponents\InternetExplorer\SecurityFeatures\IESF_CategoryScriptedWindowSecurityRestrictions
WindowsComponents\InternetExplorer\CategoryPrivacy
WindowsComponents\InternetExplorer\CategoryAccelerators
WindowsComponents\InternetExplorer\CategoryCompatView
WindowsComponents\InternetExplorer\InternetCPL\CategoryGeneralPage
WindowsComponents\InternetExplorer\InternetCPL\CategoryGeneralPage\CategoryBrowsingHistory
首先正确处理您的 xml 数据,以便您可以与之交互:
[xml]$categories
然后就可以轻松显示了:
[xml]$categories.categories.category |
select @{l='ParentCategory';e={$_.ParentCategory.ref}},Name,Displayname
ParentCategory name
-------------- ----
windows:WindowsComponents InternetExplorer
InternetCPL AdvancedPage
AdvancedPage InternetCPL_Advanced_Accessibility
AdvancedPage InternetCPL_Advanced_International
AdvancedPage InternetCPL_Advanced_Security
根据需要进行过滤:
$filtered = [xml]$categories.categories.category |
where {$_.ParentCategory.ref -match '^windows:([a-zA-Z_\ 1-9]+)$'}
$filtered
name displayName explainText parentCategory
---- ----------- ----------- --------------
InternetExplorer $(string.InternetExplorer) $(string.IE_ExplainCat) parentCategory
并将过滤后的 xml 对象导出回字符串,添加外部节点:
$xmlout = '<categories>'+$filtered.outerxml+'</categories>'
经过几个小时的研究,我偶然发现了 'systems.collections.generic.dictionary' 属性,它让我基本上可以创建一个以 PSCustomObject 作为值的哈希表。这使我可以创建一个具有可引用名称的新对象,从而避免使用搜索功能。结合新的数据类型 + 利用 Streamreader 接收文件我的脚本 运行 从大约 3-5s 到大约 0.5s p.s。忽略我在代码中的所有评论,我正在努力围绕函数大声笑。
Function New-CategoryTree {
Param (
$Categories
)
#Scriptblock that will be used to check if the currently returned object is the root object.
$GetParentCategory = [ScriptBlock]::Create({
Param(
[Parameter(mandatory=$True)]
$Category,
[Parameter(mandatory=$True)]
$Categories
)
Switch -regex ($Category.ParentCategory) {
"^windows:([a-zA-Z_\ 1-9]+)$" { #if Category matches 'Windows:*' (a.k.a. we are done with the dive.)
Return "$($Category.ParentCategory)$($Category.DisplayName)"
}
"/^$|\s+/" { #Check if whitespace or empty.
Write-Host "Warning: This shouldn't be possible, best guess is ADMX is missconfigured. CategoryName: '$($Category.Name)'."
#This means its a root category without a parent so just return.
Return
}
Default {#If not root category, then restart the loop to dive 1 layer deeper then eventually retun with parentCategory.DisplayName\Category.DisplayName.
#If there is no valid parent category then thow a ignorable warning.
If ([String]::IsNullOrEmpty($Categories["$($Category.ParentCategory)"])) {
Write-Host "Warning: $($Category.name) has no valid parent category."
} Else {
Return ("$(& $GetParentCategory -Category $Categories["$($Category.ParentCategory)"] -Categories $Categories)$($Category.displayName)")
}
}
}
})
New-Variable -Name Results -Value (New-Object -TypeName System.Collections.Generic.List[String]) -Force
ForEach ($Category in $Categories.GetEnumerator()) {
$Results.Add((& $GetParentCategory -Category $Category.Value -Categories $Categories))
}
Return $Results
}
#Start Looping through every ADMX files.
ForEach ($File in $Script.ADMXFiles) {
#Get content of ADMX file and store results as XML
Set-Variable -Name ADMXFile -Value ([xml]((New-Object -TypeName System.IO.StreamReader -ArgumentList $File.FullName,([Text.Encoding]::Default),$False,"10000").ReadToEnd()))
New-Variable -Name Categories -Value (New-Object -TypeName 'System.Collections.Generic.Dictionary[[string], [PSCustomObject]]') -Force
$ADMXFile.policyDefinitions.categories.Category |ForEach-Object {
$Categories.add($_.name,[PSCustomObject]@{
Name = $_.name
DisplayName = ConvertFrom-StringTable -String $_.displayName -ADMX ($File.BaseName)
ParentCategory = $_.ParentCategory.ref
})
}
New-CategoryTree -Categories $Categories
}