Azure Automation中MSGraph无法识别嵌套邮件附件内容的问题
问题描述
我有一个Azure Automation Runbook,用于从Outlook邮件中获取附件并在虚拟机上进行转换。近期更新MSGraph密钥后,代码部分功能失效:直接附加的Excel文件可正常处理,但嵌套在邮件附件中的Excel或ZIP文件无法处理。
现有代码逻辑
- 通过
Invoke-GraphRequest获取邮件附件列表 - 若附件包含
contentBytes字段,直接调用HandleAttachment处理Excel文件 - 处理嵌套邮件附件时,调用
$value端点获取RFC822格式内容,尝试通过匹配boundary提取Excel文件,或匹配contentDisposition提取ZIP文件的Base64内容
当前遇到的问题
- 无法匹配到
$boundaryMatches或$contentDisposition - Azure Automation测试面板无法输出调试信息,无法查看
$rfc822的内容 - Runbook在处理嵌套附件的函数中无限运行,需手动停止
相关代码片段
Write-Host "Downloading attachments:`n`tMessageId: $($mail.internetMessageId)`n`tSubject: $($mail.subject)" $files = @() $r_att = Invoke-GraphRequest "https://graph.microsoft.com/v1.0/me/messages/$($mail.id)/attachments" -AccessToken $token ($r_att.Result.Content | ConvertFrom-Json).value | ForEach-Object { if ($_.contentBytes) { $f = HandleAttachment $_ if ($f) { $files += $f } } else { Write-Host "Handling nested attachment: $($_.name)" $v = Invoke-GraphRequest "https://graph.microsoft.com/v1.0/me/messages/$($mail.id)/attachments/$($_.id)/`$value" -AccessToken $token $rfc822 = $v.Result.Content -replace "`r", '' -split "`n" $boundaryMatches = $rfc822 | Select-String -Pattern '^Content-Type: multipart/mixed;boundary="?(.*?)"?$' -AllMatches if ($boundaryMatches) { $boundaryMatches | ForEach-Object { $region = $_.Matches[0].Groups[1].Value Write-Host "Found boundary: $region" $region_start = $rfc822.IndexOf("--$region") $region_end = $rfc822.IndexOf("--$($region)--") if ($region_start -ne -1 -and $region_end -ne -1) { $content = $rfc822[($region_start + 4) .. ($region_end - 1)] $f = "$([System.IO.Path]::GetTempFileName()).xlsx" [System.IO.File]::WriteAllBytes($f, ($content -join "`r`n").ToCharArray()) $files += $f } else { Write-Warning "Could not find start or end of region for boundary: $region" } } } else { $contentDisposition = $rfc822 | Select-String -Pattern '^Content-Disposition: attachment; filename=(.*\.zip)$' if ($contentDisposition) { $zipFileName = $contentDisposition.Matches.Groups[1].Value Write-Host "Found zip file: $zipFileName" $base64StartLine = $rfc822 | Select-String -Pattern "^Content-Disposition: attachment; filename=$zipFileName" -CaseSensitive if ($base64StartLine) { Write-Host "Found start of base64-encoded content" $base64ContentLines = $rfc822[($base64StartLine.LineNumber + 1)..($rfc822.Count - 1)] | Where-Object { $_ -notmatch "^--" } | ForEach-Object { $_.Trim() } $encodedContent = -join $base64ContentLines Write-Host "Base64 Content Preview: $($encodedContent.Substring(0, [Math]::Min(500, $encodedContent.Length)))" try { $decodedContent = [Convert]::FromBase64String($encodedContent) $zipFilePath = Join-Path $env:TEMP $zipFileName [System.IO.File]::WriteAllBytes($zipFilePath, $decodedContent) $files += $zipFilePath Write-Host "Zip file saved to: $zipFilePath" } catch { Write-Warning "Failed to base64-decode content for zip file: $zipFileName" Write-Warning "Error details: $_" } } else { Write-Warning "Could not find start of base64 encoded content for zip file: $zipFileName" } } else { Write-Warning "No zip file found in nested attachment" } } } } return $files
内容的提问来源于stack exchange,提问作者Lukas Østergaard
相关产品推荐
相关产品推荐

