Parsing String into Custom Object with Powershell and regex

Viewed 192

I have a String, which I try to parse into a array of PSCustom Object with sub expression.

The String looks like this :

date=2021-09-13 time=20:05:25 devname="chwitrfg01" devid="FG10E0TB20903187" logid="0000000013" type="traffic" subtype="forward" level="notice" vd="root" eventtime=1631556325 srcip=192.168.10.226 srcname="192.168.10.226" srcport=54809 srcintf="port8" srcintfrole="dmz" dstip=8.8.4.4 dstname="dns.google" dstport=53 dstintf="wan1" dstintfrole="lan" poluuid="01533038-da7b-51eb-b854-8fd38a0deba3" sessionid=1472996904 proto=17 action="accept" policyid=278 policytype="policy" service="DNS" dstcountry="United States" srccountry="Reserved" trandisp="snat" transip=194.56.218.226 transport=54809 duration=180 sentbyte=245 rcvdbyte=144 sentpkt=2 rcvdpkt=1 shapersentname="default_class" shaperdropsentbyte=0 shaperrcvdname="default_class" shaperdroprcvdbyte=0 appcat="unscanned" dstdevtype="Unknown" dstdevcategory="None" masterdstmac="00:00:0c:07:ac:8d" dstmac="00:00:0c:07:ac:8d" dstserver=1

And I tried something like this, but I'm a total noob in regex and have no Idea how to solve this. Is there a easy way, to add each value to a property of the custom object?

$Pattern = @(
    '(?<devname>\devname=w+)'
    '(?<srcip>(srcip=?:[0-9]+\.){3}[0-9]+):(?<srcport>srcport=[0-9]+)'
    '(?<dstip>(dstip=?:[0-9]+\.){3}[0-9]+):(?<dstport>dstport=[0-9]+)'
    
) -join '\s+'

$cmd |
    ForEach-Object {
    if ($_ -match $Pattern) {
    $Matches.Remove(0)
        [PsCustomObject]@{
            srcip = $_.Groups['srcip'].Value
            dstip = $_.Groups['dstip'].Value
            dstport = $_.Groups['dstport'].Value
            srcport = $_.Groups['srcport'].Value
            fw = $_.Groups['devname'].Value
        }
      }
    }| Select-Object -First 5
$cmd  | Format-Table
1 Answers

The simplest way to do this that I know of us the ConvertFrom-StringData cmdlet. That cmdlet creates a hashtable of name/value pairs out of a set of name=value formatted things. What you would do is put each value on its own line to make a multi-ling string, then create a new custom object, and use that hashtable to define the properties.

$cmd -replace ' (\w+=)',"`n`$1"|
    %{new-object psobject -prop (ConvertFrom-StringData $_)}

Or the shorter version in v3+ (thanks to @mklement0):

$cmd -replace ' (\w+=)',"`n`$1"|
    %{[pscustomobject] (ConvertFrom-StringData $_)}

When I ran that against the string you provided I got back:

sessionid          : 1472996904
action             : "accept"
rcvdbyte           : 144
vd                 : "root"
logid              : "0000000013"
policyid           : 278
duration           : 180
proto              : 17
dstname            : "dns.google"
srcintf            : "port8"
eventtime          : 1631556325
appcat             : "unscanned"
srcip              : 192.168.10.226
dstip              : 8.8.4.4
trandisp           : "snat"
srcname            : "192.168.10.226"
srcport            : 54809
devid              : "FG10E0TB20903187"
dstdevcategory     : "None"
level              : "notice"
sentbyte           : 245
shaperdroprcvdbyte : 0
sentpkt            : 2
masterdstmac       : "00:00:0c:07:ac:8d"
shaperrcvdname     : "default_class"
poluuid            : "01533038-da7b-51eb-b854-8fd38a0deba3"
type               : "traffic"
srcintfrole        : "dmz"
subtype            : "forward"
policytype         : "policy"
dstport            : 53
transip            : 194.56.218.226
shapersentname     : "default_class"
dstdevtype         : "Unknown"
dstserver          : 1
dstcountry         : "United States"
dstintf            : "wan1"
service            : "DNS"
srccountry         : "Reserved"
shaperdropsentbyte : 0
dstintfrole        : "lan"
transport          : 54809
date               : 2021-09-13
rcvdpkt            : 1
dstmac             : "00:00:0c:07:ac:8d"
devname            : "chwitrfg01"
time               : 20:05:25

You could probably strip quotes out of it if that is desired.

Related