Skip to content

Instantly share code, notes, and snippets.

@JPRuskin
Created April 21, 2020 14:40
Show Gist options
  • Select an option

  • Save JPRuskin/8fd473e4f1ba2bd807fc10241f032361 to your computer and use it in GitHub Desktop.

Select an option

Save JPRuskin/8fd473e4f1ba2bd807fc10241f032361 to your computer and use it in GitHub Desktop.
Quick Azure DevOps REST API build helper stuff
@{
ModuleVersion = '0.1.0'
# Modules that must be imported into the global environment prior to importing this module
RequiredModules = @(
)
# Exports. Populated by Optimize-Module during the build step.
# For best performance, do not use wildcards and do not delete these entry!
# Use an empty array if there is nothing to export.
FunctionsToExport = @(
"Set-AzureDevOpsRestApiAuthorizationToken"
"Get-AzureDevOpsRestApiResponse"
"Get-AzureDevOpsGitRepository"
)
CmdletsToExport = @()
AliasesToExport = @(
"azrest"
)
# Third party metadata
PrivateData = @{
# PowerShell Gallery data
PSData = @{
Prerelease = ''
ReleaseNotes = ''
Tags = 'Build', 'Development'
ProjectUri = ''
}
}
# ID used to uniquely identify this module
GUID = '202d1484-0df3-4e67-89cc-c42ce77e5c6b'
Description = 'Module to assist with REST calls to AzureDevOps during builds.'
Author = 'jpruskin'
# The main script or binary module that is automatically loaded as part of this module
RootModule = 'AzRestBuildHelper.psm1'
# Minimum version of the Windows PowerShell engine tested with this module
PowerShellVersion = '5.1'
}
function ConvertTo-AzureDevOpsRestEncodedAuthToken {
<#
.Synopsis
This ensures a token is valid for REST authentication to Azure DevOps
.Description
The token requires:
- Base64 encoding
- A prefixed colon (':')
.Example
ConvertTo-EncodedAuthToken 'PersonalAccessTokenFromAzureDevOps'
#>
[CmdletBinding()]
param(
[string]$Token
)
try {
[string]$DecodedString = [System.Text.Encoding]::UTF8.GetString([System.Convert]::FromBase64String($Token))
} catch { <# String is not a Base64 String #> }
if ($DecodedString -match ":[A-Z0-9]+") {
$Token = $DecodedString
}
[System.Convert]::ToBase64String([System.Text.Encoding]::UTF8.GetBytes(":$($Token -replace '^:')"))
}
function Get-AzureDevOpsRestApiAuthorizationHeader {
<#
.Synopsis
This sets the __RestAuthHeader object if not present, and returns it
.Example
$Headers = AuthHeader + @{ContentType="application\json"}
#>
[CmdletBinding()]
[Alias('AuthHeader')]
param()
if (-not $script:__RestAuthHeader) {
if ($env:System_AccessToken) {
Set-AzureDevOpsRestApiAuthorizationToken -SystemAccessToken $env:System_AccessToken
} else {
Set-AzureDevOpsRestApiAuthorizationToken # Will prompt for PAT
}
}
$script:__RestAuthHeader
}
function Set-AzureDevOpsRestApiAuthorizationToken {
<#
.Synopsis
Handles creating an authorization header if not present
.Example
Set-AzureDevOpsRestApiAuthorizationToken -PAT "PersonalAccessTokenFromAzureDevOps"
.Example
Set-AzureDevOpsRestApiAuthorizationToken -SystemAccessToken $env:System_AccessToken
#>
[CmdletBinding(DefaultParameterSetName = 'Basic')]
param(
[Parameter(ParameterSetName = 'Basic', Mandatory)]
[Alias('PAT')]
[string]$PersonalAccessToken,
[Parameter(ParameterSetName = 'Bearer', Mandatory)]
[ValidateNotNullOrEmpty()]
[string]$SystemAccessToken # $env:System_AccessToken on Build Agents
)
end {
$Token = ConvertTo-AzureDevOpsRestEncodedAuthToken -Token @($PersonalAccessToken, $SystemAccessToken)[$PSCmdlet.ParameterSetName -eq 'Bearer']
$script:__RestAuthHeader = @{
Authorization = "$($PSCmdlet.ParameterSetName) $($Token)"
}
}
}
function Get-AzureDevOpsRestApiResponse {
<#
.Synopsis
Quick wrapper for calls to the Azure REST API, to handle authentication etc.
Probably should be "Invoke-"
.Example
azrest git/repositories
#>
[Alias('azrest')]
[CmdletBinding(DefaultParameterSetName = 'Combine')]
param(
[Parameter(ParameterSetName = 'Combine', Mandatory, Position = 0, ValueFromPipeline)]
[string]$Path,
[Parameter(ParameterSetName = 'Combine')]
[string]$BaseUri,
[Parameter(ParameterSetName = 'Full', Mandatory, Position = 0, ValueFromPipelineByPropertyName)]
[Alias('href')]
[string]$Uri = "$BaseUri$Path",
[Parameter(ValueFromPipeline)]
[Hashtable]$UriArguments,
[Microsoft.PowerShell.Commands.WebRequestMethod]$Method = 'Get',
[string]$ApiVersion = '4.1',
[Hashtable]$Additional = @{}
)
process {
$Args = @{
Method = $Method
Uri = -join @(
$Uri
"?"
if($UriArguments){($UriArguments.GetEnumerator().ForEach({"$($_.Key)=$($_.Value)&"}))}
"api-version=$ApiVersion"
)
Headers = AuthHeader
} + $Additional
Invoke-RestMethod @Args
}
}
function Get-AzureDevOpsGitRepository {
<#
.Synopsis
Gets any Git repositories, or whichever matches $Name
.Example
Get-Repository
Returns all repositories
.Example
Get-Repository Platform-PHP
Returns the Platform-PHP repository
#>
[CmdletBinding()]
param(
[ArgumentCompleter({
param($CommandName, $ParameterName, $WordToComplete, $CommandAst, $BoundParams)
(Get-Repository).Name.Where{$_ -like "*$WordToComplete*"}
})]
[string]$Name
)
if ($Name) {
try {
azrest git/repositories -UriArguments @{repositoryId=$Name}
} catch {
# Maybe take this logic to azrest?
if ($JSONResponse = $_.Message | ConvertFrom-JSON -ErrorAction SilentlyContinue) {
Write-Error -Exception $JSONResponse.TypeKey -Message $JSONResponse.Message -TargetObject $JSONResponse
} else {
Write-Error -Exception $_.Exception -Message $_.Message
}
}
} else {
(azrest git/repositories).value
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment