如何在 PowerShell 中反向遍历嵌套哈希表
How to reverse traverse a nested hashtable in PowerShell
在上一个问题中,我得到了。不幸的是我忽略了安全组的应用
旧哈希table和工作函数
$Departments = @{
'Sales' = @{
'SAM' = 'Manager'
'SAP' = 'Person'
}
'IT' = @{
'ITM' = 'Manager'
'ITS' = 'Specialist'
'ITT' = 'Technician'
'ITC' = 'Consultant'
}
}
function Get-DepartmentOU {
Param (
[CmdletBinding()]
[Parameter(Mandatory = $true)]
[System.String]
$RoleCode
)
# Get the DictionaryEntry in the main Hashtable where the nested Hashtable value matches the role you are looking for.
$Department = $script:Departments.GetEnumerator() | Where-Object { $_.Value.ContainsKey($RoleCode) }
# Print the name of the DictionaryEntry (Your department) and retrieve the value from the Hashtable for the role.
"Department: $($Department.Name) Job Title: $($Department.Value[$RoleCode])"
}
$JobCode = "SAM"
$DepartmentInfo = Get-DepartmentOU -RoleCode $JobCode
$DepartmentInfo
输出:Department: Sales Job Title: Manager
上面的效果很好,但是我现在创建了一个更深的散列table并且需要做同样的事情,只是另一个级别来提取更多信息。
新哈希table
$Departments = @{
"Parts" = @{
"SG-Parts" = @{
"PAM" = "Parts Manager"
"PAA" = "Parts Advisor"
}
}
"Sales" = @{
"SG-Sales" = @{
"SAP" = "Sales Person"
"SAR" = "Receptionist"
}
"SG-Sales Managers" = @{
"SGM" = "General Manager"
"SAM" = "Sales Manager"
}
}
}
我应该如何更改工作功能以显示按键中包含的文本
输出:SG: SG-Sales Managers Department: Sales Job Title: Manager
这可能有助于可视化@mathias-r.-jessen 的 'flat role table/map' 代码生成的数据结构:
$Rolemap = @{
"PAC" = @{
"Title" = "Parts Consultant"
"SG" = "SG-Parts"
"Department" = "Parts"
}
"PAA" = @{
"Title" = "Parts Advisor"
"SG" = "SG-Parts"
"Department" = "Parts"
}
"SGM" = @{
"Title" = "General Manager"
"SG" = "SG-Sales Managers"
"Department" = "Sales"
}
}
原始数据结构模仿了常见的小型 Active Directory 设置,因此人们可以根据需要更快地进行修改。
使用原始数据格式时,每次添加新角色只需添加到散列table中正确的'group'。但是,将 "SAM" = "Sales Manager"
反转为 "Sales Manager"="SAM"
可能有助于提高易读性和逻辑/结构。
我使用 $RoleMap |Format-Custom
和一些手动输入来构建生成的 table 可视化文本。
根据您的 OU-like 散列table 结构创建一个新的平面角色 table:
$RoleMap = @{}
foreach($departmentCode in $Departments.psbase.Keys){
foreach($sgCode in $Departments[$departmentCode].psbase.Keys){
foreach($roleCode in $Departments[$departmentCode][$sgCode].psbase.Keys){
# Create a summary object that includes all 3 pieces of information
# Store in role table and use the "role code" as the key
$RoleMap[$roleCode] = [pscustomobject]@{
Title = $Departments[$departmentCode][$sgCode][$roleCode]
SG = $sgCode
Department = $departmentCode
}
}
}
}
现在解析角色代码时可以完全避免...GetEnumerator() | Where-Object { ... }
:
function Get-DepartmentOU {
param(
[CmdletBinding()]
[Parameter(Mandatory = $true)]
[string]
$RoleCode
)
if($script:RoleMap.Contains($RoleCode)){
# `Where-Object` no longer needed!
$roleDescription = $script:RoleMap[$RoleCode]
"SG: $($roleDescription.SG) Department: $($roleDescription.Name) Job Title: $($roleDescription.Title)"
}
}
在上一个问题中,我得到了
旧哈希table和工作函数
$Departments = @{
'Sales' = @{
'SAM' = 'Manager'
'SAP' = 'Person'
}
'IT' = @{
'ITM' = 'Manager'
'ITS' = 'Specialist'
'ITT' = 'Technician'
'ITC' = 'Consultant'
}
}
function Get-DepartmentOU {
Param (
[CmdletBinding()]
[Parameter(Mandatory = $true)]
[System.String]
$RoleCode
)
# Get the DictionaryEntry in the main Hashtable where the nested Hashtable value matches the role you are looking for.
$Department = $script:Departments.GetEnumerator() | Where-Object { $_.Value.ContainsKey($RoleCode) }
# Print the name of the DictionaryEntry (Your department) and retrieve the value from the Hashtable for the role.
"Department: $($Department.Name) Job Title: $($Department.Value[$RoleCode])"
}
$JobCode = "SAM"
$DepartmentInfo = Get-DepartmentOU -RoleCode $JobCode
$DepartmentInfo
输出:Department: Sales Job Title: Manager
上面的效果很好,但是我现在创建了一个更深的散列table并且需要做同样的事情,只是另一个级别来提取更多信息。
新哈希table
$Departments = @{
"Parts" = @{
"SG-Parts" = @{
"PAM" = "Parts Manager"
"PAA" = "Parts Advisor"
}
}
"Sales" = @{
"SG-Sales" = @{
"SAP" = "Sales Person"
"SAR" = "Receptionist"
}
"SG-Sales Managers" = @{
"SGM" = "General Manager"
"SAM" = "Sales Manager"
}
}
}
我应该如何更改工作功能以显示按键中包含的文本
输出:SG: SG-Sales Managers Department: Sales Job Title: Manager
这可能有助于可视化@mathias-r.-jessen 的 'flat role table/map' 代码生成的数据结构:
$Rolemap = @{
"PAC" = @{
"Title" = "Parts Consultant"
"SG" = "SG-Parts"
"Department" = "Parts"
}
"PAA" = @{
"Title" = "Parts Advisor"
"SG" = "SG-Parts"
"Department" = "Parts"
}
"SGM" = @{
"Title" = "General Manager"
"SG" = "SG-Sales Managers"
"Department" = "Sales"
}
}
原始数据结构模仿了常见的小型 Active Directory 设置,因此人们可以根据需要更快地进行修改。
使用原始数据格式时,每次添加新角色只需添加到散列table中正确的'group'。但是,将 "SAM" = "Sales Manager"
反转为 "Sales Manager"="SAM"
可能有助于提高易读性和逻辑/结构。
我使用 $RoleMap |Format-Custom
和一些手动输入来构建生成的 table 可视化文本。
根据您的 OU-like 散列table 结构创建一个新的平面角色 table:
$RoleMap = @{}
foreach($departmentCode in $Departments.psbase.Keys){
foreach($sgCode in $Departments[$departmentCode].psbase.Keys){
foreach($roleCode in $Departments[$departmentCode][$sgCode].psbase.Keys){
# Create a summary object that includes all 3 pieces of information
# Store in role table and use the "role code" as the key
$RoleMap[$roleCode] = [pscustomobject]@{
Title = $Departments[$departmentCode][$sgCode][$roleCode]
SG = $sgCode
Department = $departmentCode
}
}
}
}
现在解析角色代码时可以完全避免...GetEnumerator() | Where-Object { ... }
:
function Get-DepartmentOU {
param(
[CmdletBinding()]
[Parameter(Mandatory = $true)]
[string]
$RoleCode
)
if($script:RoleMap.Contains($RoleCode)){
# `Where-Object` no longer needed!
$roleDescription = $script:RoleMap[$RoleCode]
"SG: $($roleDescription.SG) Department: $($roleDescription.Name) Job Title: $($roleDescription.Title)"
}
}