You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何用PowerShell将Azure活动日志文本转为单行JSON?

问题:将Azure活动日志文本转换为单行JSON格式

我是PowerShell脚本开发新手,需要读取存储Azure活动日志的文本文件,该文件包含多组如下结构的信息块:

Authorization        : 
                       Scope     : /subscriptions/XXXXXXXXXXXXXXXXXXXXXXXXXX/resourceGroups/XXXXXXXXXXXXXXXXXX
                       Action    : Microsoft.ContainerService/managedClusters/listClusterAdminCredential/action
Claims               : 
                       aud            : https://management.core.windows.net/
                       iss            : https://sts.windows.net/XXXXXXXXXXXXXXX/
                       aio            : XXXXXXXXXXXXXXXXXXXXXXXX
                       appidacr       : 2
                       http://schemas.microsoft.com/identity/claims/identityprovider: https://sts.windows.net/XXXXXXXXXXXXXXXXXXXXXXXXXXX/
                       xms_tcdt       : XXXXXXXXXX
HttpRequest          : 
                       ClientId        : XXXXXXXXXXXXXXXXXXXXXXXXXXXX
                       Method          : POST
                       Url             : https://management.azure.com/subscriptions/XXXXXXXXXXXXXXXXXXXXXXX/resourceGroups/XXXXXXXXXXXXXXXX/
                       ClientIpAddress : XX.XX.XX.XX
Properties           : 
                       statusCode     : OK
                       serviceRequestId: 
                       eventCategory  : Administrative
                       entity         : /subscriptions/XXXXXXXXXXXXXXXXXXXXXXX/resourceGroups/XXXXXXXXXXXXXXXXXXXXXX/providers/
Level                : Informational
EventTimestamp       : 8/22/2023 5:59:49 PM
SubStatus            : OK (HTTP Status Code: 200)
Caller               : XXXXXXXXXXXXXXXXXXXXXXXXXX
Id                   : /subscriptions/XXXXXX/resourceGroups/XXXXX/providers/Microsoft.ContainerService/managedClusters/XXXXX/events/XXXXX

期望将其转换为如下单行JSON格式并写入新文件,且文件每小时会追加新数据:

{"Authorization":{"scope":"/subscriptions/XXXXXXXXXXXXXXXXXXXXXXXXXX/resourceGroups/XXXXXXXXXXXXXXXXXX","action":"Microsoft.ContainerService/managedClusters/listClusterAdminCredential/action"},"Claims":{"aud":"https://management.core.windows.net/","iss":"https://sts.windows.net/XXXXXXXXXXXXXXX/","aio":"XXXXXXXXXXXXXXXXXXXXXXXX","appidacr":"2","http://schemas.microsoft.com/identity/claims/identityprovider":"https://sts.windows.net/XXXXXXXXXXXXXXXXXXXXXXXXXXX/","xms_tcdt":"XXXXXXXXXX"},"HttpRequest":{"ClientId":"XXXXXXXXXXXXXXXXXXXXXXXXXXXX","Method":"POST","Url":"https://management.azure.com/subscriptions/XXXXXXXXXXXXXXXXXXXXXXX/resourceGroups/XXXXXXXXXXXXXXXX/","ClientIpAddress":"XX.XX.XX.XX"},"Properties":{"statusCode":"OK","serviceRequestId":"","eventCategory":"Administrative","entity":"/subscriptions/XXXXXXXXXXXXXXXXXXXXXXX/resourceGroups/XXXXXXXXXXXXXXXXXXXXXX/providers/"},"Level":"Informational","EventTimestamp":"8/22/2023 5:59:49 PM","SubStatus":"OK (HTTP Status Code: 200)","Caller":"XXXXXXXXXXXXXXXXXXXXXXXX","Id":"/subscriptions/XXXXXX/resourceGroups/XXXXX/providers/Microsoft.ContainerService/managedClusters/XXXXX/events/XXXXX"}

我已编写初步脚本:

Write-Host " ..... " -ForegroundColor Yellow
$customlogfile = 'C:\azlogs\customlog.txt'

Write-Host "Reading the Activity Log file ..... " -ForegroundColor Yellow
$originfile = 'C:\azlogs\activitylogs.txt'
$originfilecontent = Get-Content -Path $originfile | Where-Object { $_ -ne '' }

