PowerShell添加CC和BCC时报错:哈希字面量中键后缺少'='
报错信息
At line:60 char:11 + if ($ccEmailAddress) { + ~ Missing '=' operator
after key in hash literal. At line:71 char:9 + } + ~ Missing closing
')' in subexpression. At line:72 char:5 + } + ~ Missing closing ')' in
subexpression. At line:73 char:1 + ) + ~ Unexpected token ')' in
expression or statement. At line:74 char:1 + } + ~ Unexpected token
'}' in expression or statement. At line:76 char:1 + from = @{ + ~~~~
The 'from' keyword is not supported in this version of the language.
At line:86 char:1 + } + ~ Unexpected token '}' in expression or
statement.
传入的JSON数据
{ "destEmailAddress": "to@abc.com", "fromEmailAddress": "from@abc.com", "subject": "mailSubject", "content": "mailContent", "ccEmailAddresses": ["cc1@abc.com","cc2@abc.com"], "bccEmailAddresses": [] }
注:原传入数据存在格式错误,已修正为标准JSON格式
问题脚本代码
param ( [Parameter(Mandatory=$false)] [object] $WebhookData ) write-output "start" write-output ("object type: {0}" -f $WebhookData.gettype()) write-output $WebhookData write-output "`n`n" if ($WebhookData.RequestBody) { $details = (ConvertFrom-Json -InputObject $WebhookData.RequestBody) foreach ($x in $details) { $destEmailAddress = $x.destEmailAddress Write-Output "To - $destEmailAddress" $fromEmailAddress = $x.fromEmailAddress Write-Output "From - $fromEmailAddress" $subject = $x.subject Write-Output "Subject Line - $subject" $content = $x.content Write-Output "Mail Body - $content" # Optional CC and BCC as arrays $ccEmailAddresses = $x.ccEmailAddress $bccEmailAddresses = $x.bccEmailAddress } } else { Write-Output "No details received" } Disable-AzContextAutosave -Scope Process $SENDGRID_API_KEY = "XYZ" $headers = New-Object "System.Collections.Generic.Dictionary[[String],[String]]" $headers.Add("Authorization", "Bearer " + $SENDGRID_API_KEY) $headers.Add("Content-Type", "application/json") $body = @{ personalizations = @( @{ to = @( @{ email = $destEmailAddress } ) } ) } if ($ccEmailAddresses) { $cc = @() foreach ($ccAddress in $ccEmailAddresses) { $cc += @{ email = $ccAddress } } $body.personalizations[0].cc = $cc } if ($bccEmailAddresses) { $bcc = @() foreach ($bccAddress in $bccEmailAddresses) { $bcc += @{ email = $bccAddress } } $body.personalizations[0].bcc = $bcc } $body.from = @{ email = $fromEmailAddress } $body.subject = $subject $body.content = @( @{ type = "text/html" value = $content } ) $bodyJson = $body | ConvertTo-Json -Depth 4 $response = Invoke-RestMethod -Uri https://api.sendgrid.com/v3/mail/send -Method Post -Headers $headers -Body $bodyJson
问题排查与修复方案
1. 变量名不匹配
脚本中使用$ccEmailAddress和$bccEmailAddress,但传入的JSON字段是ccEmailAddresses和bccEmailAddresses(复数形式),导致变量未正确赋值,后续逻辑出错。
修复:将变量名改为与JSON字段一致:
$ccEmailAddresses = $x.ccEmailAddresses $bccEmailAddresses = $x.bccEmailAddresses
2. 传入JSON格式错误
原JSON中CC/BCC数组被包裹在单引号中(如'['cc1@abc.com','cc2@abc.com']'),这会被解析为字符串而非数组。标准JSON需使用双引号,数组直接定义无需外层引号。
修复:修正传入的JSON格式为标准结构(如上方修正后的JSON示例)。
3. 邮件逻辑位置错误
原脚本将邮件构造与发送逻辑放在foreach循环外部,若$details包含多个条目,只会使用最后一个条目的变量值;若未进入循环,变量为空会触发语法错误。
修复:将邮件构造、CC/BCC处理、发送逻辑全部移入foreach循环内部。
4. 空地址过滤
当BCC字段传入空数组或包含空字符串时,需过滤无效地址,避免SendGrid API报错。
修复:处理CC/BCC时添加空值过滤:
foreach ($ccAddress in $ccEmailAddresses | Where-Object { $_ -and $_ -match '\S' }) { # ... }
修复后的完整脚本
param ( [Parameter(Mandatory=$false)] [object] $WebhookData ) Write-Output "start" Write-Output ("object type: {0}" -f $WebhookData.GetType()) Write-Output $WebhookData Write-Output "`n`n" Disable-AzContextAutosave -Scope Process $SENDGRID_API_KEY = "XYZ" if ($WebhookData.RequestBody) { $details = ConvertFrom-Json -InputObject $WebhookData.RequestBody foreach ($x in $details) { $destEmailAddress = $x.destEmailAddress Write-Output "To - $destEmailAddress" $fromEmailAddress = $x.fromEmailAddress Write-Output "From - $fromEmailAddress" $subject = $x.subject Write-Output "Subject Line - $subject" $content = $x.content Write-Output "Mail Body - $content" # 匹配JSON字段名,获取CC/BCC数组 $ccEmailAddresses = $x.ccEmailAddresses $bccEmailAddresses = $x.bccEmailAddresses # 构造请求头 $headers = New-Object "System.Collections.Generic.Dictionary[[String],[String]]" $headers.Add("Authorization", "Bearer " + $SENDGRID_API_KEY) $headers.Add("Content-Type", "application/json") # 初始化邮件主体 $body = @{ personalizations = @( @{ to = @( @{ email = $destEmailAddress } ) } ) from = @{ email = $fromEmailAddress } subject = $subject content = @( @{ type = "text/html" value = $content } ) } # 处理CC地址(过滤空值) if ($ccEmailAddresses) { $cc = @() foreach ($ccAddress in $ccEmailAddresses | Where-Object { $_ -and $_ -match '\S' }) { $cc += @{ email = $ccAddress } } if ($cc.Count -gt 0) { $body.personalizations[0].cc = $cc } } # 处理BCC地址(过滤空值) if ($bccEmailAddresses) { $bcc = @() foreach ($bccAddress in $bccEmailAddresses | Where-Object { $_ -and $_ -match '\S' }) { $bcc += @{ email = $bccAddress } } if ($bcc.Count -gt 0) { $body.personalizations[0].bcc = $bcc } } # 转换为JSON并发送邮件 $bodyJson = $body | ConvertTo-Json -Depth 4 Write-Output "Request Body: $bodyJson" $response = Invoke-RestMethod -Uri https://api.sendgrid.com/v3/mail/send -Method Post -Headers $headers -Body $bodyJson Write-Output "Email sent successfully. Response: $response" } } else { Write-Output "No details received" }
内容的提问来源于stack exchange,提问作者Sivaani

