I have a YAML config file that I read values from and is structured as below:
hosts:
- name: server1
role:
- role1
services:
- iis
- sql
- name: server2
role:
- role1
- role4
services:
- iis
- name: server3
role:
- role2
services:
- sql_server
And I read from this YAML config file in a PowerShell script and store the config in a variable called $config
I created empty arrays to then iterate through the list of hosts and store in the corresponding array based on a role as below:
$role1_servers,$role2_servers = @()
$config.hosts | % {
$server_name = $_.name
$_.role | % {
switch($_){
"role1" {
$role1_servers = $server_name
}
"role2" {
$role2_servers = $server_name
}
}
}
}
But instead of adding the values to the relevant array, PowerShell is doing string concatenation rather than adding an item to the array.
When outputting $role1_servers
for example, it would output
server1server2
rather than the desired output of
server1
server2
Is there a way to add the string value as an object to the array rather than string concatenation? I'd need these items in an array to iterate through all servers in a particular role at a later stage.
CodePudding user response:
Continuing from our comments, I think the best thing to do is to create an object array where all server names and roles are present like this:
$allServers = $config.hosts | ForEach-Object {
$server = $_.name
foreach ($role in $_.role) {
[PsCustomObject]@{
Server = $server
Role = $role
}
}
}
Now you can filter out all servers having a certain role
$role1_servers = $allServers | Where-Object { $_.role -eq 'role1' }
$role2_servers = $allServers | Where-Object { $_.role -eq 'role2' }
# etc.
CodePudding user response:
You might consider a ready made module from PS Gallery for handling YAML.
install-module powershell-yaml
$hosts = @'
hosts:
- name: server1
role:
- role1
services:
- iis
- sql
- name: server2
role:
- role1
- role4
services:
- iis
- name: server3
role:
- role2
services:
- sql_server
'@ | ConvertFrom-Yaml | ConvertTo-Json | ConvertFrom-Json
Now you can filter the values you are looking for
$hosts.hosts | where role -like '*role1*'
name services role
---- -------- ----
server1 iis sql role1
server2 iis role1 role4