Home > Mobile >  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

Time:12-07

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
  • Related