0

My PowerShell(version 5.1.19041.906) command azsphere device-group list --tenant <GUID> give data as below

Result:

 -------- -------- -------- -------- -------- -------- -------- -------- 
 Id       Name     Descript ProductI OsFeedTy UpdatePo AllowCra CurrentD 
                   ion      d        pe       licy     shDumpsC eploymen 
                                                       ollectio t        
                                                       n                 
 ======================================================================= 
 ba7fab67 Developm Default  556957b4 Retail   Accept o False    None     
 -5cd7-40 ent      developm -aa39-4e          nly syst                   
 1a-9c88-          ent devi 5a-aa4c-          em softw                   
 c4a2e88f          ce group d3208c27          are upda                   
 6932                       7f3c              tes. Don                   
                                              't accep                   
 -------- -------- -------- -------- -------- -------- -------- -------- 
 45acb705 Field Te FieldTes 556957b4 Retail   Accept a False    d684d491 
 -a591-4e st       t        -aa39-4e          ll updat          -9229-48 
 41-ba1e-                   5a-aa4c-          es from           4f-a2eb- 
 4b3dd062                   d3208c27          the Azur          fda0168f 
 e1ec                       7f3c              e Sphere          7e27     
                                               Securit                   
 -------- -------- -------- -------- -------- -------- -------- -------- 
 07c76f21 Producti Default  556957b4 Retail   Accept a False    None     
 -773e-4e on       producti -aa39-4e          ll updat                   
 0a-ad29-          on devic 5a-aa4c-          es from                    
 569af4eb          e group  d3208c27          the Azur                   
 24a8                       7f3c              e Sphere                   
                                               Securit                   
 -------- -------- -------- -------- -------- -------- -------- -------- 
 0e2aed60 Producti Default  556957b4 RetailEv Accept a False    None     
 -41ba-49 on OS Ev Producti -aa39-4e al       ll updat                   
 74-9bfb- aluation on OS Ev 5a-aa4c-          es from                    
 cdee6e1c          aluation d3208c27          the Azur                   
 0fc5               device  7f3c              e Sphere                   
                   group                       Securit                   
 -------- -------- -------- -------- -------- -------- -------- -------- 
 8bb2b77c Field Te Default  556957b4 RetailEv Accept a False    None     
 -3839-4b st OS Ev Field Te -aa39-4e al       ll updat                   
 09-b57d- aluation st OS Ev 5a-aa4c-          es from                    
 3f20081c          aluation d3208c27          the Azur                   
 d161               device  7f3c              e Sphere                   
                   group                       Securit                   
 -------- -------- -------- -------- -------- -------- -------- -------- 

From the above result, I want to get ID where Description is equal to FieldTest

I tried this command, it wont work, because, result is not in proper list format.

((azsphere device-group list --tenant $myTenantId) -split '\n') | Select-String -Pattern 'FieldTest'

Also tried doing something like this but no difference

((azsphere device-group list --tenant $myTenantId) -split '\n') | select -Skip 1 | Select-Object Id, Name | Format-Table -AutoSize -Wrap

When I use this command, nothing returns. Not sure what is the object returned by the azsphere exe

azsphere dev....... | Where-Object {$_.Description -eq 'FieldTest'}

enter image description here

10
  • What object type does azsphere returns? I mean prior to splitting on \n. Commented May 25, 2021 at 14:01
  • If azsphere was returning PSObjects you could do (azsphere dev....... | Where-Object {$_.Description -eq 'FieldTest'}).ID... Do you see an option to have it return a Csv? Commented May 25, 2021 at 14:14
  • @SantiagoSquarzon I had hoped for the same, something like schedtasks.exe, however it doesn't look like it AZShere Doc . Commented May 25, 2021 at 14:30
  • Is the table wrapping cells natural output from the application or did you do that for display purposes. If the former it'll make parsing more difficult. Commented May 25, 2021 at 14:31
  • @Steven the wrapping seems to be a behavior of the PS Host by looking at the docs. It's curious how these guys don't have a compatible PS module. Commented May 25, 2021 at 14:38

1 Answer 1

1

Hmmm indeed strange output to parse.. I'm using a Here-String to mimic the file , but in real life you'd probably want to load it from a file.
In that case, make sure you read it as one single, multiline string using the -Raw switch:

$txt = Get-Content -Path 'D:\Test\azsphereOutput.txt' -Raw

If the output is given as an array of strings, combine these into a single multiline string using:

$txt = (azsphere device-group list --tenant $myTenantId) -join [environment]::NewLine

Next the code:

