我在这里有一个PowerShell脚本:
https://github.com/Azure/azure-devtestlab/blob/master/Artifacts/windows-vsts-download-and-run-script/DownloadVstsDropAndExecuteScript.ps1
我用来下载VSTS构建工件的:
[CmdletBinding()]
param(
[string] $accessToken,
[string] $buildDefinitionName,
[string] $vstsProjectUri,
[string] $pathToScript,
[string] $scriptArguments,
[string] $buildDefId
)
###################################################################################################
#
# PowerShell configurations
#
# NOTE: Because the $ErrorActionPreference is "Stop", this script will stop on first failure.
# This is necessary to ensure we capture errors inside the try-catch-finally block.
$ErrorActionPreference = "Stop"
# Ensure we force use of TLS 1.2 for all downloads.
[Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12
# Ensure we set the working directory to that of the script.
Push-Location $PSScriptRoot
# Configure strict debugging.
Set-PSDebug -Strict
###################################################################################################
#
# Handle all errors in this script.
#
trap
{
# NOTE: This trap will handle all errors. There should be no need to use a catch below in this
# script, unless you want to ignore a specific error.
$message = $error[0].Exception.Message
if ($message)
{
Write-Host -Object "ERROR: $message" -ForegroundColor Red
}
# IMPORTANT NOTE: Throwing a terminating error (using $ErrorActionPreference = "Stop") still
# returns exit code zero from the PowerShell script when using -File. The workaround is to
# NOT use -File when calling this script and leverage the try-catch-finally block and return
# a non-zero exit code from the catch block.
exit -1
}
###################################################################################################
#
# Functions used in this script.
#
function Get-BuildArtifacts
{
[CmdletBinding()]
param (
[string] $ArtifactsUri,
[Hashtable] $Headers,
[string] $Destination
)
# Clean up destination path first, if needed.
if (Test-Path $Destination -PathType Container)
{
Write-Host "Cleaning up destination folder $Destination"
Remove-Item -Path $Destination -Force -Recurse | Out-Null
}
Write-Host "Getting build artifacts information from $ArtifactsUri"
[Array] $artifacts = (Invoke-RestMethod -Uri $ArtifactsUri -Headers $Headers -Method Get | ConvertTo-Json -Depth 3 | ConvertFrom-Json).value
# Process all artifacts found.
foreach ($artifact in $artifacts)
{
if ($artifact.resource.type -notlike "Container") {
Write-Host "Skip download of artifact $($artifact.name) as it is not of type 'Container'"
continue
}
$artifactName = "$($artifact.name)"
$artifactZip = "$artifactName.zip"
Write-Host "Preparing to download artifact $artifactName to file $artifactZip"
$downloadUrl = $artifact.resource.downloadUrl
if (-not $downloadUrl)
{
throw "Unable to get the download URL for artifact $artifactName."
}
$outfile = "$PSScriptRoot\$artifactZip"
Write-Host "Downloading artifact $artifactName from $downloadUrl"
Invoke-RestMethod -Uri "$downloadUrl" -Headers $Headers -Method Get -Outfile $outfile | Out-Null
Write-Host "Extracting artifact file $artifactZip to $Destination"
[System.Reflection.Assembly]::LoadWithPartialName("System.IO.Compression.FileSystem") | Out-Null
[System.IO.Compression.ZipFile]::ExtractToDirectory($outfile, $Destination) | Out-Null
}
}
function Get-BuildDefinitionId
{
[CmdletBinding()]
param (
[string] $BuildDefinitionUri,
[Hashtable] $Headers
)
Write-Host "Getting build definition ID from $BuildDefinitionUri"
$buildDef = Invoke-RestMethod -Uri $BuildDefinitionUri -Headers $Headers -Method Get
if (-not $buildDefId)
{
$buildDefinitionId = $buildDef.value.id[0]
if (-not $buildDefinitionId)
{
throw "Unable to get the build definition ID from $buildDefinitionUri"
}
}
else
{
$buildDefinitionId = $buildDefId
}
return $buildDefinitionId
}
function Get-LatestBuildId
{
param (
[string] $BuildUri,
[Hashtable] $Headers
)
Write-Host "Getting latest build ID from $BuildUri"
$builds = Invoke-RestMethod -Uri $BuildUri -Headers $Headers -Method Get | ConvertTo-Json | ConvertFrom-Json
$buildId = $builds.value[0].id
if (-not $buildId)
{
throw "Unable to get the latest build ID from $BuildUri"
}
return $buildId
}
function Invoke-Script
{
[CmdletBinding()]
param (
[string] $Path,
[string] $Script,
[string] $Arguments
)
$scriptPath = Join-Path -Path $Path -ChildPath $Script
Write-Host "Running $scriptPath"
if (Test-Path $scriptPath -PathType Leaf)
{
Invoke-Expression "& `"$scriptPath`" $Arguments"
}
else
{
Write-Error "Unable to locate $scriptPath"
}
}
function Set-AuthHeaders
{
[CmdletBinding()]
param (
[string] $UserName = "",
[string] $AccessToken
)
$basicAuth = [Convert]::ToBase64String([Text.Encoding]::ASCII.GetBytes(("{0}:{1}" -f $UserName,$AccessToken)))
return @{ Authorization = "Basic $basicAuth" }
}
###################################################################################################
#
# Main execution block.
#
try
{
# Prepare values used throughout.
$vstsApiVersion = "2.0"
$destination = "$($env:HOMEDRIVE)\$buildDefinitionName"
$vstsProjectUri = $vstsProjectUri.TrimEnd("/")
$headers = Set-AuthHeaders -AccessToken $accessToken
# Output provided parameters.
Write-Host 'Provided parameters used in this script:'
Write-Host " `$accessToken = $('*' * $accessToken.Length)"
Write-Host " `$buildDefinitionName = $buildDefinitionName"
Write-Host " `$vstsProjectUri = $vstsProjectUri"
Write-Host " `$pathToScript = $pathToScript"
Write-Host " `$scriptArguments = $scriptArguments"
# Output constructed variables.
Write-Host 'Variables used in this script:'
Write-Host " `$vstsApiVersion = $vstsApiVersion"
Write-Host " `$outfile = $outfile"
Write-Host " `$destination = $destination"
# Get the build definition ID.
$buildDefinitionUri = "$vstsProjectUri/_apis/build/definitions?api-version=$vstsApiVersion&name=$buildDefinitionName"
$buildDefinitionId = Get-BuildDefinitionId -BuildDefinitionUri $buildDefinitionUri -Headers $headers
# Get the ID of the latest successful build.
$buildUri = "$vstsProjectUri/_apis/build/builds/?api-version=$vstsApiVersion&definitions=$buildDefinitionId&statusFilter=succeeded";
$buildId = Get-LatestBuildId -BuildUri $buildUri -Headers $headers
# Download the build artifact package.
$artifactsUri = "$vstsProjectUri/_apis/build/builds/$buildId/Artifacts?api-version=$vstsApiVersion";
Get-BuildArtifacts -ArtifactsUri $artifactsUri -Headers $headers -Destination $destination
# Run the script specified after having successfully downloaded the build artifact package.
Invoke-Script -Path $destination -Script $pathToScript -Arguments $scriptArguments
}
finally
{
Pop-Location
}
字符串
当我在PowerShell中运行该脚本时,它工作得很好。当我从命令提示符运行它时,它工作得很顺利,就像这样:
powershell.exe -ExecutionPolicy Bypass C:\PathToScript\DownloadVstsDropAndExecuteScript.ps1 -parameters
型
然而,当我试图运行它作为一个计划任务的脚本似乎没有完成下载(压缩文件大小是小,当我试图打开,文件损坏)。无论是在用户登录模式和没有登录用户。
任务xml在这里:
<?xml version="1.0" encoding="UTF-16"?>
<Task version="1.2" xmlns="http://schemas.microsoft.com/windows/2004/02/mit/task">
<RegistrationInfo>
<Date>2018-07-17T08:39:31.2909587</Date>
<Author>LOCALPC\Administrator</Author>
<URI>\Download Nightly Artifacts</URI>
</RegistrationInfo>
<Triggers>
<CalendarTrigger>
<StartBoundary>2018-07-17T04:44:44</StartBoundary>
<ExecutionTimeLimit>PT2H</ExecutionTimeLimit>
<Enabled>true</Enabled>
<ScheduleByWeek>
<DaysOfWeek>
<Monday />
<Tuesday />
<Wednesday />
<Thursday />
<Friday />
<Saturday />
</DaysOfWeek>
<WeeksInterval>1</WeeksInterval>
</ScheduleByWeek>
</CalendarTrigger>
</Triggers>
<Principals>
<Principal id="Author">
<UserId>S-1-5-21-1204101111-744349012-1702229681-300</UserId>
<LogonType>InteractiveToken</LogonType>
<RunLevel>HighestAvailable</RunLevel>
</Principal>
</Principals>
<Settings>
<MultipleInstancesPolicy>IgnoreNew</MultipleInstancesPolicy>
<DisallowStartIfOnBatteries>false</DisallowStartIfOnBatteries>
<StopIfGoingOnBatteries>false</StopIfGoingOnBatteries>
<AllowHardTerminate>true</AllowHardTerminate>
<StartWhenAvailable>true</StartWhenAvailable>
<RunOnlyIfNetworkAvailable>false</RunOnlyIfNetworkAvailable>
<IdleSettings>
<StopOnIdleEnd>true</StopOnIdleEnd>
<RestartOnIdle>false</RestartOnIdle>
</IdleSettings>
<AllowStartOnDemand>true</AllowStartOnDemand>
<Enabled>true</Enabled>
<Hidden>false</Hidden>
<RunOnlyIfIdle>false</RunOnlyIfIdle>
<WakeToRun>true</WakeToRun>
<ExecutionTimeLimit>PT2H</ExecutionTimeLimit>
<Priority>7</Priority>
</Settings>
<Actions Context="Author">
<Exec>
<Command>powershell.exe</Command>
<Arguments>C:\PathToScript\DownloadVstsDropAndExecuteScript.ps1 -parameters</Arguments>
</Exec>
</Actions>
</Task>
型
1条答案
按热度按时间92vpleto1#
取代
字符串
与
型
感谢@anheledir的解决方案