0

I am trying to parse the output of a rest api query of the form

$response = Invoke-RestMethod -Uri $uri -Headers $headers
$response.name | Select-String -Pattern ^role

returns an output similar to this below (elements separated by ::)

role::servicing2
role::collaboration::lei
role::commercial_lines::npds
role::nvp::windows::ucce_gold
role::oracle::linux::oracle_oid
role::splunk::splunk_enterprise::add_on

I need to read this output line by line and parse.

If there are just 2 elements eg. role::servicing2 ignore the line
If there are 3 elements, ignore the first element "role", prepend puppet_ to the second element and it becomes the project, the third element is the role (OS is unknown)
If there are 4 or more elements, ignore the first element "role", prepend puppet_ to the second element and it becomes the project, if the third element is "windows" or "linux" that is the OS, else OS is "unknown", and the last element \:\:'(\w+)'$ is the role.

Need an output in the form of an array or table or list in this format (Don't necessarily need header)

Project         OS      Role

puppet_collaboration    unknown     lei
puppet_commercial_lines unknown     npds
puppet_nvp      windows     ucce_gold
puppet_oracle       linux       oracle_oid
puppet_splunk       unknown     add_on

I have tried various regex expressions. Couldn't figure out the logic of walking this line by line and parsing appropriately into a list or array.

2
  • "I have tried various regex expressions. Couldn't figure out the logic of walking this line by line and parsing appropriately into a list or array." - can you share what you tried so far, and how it failed? :) Commented Sep 27, 2019 at 13:11
  • I was trying to parse along the lines of $response.name | Select-String -Pattern ^role\:\:'(\w+)'\:\:'(\w+)'$ | foreach {$_.Matches.Groups[2].Value}. Not sure how to add all the logic above. Commented Sep 27, 2019 at 13:58

1 Answer 1

2

I think below code should do what you want:

$roles = @'
role::servicing2
role::collaboration::lei
role::commercial_lines::npds
role::nvp::windows::ucce_gold
role::oracle::linux::oracle_oid
role::splunk::splunk_enterprise::add_on
'@ -split '\r?\n'

$result = $roles | ForEach-Object {
    $parts = $_ -split '::'
    switch ($parts.Count) {
        2 { continue }  # ignore this line
        3 { 
            [PsCustomObject]@{
                'Project' = 'puppet_{0}' -f $parts[1]
                'OS'      = 'unknown'
                'Role'    = $parts[2]
            }
        }
        default {
            [PsCustomObject]@{
                'Project' = 'puppet_{0}' -f $parts[1]
                'OS'      = if ('windows', 'linux' -contains $parts[2]) {$parts[2]} else {'unknown'}
                'Role'    = $parts[-1]
            }        
        }
    }
}

# output on screen
$result

# output to CSV file
$result | Export-Csv -Path 'D:\roles.csv' -NoTypeInformation

For testing I have put the result of your $response.name | Select-String -Pattern ^role in a here-string.

Output:

Project                 OS      Role      
-------                 --      ----      
puppet_collaboration    unknown lei       
puppet_commercial_lines unknown npds      
puppet_nvp              windows ucce_gold 
puppet_oracle           linux   oracle_oid
puppet_splunk           unknown add_on
Sign up to request clarification or add additional context in comments.

1 Comment

This worked great. Thank you very much. I learned a lot from it.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.