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

Azure Function PowerShell脚本写入Log Analytics指定表报错求助

问题描述

我正在编写Azure Function的PowerShell脚本,目标是将数据写入Log Analytics工作区的指定表(如Table_CL),但执行过程中出现错误。以下是我的脚本内容及具体报错信息,恳请指导如何正确实现该功能:

Install-Module -Name Az.OperationalInsights -Scope CurrentUser -Force

$logAnalyticsClient = Get-AzOperationalInsightsWorkspace -ResourceGroupName "rg-name" -Name "log-analytics-wsp"
 

$WorkspaceId = "/subscriptions/subscriptionID/resourceGroups/rg-name/providers/Microsoft.OperationalInsights/workspaces/log-analytics-wsp"
$SharedKey = "some-value"
$CustomTableName = "Table_CL"


# Obtain an authentication token
$tenantId = 'some value'
$clientId = 'value of Function App identity client IOD'
$Uri = "https://log-analytics-wsp.ods.opinsights.azure.com/api/logs?api-version=2016-04-01"


$Body = @{
    "EventId" = $eventGridEvent.id;
    "eventType" = $eventGridEvent.eventType;
    "subject" = $eventGridEvent.subject;
    "TimeGenerated" = [datetime]$eventGridEvent.eventTime;
    "data" = (ConvertTo-Json -InputObject $eventGridEvent.data);
    "dataVersion" = $eventGridEventvent.dataVersion;
    "metadataVersion" = $eventGridEvent.metadataVersion;
}
$signature = $SharedKey + (get-date -uformat '%a, %d %b %Y %H:%M:%S ')

$hex = ""
foreach ($byte in $signature) {
    $hex += "{0:x2}" -f $byte
}
$Signature = $hex




$Headers = @{
    "Content-Type" = "application/json"
    "Log-Type" = $CustomTableName
    "Authorization" = $Signature
}



# Use the authentication token to send a request to the Log Analytics API
Invoke-WebRequest -Uri $Uri -Method Post -Body $Body -Headers $Headers

报错信息

2023-01-18T19:56:48Z   [Error]   ERROR: The format of value 'some-shared-key-value-==Wed, 18 Jan 2023 19:56:47 GMT' is invalid.

Exception             : 
   Type       : System.FormatException
   TargetSite : 
       Name          : ParseValue
       DeclaringType : System.Net.Http.Headers.HttpHeaderParser, System.Net.Http, Version=6.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a
       MemberType    : Method
       Module        : System.Net.Http.dll
   Message    : The format of value 'some-shared-key-value-Wed, 18 Jan 2023 19:56:47 GMT' is invalid.
   Source     : System.Net.Http
   HResult    : -2146233033
   StackTrace : 
  at System.Net.Http.Headers.HttpHeaderParser.ParseValue(String value, Object storeValue, Int32& index)
  at System.Net.Http.Headers.HttpHeaders.ParseAndAddValue(HeaderDescriptor descriptor, HeaderStoreItemInfo info, String value)
  at Microsoft.PowerShell.Commands.WebRequestPSCmdlet.GetRequest(Uri uri)
  at Microsoft.PowerShell.Commands.WebRequestPSCmdlet.ProcessRecord()
  at System.Management.Automation.Cmdlet.DoProcessRecord()
  at System.Management.Automation.CommandProcessor.ProcessRecord()
CategoryInfo          : NotSpecified: (:) [Invoke-WebRequest], FormatException
FullyQualifiedErrorId : System.FormatException,Microsoft.PowerShell.Commands.InvokeWebRequestCommand
InvocationInfo        : 
   MyCommand        : Invoke-WebRequest
   ScriptLineNumber : 55
   OffsetInLine     : 1
   HistoryId        : 1
   ScriptName       : C:\home\site\wwwroot\EventGridTrigger1\run.ps1
   Line             : Invoke-WebRequest -Uri $Uri -Method Post -Body $Body -Headers $Headers
                       
   PositionMessage  : At C:\home\site\wwwroot\EventGridTrigger1\run.ps1:55 char:1
                      + Invoke-WebRequest -Uri $Uri -Method Post -Body $Body -Headers $Header …
                      + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
   PSScriptRoot     : C:\home\site\wwwroot\EventGridTrigger1
   PSCommandPath    : C:\home\site\wwwroot\EventGridTrigger1\run.ps1
   InvocationName   : Invoke-WebRequest
   CommandOrigin    : Internal
ScriptStackTrace      : at <ScriptBlock>, C:\home\site\wwwroot\EventGridTrigger1\run.ps1: line 55
问题分析与修复方案

核心问题

签名生成逻辑完全不符合Log Analytics API的要求,Authorization头需要遵循特定的HMAC-SHA256签名格式,而非简单拼接SharedKey和时间再转十六进制。同时脚本存在语法错误和逻辑疏漏。

