Tips & Tricks

Controlling Azure DevOps from PowerShell

When using Azure DevOps frequently, a moment will come at which you’ll be faster executing a task using script rather than clicking your way through… There are a lot of reasons on why you should code repeating work, including:

  • Repeatability
  • Knowledge sharing (provided that you store the code in Version Control, accessible to your coworkers)
  • It’s fast

Today there are lots of possibilities and in this blogpost I’ll explain you how to use Az DevOps from PowerShell.

Az DevOps is an extension for Azure CLI. Azure CLI is the cross-platform Command Line Interface for Azure, enabling you to execute actions in Azure from a local command prompt, or from the Cloud Shell in the Azure Portal. To install Az DevOps, you’ll first need to install Azure CLI. The best way to install virtually anything on a Windows computer is using Chocolatey. This way there is no need to visit websites, search for downloads and you can even create a setup script to provision a bare Windows installation with all the software you need.

Install Azure CLI and Az DevOps

Follow these steps to install Azure CLI and the Az DevOps extension (more info can be found here:

  1. Start PowerShell as an Admin
  2. Run the following code to install Chocolatey (source:
    Set-ExecutionPolicy Bypass -Scope Process -Force; [System.Net.ServicePointManager]::SecurityProtocol = [System.Net.ServicePointManager]::SecurityProtocol -bor 3072; iex ((New-Object System.Net.WebClient).DownloadString(''))
  3. After the Chocolatey install finished, run this command to install Azure CLI:
    choco install azure-cli -y
  4. After the installation of Azure CLI has finished, it’s best to restart your PowerShell (again as an Admin)
  5. Run the following command to install the Az DevOps extension:
    az extension add --name azure-devops
  6. Now create a Personal Access Token (PAT) in Azure DevOps
  7. In PowerShell type the following to authenticate:
    az devops login
  8. It will prompt you for the PAT you just created; enter it (no **** will appear, so be sure you paste correctly…) and press enter
  9. Nothing happens, that is OK


Microsoft has an extensive reference on all possibilities for Az DevOps, which you can find here: To get started, open up the PowerShell window again and issue the following command (replacing the “your_organisation_name” with the name of your Azure DevOps organization):
az devops project list --org
It will display all Team Projects you have access to.

Count Git repo’s per Team Project

Let’s assume you need to report on the number of Git repo’s per Team Project; there is a command to retrieve the Git repo’s of a specific Team Project, but there is no way to retrieve all of them at once (including the Team Project name), so you’ll need to build a loop (for every Team Project, retrieve the list of repo’s). The command to retrieve repo’s is:
az repos list --org --project your_project
Before you can call the line above, you’ll need to parse the json data from the az project list command to a PowerShell object:
$projects = az devops project list –org | ConvertFrom-Json
Now it’s possible to retrieve properties of that object like: $projects[0].name. That means that we can build up our code like this:
$projects = az devops project list --org | ConvertFrom-Json
foreach ($project in $projects)
$repos = az repos list --org --project $ | ConvertFrom-Json
Write-Host "Team Project $($ has $($repos.count) Git repos"

ConvertFrom-Json is your friend when you want to parse information from the calls to Azure CLI. The alternative is to change the output format using the –output flag to e.g. tsv (tab-separated values) or table (formatted table).

Using Az DevOps for Azure DevOps Server

When Azure DevOps is installed on-premise, the situation can be different. In some cases, self-signed SSL certificates are used. Azure CLI doesn’t like self signed certificates, because they generally don’t validate against a root Certificate Authority.

The error you’ll get when requesting data is:
request failed: Error occurred in request., SSLError: HTTPSConnectionPool(host='devops.xxxx.local', port=443): Max retries exceeded with url: /tfs/defaultcollection/_apis (Caused by SLError(SSLError("bad handshake: Error([('SSL routines', 'tls_process_server_certificate', 'certificate verify failed')],)",),))

In order to work around this, I have written a script that is available on GitHub. This script does the following:

  1. Install OpenSSL Light
  2. Install Azure CLI
  3. Install Az DevOps extension
  4. Retrieves the SSL certificate of your local Azure DevOps Server
  5. Finds the root certificate in the certificate chain
  6. Exports the root certificate to a .cer file on the file system
  7. Converts the certificate file to a .pem file (using OpenSSL) and stores this file
  8. Writes the following environment variables:
    1. REQUESTS_CA_BUNDLE > points to the .pem file
    2. ADAL_PYTHON_SSL_NO_VERIFY > Tells Python to disable server TLS certificate check
    3. AZURE_CLI_DISABLE_CONNECTION_VERIFICATION > Tells Azure CLI to not check the SSL certificate
  9. Sets these variables for the current session as well
  10. Starts the login for Azure Devops

It is very important to first change the 2 topmost variables at the top of the script to make it work correctly! Configure your Azure DevOps Server URL and determine where you want the .pem file to be stored. The last setting is the index of the root certificate. You can check the certificate e.g. in Google Chrome like this:

As indicated in the picture below, the order of the indexes of the certificates are reversed, that’s why I needed to enter “2” as correct index.

The script can be found on Github here:


Keep in mind that the settings made to enable a self-signed SSL certificate as described above need to be made undone in order to work with Azure DevOps Service (Cloud). A quick way to undo them (temporarily):


To remove them permanently, run the following script:
[Environment]::SetEnvironmentVariable("REQUESTS_CA_BUNDLE", $null, [System.EnvironmentVariableTarget]::Machine) [Environment]::SetEnvironmentVariable("ADAL_PYTHON_SSL_NO_VERIFY", $null, [System.EnvironmentVariableTarget]::Machine) [Environment]::SetEnvironmentVariable("AZURE_CLI_DISABLE_CONNECTION_VERIFICATION", $null, [System.EnvironmentVariableTarget]::Machine)


Azure CLI in combination with the extension “Azure DevOps” is a great and very powerful way to control and administer Azure DevOps Service and Server, provided you know what is described in this blogpost.

Leave a Reply

Fill in your details below or click an icon to log in: Logo

You are commenting using your account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s