In a previous question, I was given a solution for finding the name of a key by its value. Unfortunately I neglected to consider the application of Security Groups
Old hashtable and working function
$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
OUTPUT: Department: Sales Job Title: Manager
The above works excellently, however I've now created a deeper hashtable and need to do the same thing, just another level to extract more information.
New hashtable
$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"
}
}
}
How should I change the working function to display the text contained in the key
OUTPUT: SG: SG-Sales Managers Department: Sales Job Title: Manager
CodePudding user response:
Create a new flat role table from your OU-like hashtable structure:
$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
}
}
}
}
Now you can avoid ...GetEnumerator() | Where-Object { ... }
completely when resolving the role code:
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)"
}
}