Adding String Value Converted From YAML File To PowerShell Array As An Object

Adding String Value Converted From YAML File To PowerShell Array As An Object

Problem Description:

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.

Solution – 1

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.

Solution – 2

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
Rate this post
We use cookies in order to give you the best possible experience on our website. By continuing to use this site, you agree to our use of cookies.
Accept
Reject