Artifacts/windows-execute-powershell-script/ExecutePowerShellScript.ps1 (121 lines of code) (raw):
[CmdletBinding()]
param(
[Parameter(Mandatory, ParameterSetName='NoLogging')]
[Parameter(Mandatory, ParameterSetName='UploadLogAccessToken')]
[Parameter(Mandatory, ParameterSetName='UploadLogManagedIdentity')]
[ValidateNotNullOrEmpty()]
[string]
$ScriptPath,
[Parameter(ParameterSetName='NoLogging')]
[Parameter(ParameterSetName='UploadLogAccessToken')]
[Parameter(ParameterSetName='UploadLogManagedIdentity')]
[string]
$ScriptParameters = "",
[Parameter(ParameterSetName='NoLogging')]
[Parameter(ParameterSetName='UploadLogAccessToken')]
[Parameter(ParameterSetName='UploadLogManagedIdentity')]
[hashtable]
$EnvironmentVariables = @{},
[Parameter(ParameterSetName='NoLogging')]
[Parameter(ParameterSetName='UploadLogAccessToken')]
[Parameter(ParameterSetName='UploadLogManagedIdentity')]
[ValidateNotNullOrEmpty()]
[System.IO.DirectoryInfo]
$LogsDirectory = "$env:SystemDrive\DevTestLabs\Artifacts\Logs",
# Logs drop service URL
[Parameter(Mandatory, ParameterSetName='UploadLogAccessToken')]
[Parameter(Mandatory, ParameterSetName='UploadLogManagedIdentity')]
[ValidateNotNullOrEmpty()]
[uri]
$LogsDropServiceURL,
# Logs drop name
[Parameter(Mandatory, ParameterSetName='UploadLogAccessToken')]
[Parameter(Mandatory, ParameterSetName='UploadLogManagedIdentity')]
[ValidateNotNullOrEmpty()]
[string]
$LogsDropName,
# File globs relative to the root directory and separated by ';' that specify files to upload to the logs drop at the end of artifact execution.
[Parameter(ParameterSetName='UploadLogAccessToken')]
[Parameter(ParameterSetName='UploadLogManagedIdentity')]
[string]
$LogsDropFilesToInclude,
# File globs relative to the root directory and separated by ';' that specify files to NOT upload to the logs drop at the end of the artifact execution.
[Parameter(ParameterSetName='UploadLogAccessToken')]
[Parameter(ParameterSetName='UploadLogManagedIdentity')]
[string]
$LogsDropFilesToExclude,
# Required scopes for this access token:
# - vso.drop_write: Upload logs to Azure Artifacts Drops in the $LogsDropServiceURL account
[Parameter(Mandatory, ParameterSetName='UploadLogAccessToken')]
[ValidateNotNullOrEmpty()]
[securestring]
$LogsDropServiceAccessToken,
# Client ID for the managed identity that will be used to authenticate with the $LogsDropServiceURL account
[Parameter(Mandatory, ParameterSetName='UploadLogManagedIdentity')]
[ValidateNotNullOrEmpty()]
[string]
$LogsDropServiceManagedIdentityClientID,
# Whether to ignore pending reboots from previous artifacts.
[Parameter(ParameterSetName='NoLogging')]
[Parameter(ParameterSetName='UploadLogAccessToken')]
[Parameter(ParameterSetName='UploadLogManagedIdentity')]
[switch]
$IgnorePendingReboot
)
Import-Module (Join-Path $PSScriptRoot 'Common.psm1')
$logFileName = "$(Get-Date -Format FileDateTimeUniversal)-$(Split-Path -Path $ScriptPath -Leaf).log"
$logFile = [System.IO.FileInfo](Join-Path $LogsDirectory $logFileName)
Start-ArtifactLogging -LogFile $logFile
try {
try {
Initialize-Artifact
if (Test-RebootPending) {
if ($IgnorePendingReboot) {
Write-Warning 'There is a reboot pending for this machine, but this artifact has been configured to ignore it.'
}
else {
throw 'This artifact failed because there is a reboot pending for this machine. To fix this problem, add an artifact prior to this one that reboots the machine.'
}
}
$script = Resolve-Path -Path $ScriptPath
Write-Verbose "Script path resolved to '$script'."
Write-Verbose "Attempting to set $($EnvironmentVariables.Keys.Count) environment variables..."
$EnvironmentVariables.Keys | ForEach-Object { Set-Item -Path Env:$_ -Value $EnvironmentVariables.Item($_) }
Write-Information "Successfully set $($EnvironmentVariables.Keys.Count) environment variables."
# Before potentially logging secrets, check if there are any and replace them
$scriptParamsForLogs = $ScriptParameters -replace "(ConvertTo-SecureString\s+)([^\s]+)(\s+-AsPlainText)",'$1***$3'
Write-Verbose "Attempting to execute the script '$script' with parameters '$scriptParamsForLogs'..."
Invoke-Command -ScriptBlock {Invoke-Expression ". `"$script`" $ScriptParameters"}
Write-Information "Successfully executed script '$script'."
}
catch {
if ($PsCmdlet.ParameterSetName.StartsWith('UploadLog')) {
Write-ErrorToArtifactOrchestrator -Message "$ScriptPath Failed: View '$logFileName' at log drop $(Format-AzureArtifactsLogsDropBrowserURL -LogsDropServiceURL $LogsDropServiceURL -LogsDropName $LogsDropName)"
}
throw
}
finally {
Stop-ArtifactLogging -LogFile $logFile
if ($PsCmdlet.ParameterSetName.StartsWith('UploadLog')) {
if ($LogsDropFilesToInclude -and $LogsDropFilesToExclude) {
New-FilesSnapshot -IncludeGlobPatterns $LogsDropFilesToInclude -ExcludeGlobPatterns $LogsDropFilesToExclude -SearchDirectory '/' -SnapshotDestinationDirectory $LogsDirectory -SnapshotName "Snapshot-$(Get-Date -Format FileDateTimeUniversal)"
}
elseif ($LogsDropFilesToInclude) {
New-FilesSnapshot -IncludeGlobPatterns $LogsDropFilesToInclude -SearchDirectory '/' -SnapshotDestinationDirectory $LogsDirectory -SnapshotName "Snapshot-$(Get-Date -Format FileDateTimeUniversal)"
}
if ($PsCmdlet.ParameterSetName.EndsWith('ManagedIdentity')) {
$LogsDropServiceAccessToken = Get-AccessTokenUsingManagedIdentity -ClientID $LogsDropServiceManagedIdentityClientID
}
Publish-ArtifactLogs -LogsDropServiceURL $LogsDropServiceURL -LogsDropName $LogsDropName -LogsDirectory $LogsDirectory -AccessToken $LogsDropServiceAccessToken
}
}
}
catch {
if ($PsCmdlet.ParameterSetName.StartsWith('UploadLog')) {
if ($PsCmdlet.ParameterSetName.EndsWith('ManagedIdentity')) {
$LogsDropServiceAccessToken = Get-AccessTokenUsingManagedIdentity -ClientID $LogsDropServiceManagedIdentityClientID
}
Complete-ArtifactLogsDrop -LogsDropServiceURL $LogsDropServiceURL -LogsDropName $LogsDropName -AccessToken $LogsDropServiceAccessToken
}
throw
}