AdoT is a lightweight PowerShell module to assist with security reviews of Azure DevOps.

The utility uses both documented APIs, as well as some used by the web portal, to gather resources. Rules can be run against the collected resource to help assess their configuration.

Installation

Installation instructions have been provided for manual installation or installation from the PowerShell Gallery.

Installing from PowerShell Gallery is as simple as the following:

Install-Module AdoT

Depending on the trust configuration of the repository, you may be prompted to permit the install.

Manual Install

The module can also be manually installed from the ZIP archive, using the following steps:

  • Download the module ZIP from Releases.
  • Unzip the folder.
  • Execute Import-Module ./UnzippedDir/AdoT. (note: ensure that you run Import-Module against the folder containing AdoT.psm1)

You can also install the module by placing the folder into any of the paths listed within $env:PSModulePath, e.g. /opt/microsoft/powershell/7/Modules or C:\Program Files\PowerShell\Modules.

Usage

Commands

The following commands are available in AdoT. Documentation for individual commands can be found using Get-Help $commandName in PowerShell, or within the docs linked below:

General:

Rules:

Resources:

Authentication

You have two options for authentication - a Personal Access Token (PAT), or an OAuth2.0 access token. Both have equal functionality within AdoT - a PAT is easier to configure and use, and will generally be valid for a longer period than an access token. To be clear, AdoT does not include any functionality for getting, or refreshing, OAuth tokens. It will, however, accept a valid access token and use that for API calls.

Instructions for connecting to AdoT can be found in the docs for Connect-AdoTClient.

Sample Commands

# Set this to your organisation name
$orgName = "DemoOrg"

# Ensure that status output will be printed
$InformationAction = 'Continue'

# Connect to ADO using PAT. A prompt will appear to enter the PAT
Connect-AdoTClient -Pat (Read-Host -Prompt "Enter PAT" -AsSecureString) -OrganisationName $orgName

# Get organisations
$Org = Get-AdoTOranisation -OrganisationName $orgName

# Get projects for all organisations
$Projects = $Org | Get-AdoTProject

# Get builds for all projects
$Builds = $Projects | Get-AdoTBuild

# Get logs for all builds
$BuildLogs = $Builds | Get-AdoTBuildLog

# Get build log content for all builds
$BuildLogs | ForEach-Object { (Get-AdoTBuildLogContent -BuildLog $_).Content | Out-File -FilePath "$($_.Parent.Parent.Id)_$($_.Parent.Id)_$($_.Id).log" }

Rules

AdoT includes functionality to execute basic rules against collected resources to assist in assessing their configuration. A number of default rules are included, and custom rules can also be used. Checkout the documentation for Add-AdoTRule and Invoke-AdoTRule for further details on using rules.

Custom Rules

As detailed in Add-AdoTRule, custom rules can be added from file. An example rule file can be found below:

# Rule must be annotated with the rule name (`project_visibility`) and supported resource type (`project`).
[Rule('project_visibility', 'project')]
# Rule must include a mandatory parameter `$Resource` which will be an [AdoTResource].
param(
    [Parameter(Mandatory)]
    [AdoTResource]$Resource
)
# Properties of the object can be queried to determine configuration
if ($Resource.Visibility -eq 'public') {
    # The rule can return a rule result object supporting the following properties:
    #  - Passed: boolean
    #  - Comment: string
    #  - Risk: enum[ None, Low, Medium, High]
    #  - Value: any object
    return @{
        Passed  = $false
        Comment = 'Project visibility is set to public'
        Risk    = 'low'
    }
}
else {
    # Rules can simple return $true is the rule is passed
    return $true
}

FAQs

Can I use an HTTP proxy?

You can configure HTTP proxy settings wth Set-AdoTConfig. AdoT also supports the standard environment variables HTTP_PROXY, HTTPS_PROXY, ALL_PROXY and NO_PROXY. For more details, check the Microsoft documentation for Invoke-WebRequest.

I’m not seeing any command output?

AdoT is configured to properly use each of PowerShell’s output streams for the corresponding severity of an event. The default configuration of some of these streams is SilentlyContinue meaning that the output is not shown. These can be updated using each of the corresponding preference variables, e.g. $InformationPreference = 'Continue'. These cannot be set using the parameters such as -InformationPreference as noted in known issues.

What about pipeline run logs?

You may notice that pipeline run logs are intentionally not included at this stage. These are all actually available as Build Logs, you’ll just need to reference the build ID property of the relevant pipeline run. The reason for not including the logs from the pipeline API as well is that the pipeline API provides a signed URL for retrieving the actual log contents, rather than returning the contents directly. This signed URL is valid for a short period of time and adds unnecessary complexity to an intentionally simple codebase.

Known Issues

  • The AdoT does not support some of the common parameters that are present for all advanced functions. The reason for this is that preference parameters, such as InformationPreference, are not passed to class methods.

Development

Please see the development guide for details on developing and contributing to AdoT.