Write-Host "Reformatting content of the Activity Log file ..... " -ForegroundColor Yellow
$originfilecontent | Select-String -Pattern 'Authorization' -CaseSensitive -SimpleMatch -Context 1 | Add-Content -Path $customlogfile | ConvertTo-Json

但得到的输出不符合预期:

> Authorization        : 
                         Scope     : /subscriptions/XXXXXXXXXXX/resourceGroups/XXXXXXXXX/
TenantId             : 
> Authorization        : 
                         Scope     : /subscriptions/XXXXXXXXXXX/resourceGroups/XXXXXXXXX/

请求指导如何实现正确的格式化,将日志文本转换为目标单行JSON格式。


解决方案

1. 核心思路

原脚本未正确分割独立日志块,也未解析嵌套键值对。需完成以下步骤:

  • 按Authorization开头分割独立日志块
  • 解析每个块中的嵌套/顶级键值对,转换为PowerShell对象
  • 将对象转为压缩版单行JSON
  • 记录已处理行数,避免重复处理新增内容

2. 完整脚本实现

$originFile = 'C:\azlogs\activitylogs.txt'
$customLogFile = 'C:\azlogs\customlog.txt'
$processedMarkerFile = 'C:\azlogs\processedLineCount.txt'

# 读取已处理行数,跳过已处理内容
$processedLines = if (Test-Path $processedMarkerFile) { [int](Get-Content $processedMarkerFile) } else { 0 }
$content = Get-Content -Path $originFile | Select-Object -Skip $processedLines | Where-Object { $_ -match '\S' }

if (-not $content) {
    Write-Host "无新内容需要处理。" -ForegroundColor Cyan
    exit
}

# 分割日志块:定位所有Authorization行的索引,拆分独立条目
$blockStarts = @(0) + @($content | Select-String -Pattern '^Authorization' -AllMatches | ForEach-Object { $_.LineNumber - 1 })
$blocks = for ($i = 0; $i -lt $blockStarts.Count - 1; $i++) {
    $start = $blockStarts[$i]
    $end = $blockStarts[$i+1] - 1
    $content[$start..$end]
}
$blocks += $content[$blockStarts[-1]..($content.Count - 1)]

# 解析每个日志块为PSObject
$parsedObjects = foreach ($block in $blocks) {
    $obj = [PSCustomObject]@{}
    $currentParent = $null

    foreach ($line in $block) {
        # 匹配顶级父键(如Authorization、Claims)
        if ($line -match '^(\w+)\s*:\s*$') {
            $currentParent = $matches[1]
            $obj | Add-Member -MemberType NoteProperty -Name $currentParent -Value ([PSCustomObject]@{})
            continue
        }

        # 匹配嵌套属性或顶级键值对
        if ($line -match '^\s+([^:]+)\s*:\s*(.*)$') {
            $key = $matches[1].Trim()
            $value = $matches[2].Trim()

            if ($currentParent) {
                $obj.$currentParent | Add-Member -MemberType NoteProperty -Name $key -Value $value
            } else {
                $obj | Add-Member -MemberType NoteProperty -Name $key -Value $value
            }
        }
    }
    $obj
}

# 转换为单行JSON并追加写入
if ($parsedObjects) {
    $parsedObjects | ConvertTo-Json -Compress | Add-Content -Path $customLogFile
    # 更新已处理行数标记
    $processedLines + $content.Count | Set-Content -Path $processedMarkerFile
    Write-Host "成功处理 $($parsedObjects.Count) 条日志条目。" -ForegroundColor Green
} else {
    Write-Host "新增内容中未找到有效日志块。" -ForegroundColor Yellow
}

3. 脚本说明

  • 重复处理规避:通过processedLineCount.txt记录已处理行数,仅处理新增内容,适配每小时追加的场景。
  • 日志块分割:通过定位Authorization行的位置,将文本拆分为独立的日志条目。
  • 嵌套结构解析:识别顶级父键后,将后续缩进行解析为该键的子属性,完整保留原始层级。
  • 单行JSON输出:使用ConvertTo-Json -Compress生成压缩的单行JSON,符合需求格式。

内容的提问来源于stack exchange,提问作者GTGabaaron

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.12 02:07:33