我尝试过invoke-restmethod
,new-object
和许多其他方法来实现我想做的事情。下面是最新的两个迭代:
$req = Invoke-WebRequest -uri $scripturl -OutFile "$($scriptpath)fls.core.ps1"
Write-Host "StatusCode:" $req.StatusCode
$req = Invoke-WebRequest -uri $scripturl -OutFile "$($scriptpath)fls.core.ps1" | Select-Object -Expand StatusCode
Write-Host "StatusCode:" $req
基本上我正在尝试下载另一个PowerShell脚本并执行它。显然,它需要是同步的。我还需要状态,这样我就可以确定它是否更新了。
下面是我想要完成的伪代码:
try {
download file
} catch {
output error
if (local copy exists) {
log warning that local copy is being used
} else {
log error could not download and no local copy available
exit script
}
}
run script (only after downloading new one if available)
下面是我当前的完整代码:
$param1=$args[0]
if ($param1 -eq "-d" -or $param1 -eq "-D") {
$isDev = $true
}
#todo: Move to config file
$logpath = "c:companylogsloginscript"
$scriptpath = "c:companyscripts"
$scripturl = "http://downloads.company.com/fls.core.ps1"
$logfile="$(Get-Date -Format "yyyy-MM-dd hhmmss").log"
Function log($message) {
Write-Output "[$(Get-Date -Format "yyyy-MM-dd hhmmss")] $message" | Out-file "$($logpath)$($logfile)" -append
if ($isDev) { Write-Host "[$(Get-Date -Format "yyyy-MM-dd hhmmss")] $message" }
}
Function createFolder($path) {
if (-!(Test-Path $path)) { New-Item -Type Directory -Path $path }
}
function updateScripts() {
try {
$req = Invoke-WebRequest -uri $scripturl -OutFile "$($scriptpath)fls.core.ps1"
Write-Host "StatusCode:" $req.StatusCode
} catch {
Write-Host "StatusCode:" $req.StatusCode
if ($req.StatusCode -eq 404) {
log "WARNING: Script not found at $scripturl"
} else {
log "ERROR: Script download error: $req.StatusCode"
}
if (Test-Path "$($scriptpath)fls.core.ps1") {
log "WARNING: Using local script"
} else {
log "ERROR: Unable to update script and no local script found. Exiting."
exit
}
}
}
#----------------------------------------------#
#---- MAIN CODE BLOCK -------------------------#
#----------------------------------------------#
createFolder $logpath
createFolder $scriptpath
#update scripts
updateScripts
#execute core loginscript
& $scriptpath/fls.core.ps1
$req.StatusCode
显示为空。
Invoke-WebRequest
报告错误为语句终止错误,这意味着在发生错误的情况下,不会对变量$req
(在语句$req = Invoke-WebRequest ...
中)赋值。
更新:
PowerShell(核心)7 +现在,您可以使用
-SkipHttpErrorCheck
切换到抑制错误,并像往常一样得到一个响应对象,其.StatusCode
属性包含HTTP状态码;例如:# PS 7+ only: -> 404 (Invoke-WebRequest -SkipHttpErrorCheck http://example.org/nosuchpage).StatusCode
下面的适用于Windows PowerShell(但该技术在PowerShell (Core)中仍然有效)。
相反,不幸的是,如果发生错误,响应对象[1]必须从表示错误的[ErrorRecord]
实例中收集。,这可以通过$Error[0]
在事实之后获得,或者通过try { ... } catch { ... }
语句的catch
块中的$_
获得(改编自此答案):
try {
Invoke-WebRequest -Uri $scripturl -OutFile "$scriptpathfls.core.ps1"
} catch [Microsoft.PowerShell.Commands.HttpResponseException] {
# Get the status code...
$statuscode = $_.Exception.Response.StatusCode
# ... and work with it.
# if ($statusCode -eq 404) { ...
} catch {
# Unexpected error, re-throw
throw
}
严格地说,$_.Exception.Response.StatusCode
返回一个枚举类型的值System.Net.HttpStatusCode
,而不是[int]
的值,但是您可以像使用整数一样使用它。返回一个整数,附加.Value__
或铸[int]
。
注意Invoke-WebRequest
总是同步;如果下载文件(成功),在下载完成之前,调用不会返回。
[1]正如链接的答案所解释的那样,错误记录中包含的响应对象与Invoke-WebRequest
在成功情况下返回的对象(如果还指定了-OutFile
,则需要-PassThru
)具有不同的类型:错误记录的.Exception.Response
属性包含System.Net.Http.HttpResponseMessage
实例,而Invoke-WebRequest
返回一个实例(派生自)Microsoft.PowerShell.Commands.WebResponseObject
,其中在其.BaseResponse
属性中包含前一类型的实例。