I’m trying create some automations to help with general activities on an environment and was trying to think of a clean accessible way to store and access info via powershell hashmaps
$test=@{
"server1"=@{
"service1"=@{
"filePath"="C:\hi";
"serviceName"="servName1";
"processName"="procName1" ;
"group"=@("ALL", "SUBSET" );
"properties1"=@{"prop1"="prop2";};
"properties2"=@{"prop1"="prop2";};
};
"service2"=@{
"filePath"="C:\hi2";
"serviceName"="servName2";
"processName"="procName2" ;
"group"=@("ALL");
"properties1"=@{"prop1"="prop2";};
"properties2"=@{"prop1"="prop2";};
};
};
"server2"=@{
"service3"=@{
"filePath"="C:\hi3";
"serviceName"="servName3";
"processName"="procName3" ;
"group"=@("ALL", "SUBSET" )
"properties1"=@{"prop1"="prop2";};
"properties2"=@{"prop1"="prop2";};
};
};
};
Above lets me get list of servers, services on a specific server, etc easily but more importantly it gives an easy way to return a filter-down hashmap to get all info e.g. on a particular server etc
write-host "list of servers:";
$test.keys;
write-host "list of services on server1:";
$test['server1'].keys;
write-host "hashmap of services on server1:";
$test['server1'];
list of servers:
server2
server1
list of services on server1:
service2
service1
hashmap of services on server1:
Name Value
---- -----
service2 {serviceName, processName, properties1, group…}
service1 {serviceName, processName, properties1, group…}
hashmap of SUBSET services:
server2 {service3}
server1 {service1}
I’m a little unsure if there is an elegant way to do more tailored filters that are nested much deeper e.g get the hashmap filtered down to only services that have SUBSET in the group name etc
write-host "hashmap of SUBSET services:";
#expected result
@{
"server1"=@{
"service1"=@{
"filePath"="C:\hi";
"serviceName"="servName1";
"processName"="procName1" ;
"group"=@("ALL", "SUBSET" );
"properties1"=@{"prop1"="prop2";};
"properties2"=@{"prop1"="prop2";};
};
};
"server2"=@{
"service3"=@{
"filePath"="C:\hi3";
"serviceName"="servName3";
"processName"="procName3" ;
"group"=@("ALL", "SUBSET" )
"properties1"=@{"prop1"="prop2";};
"properties2"=@{"prop1"="prop2";};
};
};
};
Only way I can think of is just a huge clunky series of nested for loops which might make it difficult to reuse if I want to do other filters like get hashmap of everything that has a specific serviceName.
Does anyone have any idea? If I can easily access $test['server1'] without a first level for loop, is there a way I can do the same thing for nested fields e.g.
$test(*)(*)[“group”].contains(“SUBSET”)
Thanks for the extra info in your comment.
If you want a filtered result where only services are listed that have keyword 'SUBSET' as one of the values in their 'group' item array, you could do like below:
$filtered = @{} # a new Hashtable object to store the results
foreach ($server in $test.Keys) { # loop over the items in the original Hash
foreach ($service in $test.$server.Keys) {
if ($test.$server.$service.group -contains 'SUBSET') {
$filtered.Add($server,@{$service = $test.$server.$service})
}
}
}
Now, $filtered
contains only Hashtables of servers and their services containing 'SUBSET' in the group item:
Name Value
---- -----
server1 {service1}
server2 {service3}