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

迁移至Microsoft Workflow后Teams Webhook通知格式及链接异常求助

问题描述

此前搭建了扫描Azure Key Vault的流水线,通过Eonos Office Webhook发送Microsoft Teams过期通知(密钥/证书过期或即将过期),运行正常。但因O365连接器被弃用,改用Microsoft Workflows的「收到Webhook请求时发布到频道」Workflow后,通知仅显示纯文本,无规范样式,且密钥链接不可点击;即使启用消息代码视图,保存刷新后仍会回到普通模式。

相关代码:

密钥检查函数

function Check-Secrets {
param(
    [string]$keyVault,
    [string]$globalSubscription,
    [string]$resourceGroup
)

$expiringSecrets = @()
$noExpirySecrets = @()

$secrets = az keyvault secret list --vault-name $keyVault --query "[].id" -o tsv 2>$null
if ($LASTEXITCODE -ne 0) {
    Write-Output "Unable to access Key Vault: $keyVault"
    $global:inaccessibleKeyVaults += $keyVault
    continue
}

foreach ($secret in $secrets) {
    $secretAttributesJson = az keyvault secret show --id $secret --query "attributes" -o json
    $secretAttributes = $secretAttributesJson | ConvertFrom-Json
    $secretName = az keyvault secret show --id $secret --query "name" -o tsv
    $secretUrl = "https://portal.azure.com/#view/Microsoft_Azure_KeyVault/ListObjectVersionsRBACBlade/~/overview/objectType/secrets/objectId/https%3A%2F%2F$keyVault.vault.azure.net%2Fsecrets%2F$secretName/vaultResourceUri/%2Fsubscriptions%2F$globalSubscription%2FresourceGroups%2F$resourceGroup%2Fproviders%2FMicrosoft.KeyVault%2Fvaults%2F$keyVault/vaultId/%2Fsubscriptions%2F$globalSubscription%2FresourceGroups%2F$resourceGroup%2Fproviders%2FMicrosoft.KeyVault%2Fvaults%2F$keyVault"

    if ($null -ne $secretAttributes.expires -and $secretAttributes.expires -ne '') {
        $expiryDate = [DateTime]::Parse($secretAttributes.expires)
        $oneMonthFromNow = (Get-Date).AddMonths(1)

        if ($expiryDate -lt $oneMonthFromNow) {
            $expiringSecrets += "Secret ID: [$secretName]($secretUrl), Expiry Date: $($expiryDate.ToString('yyyy-MM-dd HH:mm:ss'))"
        }
    }
    else {
        $noExpirySecrets += "Secret ID: [$secretName]($secretUrl)"
    }
}


return @{
    "ExpiringSecrets" = $expiringSecrets
    "NoExpirySecrets" = $noExpirySecrets
}
}

调用代码

$expiringSecretsMessage = if ($expiringSecrets.Count -gt 0) { "### 即将过期的密钥<br />" + ($expiringSecrets -join "<br />") }
$noExpirySecretsMessage = if ($noExpirySecrets.Count -gt 0) { "### 无过期时间的密钥<br />" + ($noExpirySecrets -join "<br />") }
$expiringCertificatesMessage = if ($expiringCertificates.Count -gt 0) { "### 即将过期的证书<br />" + ($expiringCertificates -join "<br />") }
$noExpiryCertificatesMessage = if ($noExpiryCertificates.Count -gt 0) { "### 无过期时间的证书<br />" + ($noExpiryCertificates -join "<br />") }

Send-Notification -keyVault $keyVault -WebhookURL $WebhookURL -messageParts @($expiringSecretsMessage, $noExpirySecretsMessage, $expiringCertificatesMessage, $noExpiryCertificatesMessage)
解决方案

问题根源在于:PowerShell发送的消息格式不符合Teams Webhook规范,且Workflow默认配置未正确解析富文本格式。需从两方面调整:

1. 修改PowerShell的Send-Notification函数,发送标准Teams Webhook JSON payload

原函数直接发送文本字符串,需改为发送符合Teams要求的JSON结构(支持Markdown),示例如下:

function Send-Notification {
    param(
        [string]$keyVault,
        [string]$WebhookURL,
        [array]$messageParts
    )

    # 过滤空消息片段
    $validParts = $messageParts | Where-Object { $_ -ne $null }
    if ($validParts.Count -eq 0) {
        Write-Output "No messages to send for Key Vault: $keyVault"
        return
    }

    # 构建Markdown内容,替换HTML换行为Markdown换行
    $markdownContent = "# Azure Key Vault 过期提醒 - $keyVault`n`n" + ($validParts -join "`n`n")
    $markdownContent = $markdownContent -replace "<br />", "`n"

    # 构建Teams MessageCard格式的JSON payload
    $payload = @{
        "@type" = "MessageCard"
        "@context" = "http://schema.org/extensions"
        "summary" = "Azure Key Vault 过期提醒"
        "themeColor" = "FF0000" # 红色提醒色
        "sections" = @(
            @{
                "text" = $markdownContent
            }
        )
    } | ConvertTo-Json -Depth 10

    # 发送POST请求,指定Content-Type为JSON
    try {
        Invoke-RestMethod -Uri $WebhookURL -Method Post -Body $payload -ContentType "application/json"
        Write-Output "Notification sent successfully for Key Vault: $keyVault"
    }
    catch {
        Write-Output "Failed to send notification: $_"
    }
}

2. 调整Microsoft Workflows配置

原模板默认将请求体解析为纯文本,需修改步骤:

  • 步骤1:添加「解析JSON」动作
    在「当收到HTTP请求时」之后,添加「解析JSON」动作,使用以下Schema解析传入的payload:

    {
        "type": "object",
        "properties": {
            "@type": { "type": "string" },
            "@context": { "type": "string" },
            "summary": { "type": "string" },
            "themeColor": { "type": "string" },
            "sections": {
                "type": "array",
                "items": {
                    "type": "object",
                    "properties": {
                        "text": { "type": "string" }
                    }
                }
            }
        }
    }
    

    设置「内容」为「当收到HTTP请求时」的「正文」。

  • 步骤2:修改「发布消息」动作
    将消息内容替换为「解析JSON」输出的sections[0].text,并在「消息格式」选项中选择Markdown(而非纯文本)。

  • 可选:使用自适应卡片增强样式
    若需要更美观的布局,可将payload改为自适应卡片格式,Workflow中选择「发布自适应卡片」动作,示例payload:

    $payload = @{
        "type" = "AdaptiveCard"
        "version" = "1.0"
        "body" = @(
            @{
                "type" = "TextBlock"
                "size" = "Large"
                "weight" = "Bolder"
                "text" = "Azure Key Vault 过期提醒 - $keyVault"
            },
            @{
                "type" = "TextBlock"
                "text" = $markdownContent
                "wrap" = $true
            }
        )
    } | ConvertTo-Json -Depth 10
    
关键说明
  • Teams Webhook支持MessageCard和AdaptiveCard两种格式,均需确保请求的Content-Type为application/json。
  • Workflow的「发布消息」动作必须设置为Markdown格式,否则会将所有内容解析为纯文本,导致链接失效。
  • 统一使用Markdown语法(如\n换行),避免混用HTML标签。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.18 11:48:11