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

PowerShell包导入脚本执行时出现#document输出且无报错

问题排查:包导入日志出现异常#document输出

问题场景

执行PowerShell的ImportPackage函数调用REST接口完成包导入操作,流程显示执行完成且无报错,但日志中出现异常的#document输出,完整执行日志如下:

Package Validation Process Started for - 3. PTW_Dashboards.zip....
Package Validation Process Finished for - 3. PTW_Dashboards.zip
Package Import Process Started for - 3. PTW_Dashboards.zip...
Reading the Package data...
#document
Package Import Process Completed for -  3. PTW_Dashboards.zip
Logout Process Started...
Logout Process completed

对应的ImportPackage函数代码:

function ImportPackage([String] $MeridiumToken, [String] $PackageName, [String] $PkgItems, [String] $DNSURL,
    [String] $DBConnStr, [String] $DBTableName, [String] $ReleaseID, [String] $pkgID) {
    
    try {
        Write-Host "Package Import Process Started for - $PackageName..."
        
        $APIIURL = $DNSURL + '/apm/api/v1/core/metadata/import/selecteditems'
    
        # Encode Type
        $EncodeType = "iso-8859-1"
    
        # Dynamic input parameters section
        $FilePath = "$($env:SYSTEM_DEFAULTWORKINGDIRECTORY)/Subtract-a-thon/Automation/" + $PackageName
        
        # Header
        $IHeaders = @{ 'MeridiumToken' = $MeridiumToken }
    
        # Reading Package
        Write-Host "Reading the Package data..."
        $FileBinary = [System.IO.File]::ReadAllBytes($FilePath)
    
        $Enc = [System.Text.Encoding]::GetEncoding($EncodeType)
        $FileEnc = $Enc.GetString($FileBinary)
    
        $CRLF = "`r`n"
        $Boundary = [System.Guid]::NewGuid().ToString()
    
        # FileName
        $File_Name = Split-Path $FilePath -leaf
    
        # Request Body
        $IBody = (
            "--$Boundary",
            "Content-Disposition: form-data; name=`"file`"; filename=`"$File_Name`"",
            "Content-Type: application/octet-stream$CRLF",
            $FileEnc,
            $CRLF,
            "--$Boundary",
            "Content-Type:application/json",
            "Content-Disposition: form-data; name=`"items`"$CRLF",
            $PkgItems,
            "--$Boundary--"
        ) -join $CRLF
    
        # Request Content Type
        $IContentType = "multipart/form-data; boundary=`"$boundary`""
        
        # REST Call
        $ImportLog = Invoke-RestMethod -Uri $APIIURL -Method Post -Headers $IHeaders -ContentType $IContentType -Body $IBody


        Write-Host $ImportLog
        Write-Host "Package Import Process Completed for - " $PackageName
            }
    catch {
        Write-Host "An error occurred:"
        Write-Host $_.ScriptStackTrace
        throw $_
    }
}

问题原因

  1. #document输出的直接原因:
    Invoke-RestMethod调用接口后返回的是XML文档对象([xml]类型),直接使用Write-Host输出该对象时,PowerShell会默认显示其类型标识#document,而非实际的响应内容。

  2. 潜在的请求构建风险:
    手动将二进制文件转成字符串再拼接multipart请求体,可能因编码问题导致文件内容损坏(本次导入成功属于偶然,长期使用可能引发导入失败)。

解决方案

1. 修复#document输出问题

修改Write-Host $ImportLog的代码,将XML对象转为字符串输出:

# 替换原有的Write-Host $ImportLog
Write-Host $ImportLog.OuterXml

如果接口可能返回JSON或XML两种格式,可增加类型判断兼容处理:

if ($ImportLog -is [xml]) {
    Write-Host $ImportLog.OuterXml
} else {
    Write-Host ($ImportLog | ConvertTo-Json -Depth 10)
}

2. 优化multipart请求构建(避免编码隐患)

使用PowerShellInvoke-RestMethod原生支持的-Form参数上传文件,无需手动拼接请求体,彻底规避编码问题:

# 删除原手动构建IBody、IContentType的代码,替换为以下内容
$formParams = @{
    file = Get-Item -Path $FilePath  # 直接传入文件对象
    items = $PkgItems  # 若PkgItems是JSON字符串,直接传入即可
}

# 发起请求
$ImportLog = Invoke-RestMethod -Uri $APIIURL -Method Post -Headers $IHeaders -Form $formParams

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.11 14:32:41