下载文件,获取状态,然后执行文件

Download a file, get the status, then execute the file

我已经尝试了 invoke-restmethodnew-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:\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) {
    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 将错误报告为 statement-terminating errors,这意味着 没有赋值给变量$req(在语句 $req = Invoke-WebRequest ... 中)在发生错误时发生。

相反,不幸的是,如果发生错误,响应对象[1] 必须从 [ErrorRecord] instance representing the error, which is available via $Error[0] after the fact, or via $_ in the catch block of a try { ... } catch { ... } statement (adapted from this answer):

try {
  Invoke-WebRequest -Uri $scripturl -OutFile "$scriptpath\fls.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.StatusCodereturn是枚举类型的值,System.Net.HttpStatusCode,而不是[int] 值,但你可以像整数一样使用它。要 return 一个整数开头,追加 .Value__ 或转换为 [int].

注意Invoke-WebRequest总是同步;如果您下载文件(成功),则在下载完成之前不会return调用。


[1] 正如链接的答案所解释的那样,错误记录中包含的响应对象与 Invoke-WebRequest 不同类型 ] returns 在成功的情况下(如果还指定了 -OutFile 则需要 -PassThru):错误记录的 .Exception.Response 属性 包含一个 System.Net.Http.HttpResponseMessage instance, whereas Invoke-WebRequest returns an instance (derived from) Microsoft.PowerShell.Commands.WebResponseObject在其 .BaseResponse 属性.

中包含 前一种类型的一个实例