迁移至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
相关产品推荐
相关产品推荐

