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

Windows 11中PowerShell调用Invoke-WebRequest出现403禁止错误求助

问题:PowerShell调用Jira REST API下载附件返回403 Forbidden错误

错误详情

Invoke-WebRequest : The remote server returned an error: (403) Forbidden.
No line:64 caractere:2
Invoke-WebRequest -Headers @{"Authorization"=$authorization} -uri $u ...
 + CategoryInfo          : InvalidOperation: (System.Net.HttpWebRequest:HttpWebRequest) [Invoke-WebRequest], WebException
 + FullyQualifiedErrorId : WebCmdletWebResponseException,Microsoft.PowerShell.Commands.InvokeWebRequestCommand

完整脚本

# Export all attachments from XML export of Jira

Function Get-Folder($initialDirectory)
{
 [System.Reflection.Assembly]::LoadWithPartialName("System.windows.forms")|Out-Null

$foldername = New-Object System.Windows.Forms.FolderBrowserDialog
 $foldername.Description = "Select a folder to store exported attachments"
 $foldername.rootfolder = "MyComputer"

if($foldername.ShowDialog() -eq "OK")
 {
 $folder += $foldername.SelectedPath
 }
 return $folder
}

# Jira Authorization
$cred=get-credential -Message "Enter you username and password to access Jira Cloud"
$user = $cred.username
$pass = [Runtime.InteropServices.Marshal]::PtrToStringAuto([Runtime.InteropServices.Marshal]::SecureStringToBSTR($cred.password))
$pair = "$($user):$($pass)"
$encodedCreds = [System.Convert]::ToBase64String([System.Text.Encoding]::ASCII.GetBytes($pair))
$authorization = "Basic $encodedCreds"
$directory = Get-Folder

# You must create a filter and copy "export to XML" URL
$uri=read-host "Paste 'XML export' URL (Jira)"
$temp=$uri.Split("/")
$base_uri=$temp[0]+'//'+$temp[2]
$outfile="list.xml"

# This folder will be used to store all attachments, for each record (jira issue) will be created a folder 
# with the issue key and inside it will be stored all attachments
$directory="$directory\attachments"

Invoke-WebRequest -Headers @{"Authorization"=$authorization} -uri $uri -outfile $outfile

[xml]$Content = Get-Content .\list.xml
$Feed = $Content.rss.channel

ForEach ($msg in $Feed.Item){ 
 $idjira=$msg.key.'#text'
 if (Test-path "$directory\$idjira") {
 write-host "Folder $directory\$idjira exists"
 } else {
 write-host "Folder $directory\$idjira don´t exist, creating..."
 mkdir "$directory\$idjira"
 }
 ForEach ($attachment in $msg.attachments.attachment) {
 $idattachment=$attachment.id
 $nameattachment=$attachment.name
 $uri="$base_uri/secure/attachment/$idattachment/"
 if (test-path "$directory\$idjira\$nameattachment") {
 $outfile="$directory\$idjira\$idattachment.$nameattachment"
 $outfile=$outfile.Replace('[','').replace(']','')
 write-host "File [$directory\$idjira\$nameattachment] already exists, creating other version $outfile"
 } else {
 $outfile="$directory\$idjira\$nameattachment"
 $outfile=$outfile.Replace('[','').replace(']','') 
 write-host "Creating file $outfile" 
 }
 write-host "Downloading $uri to $outfile..."
 Invoke-WebRequest -Headers @{"Authorization"=$authorization} -uri $uri -outfile $outfile
 write-host "done"
 }
}
Remove-item ".\list.xml"

已尝试相关HTTPS错误解决方案但无效,需求是解决该403错误以成功下载Jira附件。


解决方案

1. 更换Jira Cloud授权凭证

Jira Cloud已禁用账号密码直接用于Basic Auth,必须使用API令牌替代密码:

  • 生成API令牌:进入Jira个人设置→「安全」→创建新API令牌
  • 修改脚本中密码获取逻辑,将$pass替换为生成的API令牌,而非原账号密码

2. 修正附件下载API端点

当前脚本使用的旧页面路径不兼容REST API,替换为官方附件下载端点:

$uri = "$base_uri/rest/api/3/attachment/$idattachment/content"

3. 补充必要请求头

Jira REST API要求指定Accept头以获取二进制附件,更新Invoke-WebRequest调用:

Invoke-WebRequest -Headers @{
    "Authorization" = $authorization
    "Accept" = "application/octet-stream"
} -Uri $uri -OutFile $outfile

4. 验证账号权限

确保你的Jira账号拥有目标项目的「浏览附件」权限,以及API访问权限,可在Jira权限管理页面确认。

5. 优化文件名清理逻辑

用系统内置方法全面清理非法字符,避免路径解析错误:

$invalidChars = [System.IO.Path]::GetInvalidFileNameChars()
$nameattachment = $nameattachment -replace "[$([regex]::Escape($invalidChars))]", ""

内容的提问来源于stack exchange,提问作者Fernando Eugênio

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.09 17:14:53