$txt = @"
 -------- -------- -------- -------- -------- -------- -------- -------- 
 Id       Name     Descript ProductI OsFeedTy UpdatePo AllowCra CurrentD 
                   ion      d        pe       licy     shDumpsC eploymen 
                                                       ollectio t        
                                                       n                 
 ======================================================================= 
 ba7fab67 Developm Default  556957b4 Retail   Accept o False    None     
 -5cd7-40 ent      developm -aa39-4e          nly syst                   
 1a-9c88-          ent devi 5a-aa4c-          em softw                   
 c4a2e88f          ce group d3208c27          are upda                   
 6932                       7f3c              tes. Don                   
                                              't accep                   
 -------- -------- -------- -------- -------- -------- -------- -------- 
 45acb705 Field Te FieldTes 556957b4 Retail   Accept a False    d684d491 
 -a591-4e st       t        -aa39-4e          ll updat          -9229-48 
 41-ba1e-                   5a-aa4c-          es from           4f-a2eb- 
 4b3dd062                   d3208c27          the Azur          fda0168f 
 e1ec                       7f3c              e Sphere          7e27     
                                               Securit                   
 -------- -------- -------- -------- -------- -------- -------- -------- 
 07c76f21 Producti Default  556957b4 Retail   Accept a False    None     
 -773e-4e on       producti -aa39-4e          ll updat                   
 0a-ad29-          on devic 5a-aa4c-          es from                    
 569af4eb          e group  d3208c27          the Azur                   
 24a8                       7f3c              e Sphere                   
                                               Securit                   
 -------- -------- -------- -------- -------- -------- -------- -------- 
 0e2aed60 Producti Default  556957b4 RetailEv Accept a False    None     
 -41ba-49 on OS Ev Producti -aa39-4e al       ll updat                   
 74-9bfb- aluation on OS Ev 5a-aa4c-          es from                    
 cdee6e1c          aluation d3208c27          the Azur                   
 0fc5               device  7f3c              e Sphere                   
                   group                       Securit                   
 -------- -------- -------- -------- -------- -------- -------- -------- 
 8bb2b77c Field Te Default  556957b4 RetailEv Accept a False    None     
 -3839-4b st OS Ev Field Te -aa39-4e al       ll updat                   
 09-b57d- aluation st OS Ev 5a-aa4c-          es from                    
 3f20081c          aluation d3208c27          the Azur                   
 d161               device  7f3c              e Sphere                   
                   group                       Securit                   
 -------- -------- -------- -------- -------- -------- -------- -------- 
"@

# create a List object to store the result in (build a CSV really)
$list = [System.Collections.Generic.List[string]]::new()

# split the text on the '=============' line to separate the header block from the data
$hdrBlock, $dataBlock = $txt -split '(?m)^[\s=]+$' -ne ''

# Next proceed by getting the columnwidths. It so happens that in this case all columns 
# have the same width, but you can never be sure of that..
# split the header block in separate lines, remove possible empty or whitespace-only lines
# and remove the single leading and trailing spaces 
$hdrLines   = ($hdrBlock -split '\r?\n' | Where-Object { $_ -match '\S' }) -replace '^\s|\s$'
$colWidths  = ($hdrLines[0].Trim() -split '\s+') | ForEach-Object { $_.Length + 1 }
$fieldCount = $colWidths.Count
# create a regex string like '^(.{9})(.{9})(.{9})(.{9})(.{9})(.{9})(.{9})(.*)'
$fieldBreaks = '^' + (-join ($colWidths | ForEach-Object { "(.{$_})" })) -replace '\(.{\d}\)$', '(.*)'

# We can now parse the first (headers) block by reassembling the wrapped lines
# start from index 1 here to skip the dashed line above the headers
$lines = for ($i = 1; $i -lt $hdrLines.Count; $i++) {  
    # the unary leading comma ensures $lines will be an array of arrays
    ,($hdrLines[$i] -split $fieldBreaks -ne '')
}
# vertically, join whatever is in the columns as wrapped text
$headers = for ($j = 0; $j -lt $fieldCount; $j++) {
    $column = for ($k = 0; $k -lt $lines.Count; $k++) {
        $lines[$k][$j].Trim()
    }
    # join the wrapped stuff together to form the field content as quoted value
    '"{0}"' -f ($column -join '')
}

# add the completed line to the List
$list.Add($headers -join ',')

# Proceed with the data in $dataBlock
# split each data sub block and loop through
$dataBlock -split '(?m)^[\s-]+$' -ne '' | ForEach-Object {
    # split this data block in separate lines, , remove possible empty or whitespace-only lines
    # and remove the single leading and trailing spaces 
    $data = ($_ -split '\r?\n' | Where-Object { $_ -match '\S' }) -replace '^\s|\s$'
    $lines = for ($i = 0; $i -lt $data.Count; $i++) {
        ,($data[$i] -split $fieldBreaks -ne '')
    }
    $row = for ($j = 0; $j -lt $fieldCount; $j++) {
        $column = for ($k = 0; $k -lt $lines.Count; $k++) {
            $lines[$k][$j].Trim()
        }
        # join the wrapped stuff together to form the field content as quoted value
        '"{0}"' -f ($column -join '')
    }
    # add the completed line to the List
    $list.Add($row -join ',')
}

# use ConvertFrom-Csv to convert the CSV we now have in $list into an array of objects
$result = $list | ConvertFrom-Csv

# Display via Out-GridView, because it won't fit the console in table format
$result | Out-GridView -Title 'azsphere Result'

# and/or you could save it as csv file
$result | Export-Csv -Path 'D:\Test\azsphereResult.csv' -NoTypeInformation

Now you can easily filter out the objects you need, like get the ID where Description is equal to FieldTest:

($result | Where-Object { $_.Description -eq 'FieldTest' }).Id  # --> 45acb705-a591-4e41-ba1e-4b3dd062e1ec

Oh yes, nearly forgot.. This is what the result looks like in the GridView:

enter image description here

Sign up to request clarification or add additional context in comments.

1 Comment

That's a cool parser snippet Worked like a charm!

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.