PowerShell脚本同步下载、状态获取与执行问题:$req.StatusCode返回Null
解决PowerShell中Invoke-WebRequest无法获取StatusCode的问题
你遇到的核心问题主要有两点:一是使用-OutFile参数时Invoke-WebRequest默认不会返回响应对象,导致$req.StatusCode为空;二是请求失败进入catch块时,try里的$req根本没被初始化,自然拿不到状态码。下面我来拆解原因并给出适配你需求的完整解决方案:
问题根源解析
- 成功请求时的空值问题:当搭配
-OutFile使用Invoke-WebRequest时,PowerShell默认会直接把内容写入文件,不会返回响应对象(返回值为$null),所以你赋值的$req是空的,访问其StatusCode属性自然也会得到$null。解决这个只需要加上-PassThru参数,强制让命令返回响应对象。 - 异常时的状态码获取:请求失败抛出异常时,
try块里的$req根本没机会被赋值,此时要从异常对象$_里提取响应信息——具体是通过$_.Exception.Response来访问失败的响应,进而拿到状态码(注意枚举类型的StatusCode需要用.value__获取数字值)。
修正后的完整代码
下面是完全匹配你伪代码逻辑的优化版代码:
$param1=$args[0] if ($param1 -eq "-d" -or $param1 -eq "-D") { $isDev = $true } #todo: Move to config file $logpath = "c:\company\logs\loginscript" $scriptpath = "c:\company\scripts\" $scripturl = "http://downloads.company.com/fls.core.ps1" $logfile="$(Get-Date -Format "yyyy-MM-dd hhmmss").log" Function log($message) { $logEntry = "[$(Get-Date -Format "yyyy-MM-dd hhmmss")] $message" $logEntry | Out-file "$($logpath)\$($logfile)" -append if ($isDev) { Write-Host $logEntry } } Function createFolder($path) { if (-!(Test-Path $path)) { New-Item -Type Directory -Path $path -Force | Out-Null } } function updateScripts() { $localScriptPath = Join-Path $scriptpath "fls.core.ps1" $downloadSuccess = $false try { # 用-PassThru强制返回响应对象,才能获取StatusCode $req = Invoke-WebRequest -Uri $scripturl -OutFile $localScriptPath -PassThru -ErrorAction Stop log "脚本下载成功,状态码:$($req.StatusCode)" $downloadSuccess = $true } catch { # 从异常中提取状态码,处理无响应的极端情况 $statusCode = if ($_.Exception.Response) { $_.Exception.Response.StatusCode.value__ } else { "未知" } log "脚本下载失败,状态码:$statusCode,错误信息:$($_.Exception.Message)" # 检查本地脚本是否存在,无本地副本则退出 if (-not (Test-Path $localScriptPath)) { log "ERROR: 无法下载脚本且无本地副本可用,正在退出..." exit 1 } else { log "WARNING: 将使用本地脚本副本" } } return $downloadSuccess } #----------------------------------------------# #---- MAIN CODE BLOCK -------------------------# #----------------------------------------------# createFolder $logpath createFolder $scriptpath # 更新脚本 $updated = updateScripts # 执行核心脚本 $coreScriptPath = Join-Path $scriptpath "fls.core.ps1" if (Test-Path $coreScriptPath) { log "开始执行核心脚本..." & $coreScriptPath } else { log "ERROR: 核心脚本不存在,无法执行" exit 1 }
关键改进说明
-PassThru参数:解决了-OutFile模式下无法获取响应对象的问题,成功时能正常拿到StatusCode。- 异常处理优化:通过
$_.Exception.Response捕获失败请求的状态,同时处理了无响应的极端场景。 - 路径安全处理:用
Join-Path代替字符串拼接路径,避免因格式错误导致的文件找不到问题。 - 逻辑清晰度提升:增加
$downloadSuccess标记明确下载状态,日志格式统一,减少重复代码。
内容的提问来源于stack exchange,提问作者user736893
相关产品推荐
相关产品推荐

