Alessandro
Alessandro

Reputation: 313

Powershell - How to get data within delimiters and manipulate the data

I'm using Powershell to write a script which based on an input file splits each section and manipulates the underlying data. In practical terms, i have a TXT file which is formatted like so:

-------Group_Name_1-------
member: Name:Host1 Handle:123
member: Name:Host2 Handle:213
member: Name:Host3 Handle:321

-------Group_Name_2-------
member: Name:Host10 Handle:1230
member: Name:Host20 Handle:2130

Group (member of): Firewall subnet
etc...

So far, I've come up with the following script:

$filepath = 'C:\test.txt'
$getfile = Get-Content $filepath -Raw

$regex_group_name = '.*-------'

foreach($object in $splitfile){
$lines = $object.Split([Environment]::NewLine)

$data_group_name = @($lines) -match $regex_group_name
$data_group_value = $data_group_name -replace '-------' , ''

Write-Host $data_group_value
}

I'm trying to achieve the following output for each group (for example):

add group name Group_Name_1 members.1 "Host1" members.2 "Host2" members.3 "Host3" groups.1 "Firewall Subnet"

And I'm stuck in 2 parts:

1) The script above, obviously won't work, because the "split" function will basically remove the group name: how can I approach this problem in order to get the desired output?

2) I have no idea on how to change the output in order to reflect the effective number of members (if the members are 2, it will only output members.1 and members.2; alternatively members.1, members.2, members.3 etc...).

Thanks in advance for your help.

Upvotes: 0

Views: 174

Answers (1)

Tomalak
Tomalak

Reputation: 338208

I would solve this in two steps.

  • First, parse the file into a data structure (in this case, an array of PSCustomObjects)
  • Then, convert those into the command strings.

Assuming this $fileContent

$fileContent = "-------Group_Name_1-------
member: Name:Host1 Handle:123
member: Name:Host2 Handle:213
member: Name:Host3 Handle:321

-------Group_Name_2-------
member: Name:Host10 Handle:1230
member: Name:Host20 Handle:2130

Group (member of): Firewall subnet
etc..."

We can build step 1 like this:

$sections = $fileContent -split "(?m)^-------" 

$groups = foreach ($section in $sections) {
    $group = [pscustomobject]@{
        Name     = ([regex]"(.*)-------").Match($section).Groups[1].Value
        Members  = @(([regex]"member: Name:(\S+)").Matches($section) | ForEach-Object {
            $_.Groups[1].Value
        })
        MemberOf = @(([regex]"Group \(member of\): (.+)").Matches($section) | ForEach-Object {
            $_.Groups[1].Value
        })
    }
    if ($group.Name) {
        $group
    }
}

# intermediate results (parsed group structure)
$groups

This prints

Name         Members               MemberOf          
----         -------               --------          
Group_Name_1 {Host1, Host2, Host3} {}                
Group_Name_2 {Host10, Host20}      {Firewall subnet}

Now it's easy to turn this into a different format:

$commands = foreach ($group in $groups) {
    $str = "add group "
    $str += "name `"$( $group.Name )`" "
    $i = 1
    foreach ($member in $group.Members) {
        $str += "members.$i `"$member`" "
        $i++
    }
    $i = 1
    foreach ($memberOf in $group.MemberOf) {
        $str += "groups.$i `"$memberOf`" "
        $i++
    }
    $str.Trim()
}

# final results (command strings)
$commands

Which prints:

add group name "Group_Name_1" members.1 "Host1" members.2 "Host2" members.3 "Host3"
add group name "Group_Name_2" members.1 "Host10" members.2 "Host20" groups.1 "Firewall subnet"

Upvotes: 2

Related Questions