具体修复步骤

  1. 修正签名生成逻辑
    Log Analytics的签名需要对请求内容的哈希值进行HMAC-SHA256加密,再Base64编码,格式为SharedKey <WorkspaceId>:<Base64EncodedSignature>。替换原签名代码为:

    $date = (Get-Date).ToUniversalTime().ToString("r")
    $bodyJson = ConvertTo-Json -InputObject $Body -Compress
    $contentLength = $bodyJson.Length
    
    # 构造签名字符串
    $signatureString = "POST`n$contentLength`napplication/json`nx-ms-date:$date`n/api/logs"
    $encoding = [System.Text.Encoding]::UTF8
    $signatureBytes = $encoding.GetBytes($signatureString)
    $sharedKeyBytes = [System.Convert]::FromBase64String($SharedKey)
    
    # 计算HMAC-SHA256哈希
    $hmacsha256 = New-Object System.Security.Cryptography.HMACSHA256
    $hmacsha256.Key = $sharedKeyBytes
    $hashBytes = $hmacsha256.ComputeHash($signatureBytes)
    $signature = [System.Convert]::ToBase64String($hashBytes)
    
    # 构造Authorization头
    $authorizationHeader = "SharedKey $WorkspaceId`:$signature"
    
  2. 修正Body语法错误
    原脚本中$eventGridEventvent.dataVersion多打了一个vent,应改为$eventGridEvent.dataVersion。同时需将Body转为JSON字符串,因为Invoke-WebRequest的-Body参数需要字符串格式:

    $Body = @{
        "EventId" = $eventGridEvent.id;
        "eventType" = $eventGridEvent.eventType;
        "subject" = $eventGridEvent.subject;
        "TimeGenerated" = [datetime]$eventGridEvent.eventTime;
        "data" = (ConvertTo-Json -InputObject $eventGridEvent.data -Compress);
        "dataVersion" = $eventGridEvent.dataVersion;
        "metadataVersion" = $eventGridEvent.metadataVersion;
    }
    $bodyJson = ConvertTo-Json -InputObject $Body -Compress
    
  3. 修正请求头内容
    添加x-ms-date头,并使用正确格式的Authorization头:

    $Headers = @{
        "Content-Type" = "application/json"
        "Log-Type" = $CustomTableName
        "x-ms-date" = $date
        "Authorization" = $authorizationHeader
    }
    
  4. 修正Invoke-WebRequest调用
    使用转换后的JSON字符串作为请求Body:

    Invoke-WebRequest -Uri $Uri -Method Post -Body $bodyJson -Headers $Headers
    
  5. 移除冗余代码
    Azure Function中不应每次运行都执行Install-Module,建议部署前预先安装模块;未使用的$logAnalyticsClient、$tenantId、$clientId变量可直接删除。

完整修复后的脚本

$WorkspaceId = "/subscriptions/subscriptionID/resourceGroups/rg-name/providers/Microsoft.OperationalInsights/workspaces/log-analytics-wsp"
$SharedKey = "some-value"
$CustomTableName = "Table_CL"

$Uri = "https://log-analytics-wsp.ods.opinsights.azure.com/api/logs?api-version=2016-04-01"

# 构造日志数据
$Body = @{
    "EventId" = $eventGridEvent.id;
    "eventType" = $eventGridEvent.eventType;
    "subject" = $eventGridEvent.subject;
    "TimeGenerated" = [datetime]$eventGridEvent.eventTime;
    "data" = (ConvertTo-Json -InputObject $eventGridEvent.data -Compress);
    "dataVersion" = $eventGridEvent.dataVersion;
    "metadataVersion" = $eventGridEvent.metadataVersion;
}
$bodyJson = ConvertTo-Json -InputObject $Body -Compress
$contentLength = $bodyJson.Length
$date = (Get-Date).ToUniversalTime().ToString("r")

# 生成正确的签名
$signatureString = "POST`n$contentLength`napplication/json`nx-ms-date:$date`n/api/logs"
$encoding = [System.Text.Encoding]::UTF8
$signatureBytes = $encoding.GetBytes($signatureString)
$sharedKeyBytes = [System.Convert]::FromBase64String($SharedKey)

$hmacsha256 = New-Object System.Security.Cryptography.HMACSHA256
$hmacsha256.Key = $sharedKeyBytes
$hashBytes = $hmacsha256.ComputeHash($signatureBytes)
$signature = [System.Convert]::ToBase64String($hashBytes)

$authorizationHeader = "SharedKey $WorkspaceId`:$signature"

# 构造请求头
$Headers = @{
    "Content-Type" = "application/json"
    "Log-Type" = $CustomTableName
    "x-ms-date" = $date
    "Authorization" = $authorizationHeader
}

# 发送请求到Log Analytics API
Invoke-WebRequest -Uri $Uri -Method Post -Body $bodyJson -Headers $Headers

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.04 13:45:24