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

使用Graph API上传IPA至Intune时触发Bad Request 400错误

问题

通过PowerShell调用Graph API在Intune中创建iOS LOB(.ipa)应用时,应用可正常创建,但调用第二个Invoke-RestMethod上传IPA文件时,持续触发Bad Request 400错误。尝试了字节流、字符串等多种上传方式均无效。

相关代码片段:

$tenantId = "XXXXXXXXXXXXXXXXXXX"
$clientId = "XXXXXXXXXXXXXXXXXXXX"
$clientSecret = "XXXXXXXXXXXXXXXXXXX"

$appPath = "./Path to .ipa file" ## Relative Path
$resource = "https://graph.microsoft.com/"
$authUrl = "https://login.microsoftonline.com/$tenantId/oauth2/v2.0/token"

$authBody = @{   
   client_id     = $clientId
   client_secret = $clientSecret
   scope         = "https://graph.microsoft.com/.default"
   grant_type    = "client_credentials"
}
$tkResponse = Invoke-RestMethod -Method Post -Uri $authUrl -ContentType "application/x-www-form-urlencoded" -Body $authBody
$origToken = $tkResponse.access_token

$initialheaders = @{
   Authorization = "Bearer $origToken"
   "Content-Type" = "application/json"
}
$body = @{
   "@odata.type" = "#microsoft.graph.iosLobApp"
   displayName = "Test"
   bundleId = "self.test.sample.app"
   buildNumber = "1.0.0"
   versionNumber = "1.0.0"
   description = "Test description"
   publisher = "Test Publisher"
   fileName = "Test.ipa"
   committedContentVersion = "1"
   informationUrl = "https://yourappwebsite.com"
   privacyInformationUrl = "https://yourappwebsite.com/privacy"
   minimumSupportedOperatingSystem = @{
       v8_0 = $true
   }
   applicableDeviceType = @{
       iPad = $true
       iPhoneAndIPod = $true
   }
}

$mobJson = $body | ConvertTo-Json -Depth 10
$graphApiUrl = "https://graph.microsoft.com/v1.0/deviceAppManagement/mobileApps"
try{
    $response = Invoke-RestMethod -Method Post -Uri $graphApiUrl -Headers $initialheaders -Body $mobJson -ErrorAction Stop -verbose
    $applicationId = $response.id
    } catch {
   Write-Host "$($_.Exception.Response.StatusCode)"
    }

$fileUpUrl = "https://graph.microsoft.com/v1.0/deviceAppManagement/mobileApps/$applicationId/contentVersions/1/files"

$fContent = [System.IO.File]::ReadAllBytes($appPath)
$baseContent = [Convert]::ToBase64String($fContent)

$contheaders = @{
Authorization = "Bearer $origToken"
"Content-Type" = "application/octet-stream"
}
$uploadBody = @{
           "@odata.type" = "#microsoft.graph.mobileAppContentFile"
            name = (Get-Item $appPath).Name
            sizeInBytes = (Get-Item $appPath).Length
            versionCode = "1.0.0"
            versionName = "Version Name"
            contentBytes = $baseContent
           } | ConvertTo-Json

try{
       ## ERROR COMES FROM BELOW INVOKE METHOD ##
       $uploadResp = Invoke-RestMethod -Uri $fileUpUrl -Method Post -Headers $contheaders -Body $uploadBody -Verbose

} catch {
         $error = $_.Exception
}

错误详情:

2024-12-23T18:16:34.9342611Z Error uploading IPA file: The remote server returned an error: (400) Bad Request.
2024-12-23T18:16:34.9370301Z System.Net.WebException: The remote server returned an error: (400) Bad Request.
2024-12-23T18:16:34.9372124Z    at Microsoft.PowerShell.Commands.WebRequestPSCmdlet.GetResponse(WebRequest request)
2024-12-23T18:16:34.9392176Z    at Microsoft.PowerShell.Commands.WebRequestPSCmdlet.ProcessRecord()
2024-12-23T18:16:34.9404004Z Error11: System.Net.WebException: The remote server returned an error: (400) Bad Request.
2024-12-23T18:16:34.9404570Z    at Microsoft.PowerShell.Commands.WebRequestPSCmdlet.GetResponse(WebRequest request)
2024-12-23T18:16:34.9405060Z    at Microsoft.PowerShell.Commands.WebRequestPSCmdlet.ProcessRecord()
2024-12-23T18:16:34.9406974Z Error11 Message: System.Net.WebException: The remote server returned an error: (400) Bad Request.
2024-12-23T18:16:34.9407299Z    at Microsoft.PowerShell.Commands.WebRequestPSCmdlet.GetResponse(WebRequest request)
2024-12-23T18:16:34.9408070Z    at Microsoft.PowerShell.Commands.WebRequestPSCmdlet.ProcessRecord().Message
解决方案

错误核心在于上传IPA文件的流程不符合Graph API要求,直接将大文件转成Base64放入请求体不仅会导致请求过大,还违背了API设计逻辑。正确上传流程分为三步:

1. 创建空的mobileAppContentFile条目

先上传文件元数据(不含实际内容),请求头使用application/json:

$fileUpUrl = "https://graph.microsoft.com/v1.0/deviceAppManagement/mobileApps/$applicationId/contentVersions/1/files"

$contheaders = @{
    Authorization = "Bearer $origToken"
    "Content-Type" = "application/json"
}

# 仅上传元数据,不包含contentBytes
$uploadBody = @{
    "@odata.type" = "#microsoft.graph.mobileAppContentFile"
    name = (Get-Item $appPath).Name
    sizeInBytes = (Get-Item $appPath).Length
    versionCode = "1.0.0"
    versionName = "Version Name"
} | ConvertTo-Json -Depth 10

try{
    $uploadResp = Invoke-RestMethod -Uri $fileUpUrl -Method Post -Headers $contheaders -Body $uploadBody -Verbose
    $fileId = $uploadResp.id
} catch {
    Write-Host "创建文件元数据失败: $($_.Exception.Response.StatusCode)"
    $error = $_.Exception
}

2. 获取上传会话URL

通过已创建的文件ID获取专用上传会话:

$uploadSessionUrl = "https://graph.microsoft.com/v1.0/deviceAppManagement/mobileApps/$applicationId/contentVersions/1/files/$fileId/createUploadSession"

try{
    $sessionResp = Invoke-RestMethod -Uri $uploadSessionUrl -Method Post -Headers $contheaders -Body "{}" -Verbose
    $uploadUrl = $sessionResp.uploadUrl
} catch {
    Write-Host "获取上传会话失败: $($_.Exception.Response.StatusCode)"
    $error = $_.Exception
}

3. 上传文件字节流到会话URL

使用PUT请求直接上传文件字节流,请求头使用application/octet-stream:

$fContent = [System.IO.File]::ReadAllBytes($appPath)

$uploadHeaders = @{
    "Content-Type" = "application/octet-stream"
}

try{
    Invoke-RestMethod -Uri $uploadUrl -Method Put -Headers $uploadHeaders -Body $fContent -Verbose
    Write-Host "文件上传成功"
} catch {
    Write-Host "上传文件失败: $($_.Exception.Response.StatusCode)"
    $error = $_.Exception
}

额外注意事项

  • 确保应用注册拥有DeviceManagementApps.ReadWrite.All权限,且已完成管理员同意授权
  • 若IPA文件超过4MB,建议使用分块上传,通过Content-Range头分段传输
  • 检查bundleId、buildNumber、versionNumber是否与IPA文件内的实际信息完全匹配,不匹配也会导致上传失败

内容的提问来源于stack exchange,提问作者Amit Saxena

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.15 07:47:36