将防火墙日志转换为 Powershell 哈希表

Convert firewall log to Powershell hashtable

我有一个 Sophos UTM 的防火墙日志,其中包含几个条目,看起来类似于最后的示例(每个条目都是一行)。

我想编写一个 Powershell 脚本来统计特定规则匹配的频率以及诸如此类的内容。为了执行这些分析,我想将日志的每一行转换为哈希表,以便我可以轻松访问条目的信息。

有什么奇特的方法可以代替遍历包含一行防火墙日志和匹配字符的字符串(例如,搜索“=”,然后在该字符串的左侧和右侧搜索获取属性和相应值的位置)找到属性值对?

任何有关如何将数据转换为可用格式的帮助和想法都将不胜感激!

2021:09:08-00:02:45 fwtest ulogd[4040]: id="2021" severity="info" sys="SecureNet" sub="packetfilter" name="Packet dropped" action="drop" fwrule="60019" initf="eth2" srcmac="01:23:45:67:89:ab" dstmac="ba:98:76:54:32:10" srcip="10.0.0.1" dstip="10.0.1.1" proto="17" length="96" tos="0x00" prec="0x00" ttl="45" srcport="1234" dstport="4321"

Is there any fancy way to do it instead of iterating over a string

您采用的任何方式都将涉及某种形式的读取和解析字符串。您可以通过使用正则表达式来匹配 name="value" 对来简化所需的代码:

# Replace this string array with `Get-Content path\to\log\file(s).log` 
@(
  '2021:09:08-00:02:45 fwtest ulogd[4040]: id="2021" severity="info" sys="SecureNet" sub="packetfilter" name="Packet dropped" action="drop" fwrule="60019" initf="eth2" srcmac="01:23:45:67:89:ab" dstmac="ba:98:76:54:32:10" srcip="10.0.0.1" dstip="10.0.1.1" proto="17" length="96" tos="0x00" prec="0x00" ttl="45" srcport="1234" dstport="4321"'
) |Select-String -Pattern '\b(\w+)\="([^"]+)"' -AllMatches |ForEach-Object {
  # Create an ordered dictionary to hold the name-value pairs
  $props = [ordered]@{}

  # Iterate over each pair found by Select-String
  $_.Matches |ForEach-Object {
    # Add each name-value pair to the dictionary
    $props[$_.Groups[1].Value] = $_.Groups[2].Value
  }

  # Convert dictionary to PSObject
  [pscustomobject]$props
}

这将为每个日志行生成 1 个新对象,您可以使用 Where-ObjectGroup-ObjectMeasure-Object 等内置实用程序来处理这些对象

使用的正则表达式模式 (\b(\w+)\="([^"]+)") 描述:

\b          # match a word boundary
  (         # capture group start
   \w+      # match 1 or more word characters (letters or numbers)
  )         # capture group end
  \="       # match a literal = followed by "
  (         # capture group start
   [^"]+    # match 1 or more of any characters except "
  )         # capture group end
  "         # match a literal "