Posted on Leave a comment

##[error]Script failed with error: Error: Unable to locate executable file: ‘pwsh’.

In AzureCLI@2 you may choose from a variety of options when it comes on how this task will be executed on the agent machine. I usually choose powershell for windows machines and powershell core for Unix based machines (pwsh).

Recently I got an error on a Windows machine when using Powershell core. The latest version of powershell which is currently on 7.* version can be used as pscore in the AzureCLI@2 task.

      - task: AzureCLI@2
        displayName: az cli task
          azureSubscription: 'SERVICE-CONNECTION'
          scriptType: 'pscore'
          scriptLocation: 'inlineScript'
          inlineScript: |

Error message:

##[error]Script failed with error: Error: Unable to locate executable file: ‘pwsh’. Please verify either the file path exists or the file can be found within a directory specified by the PATH environment variable. Also verify the file has a valid extension for an executable file.


In order to bypass this problem you should make sure that the latest version of powershell which is multiplatform should be installed on your system. At the time of this article this version is 7.*

After installing powershell you should make a restart also on the machine in order for the environmental variables to be added on PATH. Then you can execute your pwsh tasks on your agent machines.

Posted on Leave a comment

Initialize and format windows disk with powershell

Sometimes you may need to automatically create windows disk for a virtual server using an automation mechanism. With the below powershell you can initialize a new emtpy disk with GPT partition and format it according to your needs.

You can get your available disks using:


You can use the below powershell and change the below settings:

DriveLetter : What your drive letter will be
AllocationUnitSize: Default is 4k, but in my case I define 64k
DiskNumber: number of disk from Get-Disk command
NewFileSystemLabel: name of the volume

 Initialize-Disk -number 4 -partitionstyle GPT ; New-Partition -DiskNumber 4 -UseMaximumSize ; Format-Volume -DriveLetter G -FileSystem NTFS -AllocationUnitSize 65536 -NewFileSystemLabel Volume-Name

After applying the volume will be created and initialized.

Posted on Leave a comment

Install azure cli using Powershell – silent mode

Az cli is a very important tool that one devops engineer may need to install on systems. You can perform a silent install on a windows machine using the powershell below:

$msiFilePath = "azure-cli.msi"
Invoke-WebRequest -OutFile $msiFilePath
$MSIArguments = @(
    ('"{0}"' -f $msiFilePath)
Start-Process "msiexec.exe" -ArgumentList $MSIArguments -Wait -NoNewWindow
Remove-Item -Path $msiFilePath  -Force

By running the powershell the download procedure will begin.

When the installation finishes you can locate it under installed programs:

Posted on 1 Comment

Deploy windows and linux virtual machines on Azure using terraform

Terraform is one of the best automation providers for DevOps purposes used by hundred of Engineers. It is an open source tool that can be used by anyone for free. In this article I will explain how to deploy windows and linux virtual machines on Azure using a Terraform template.

First things first you will need to have the az cli installed. Then you will have to set your subscription on your current powershell session.

az account set --subscription "12abc123-4567-1234-12345-asdr4334fsd"

Then you will need to create an app role assignment for your subscription. This will be used from terraform for the provision of the resources.

az ad sp create-for-rbac --role="Contributor" --scopes="/subscriptions/12abc123-4567-1234-12345-asdr4334fsd"

That’s all. You can now deploy your resources through terraform. In the links below I have provided my Github repository along with instructions for the template use.

A tricky part of the deployment is the vm image selection. In order to locate the available azure images names you can use:

az vm image list

Enumeration of available images:

    "offer": "CentOS",
    "publisher": "OpenLogic",
    "sku": "7.5",
    "urn": "OpenLogic:CentOS:7.5:latest",
    "urnAlias": "CentOS",
    "version": "latest"
    "offer": "debian-10",
    "publisher": "Debian",
    "sku": "10",
    "urn": "Debian:debian-10:10:latest",
    "urnAlias": "Debian",
    "version": "latest"
    "offer": "flatcar-container-linux-free",
    "publisher": "kinvolk",
    "sku": "stable",
    "urn": "kinvolk:flatcar-container-linux-free:stable:latest",
    "urnAlias": "Flatcar",
    "version": "latest"
    "offer": "openSUSE-Leap",
    "publisher": "SUSE",
    "sku": "42.3",
    "urn": "SUSE:openSUSE-Leap:42.3:latest",
    "urnAlias": "openSUSE-Leap",
    "version": "latest"
    "offer": "RHEL",
    "publisher": "RedHat",
    "sku": "7-LVM",
    "urn": "RedHat:RHEL:7-LVM:latest",
    "urnAlias": "RHEL",
    "version": "latest"
    "offer": "SLES",
    "publisher": "SUSE",
    "sku": "15",
    "urn": "SUSE:SLES:15:latest",
    "urnAlias": "SLES",
    "version": "latest"
    "offer": "UbuntuServer",
    "publisher": "Canonical",
    "sku": "18.04-LTS",
    "urn": "Canonical:UbuntuServer:18.04-LTS:latest",
    "urnAlias": "UbuntuLTS",
    "version": "latest"
    "offer": "WindowsServer",
    "publisher": "MicrosoftWindowsServer",
    "sku": "2019-Datacenter",
    "urn": "MicrosoftWindowsServer:WindowsServer:2019-Datacenter:latest",
    "urnAlias": "Win2019Datacenter",
    "version": "latest"
    "offer": "WindowsServer",
    "publisher": "MicrosoftWindowsServer",
    "sku": "2016-Datacenter",
    "urn": "MicrosoftWindowsServer:WindowsServer:2016-Datacenter:latest",
    "urnAlias": "Win2016Datacenter",
    "version": "latest"
    "offer": "WindowsServer",
    "publisher": "MicrosoftWindowsServer",
    "sku": "2012-R2-Datacenter",
    "urn": "MicrosoftWindowsServer:WindowsServer:2012-R2-Datacenter:latest",
    "urnAlias": "Win2012R2Datacenter",
    "version": "latest"
    "offer": "WindowsServer",
    "publisher": "MicrosoftWindowsServer",
    "sku": "2012-Datacenter",
    "urn": "MicrosoftWindowsServer:WindowsServer:2012-Datacenter:latest",
    "urnAlias": "Win2012Datacenter",
    "version": "latest"
    "offer": "WindowsServer",
    "publisher": "MicrosoftWindowsServer",
    "sku": "2008-R2-SP1",
    "urn": "MicrosoftWindowsServer:WindowsServer:2008-R2-SP1:latest",
    "urnAlias": "Win2008R2SP1",
    "version": "latest"

In order to narrow down and find Ubuntu available images (use grep instead of Select-string for Unix environments)

az vm image list-offers -p canonical -l eastus | Select-String name

Ubuntu images names for east us region:

 "name": "0001-com-ubuntu-confidential-vm-experimental",
    "name": "0001-com-ubuntu-confidential-vm-focal",
    "name": "0001-com-ubuntu-confidential-vm-test-focal",
    "name": "0001-com-ubuntu-minimal-focal-daily",
    "name": "0001-com-ubuntu-minimal-groovy-daily",
    "name": "0001-com-ubuntu-minimal-hirsute-daily",
    "name": "0001-com-ubuntu-minimal-impish-daily",
    "name": "0001-com-ubuntu-minimal-jammy-daily",
    "name": "0001-com-ubuntu-private-fips-motorola",
    "name": "0001-com-ubuntu-pro-advanced-sla",
    "name": "0001-com-ubuntu-pro-advanced-sla-att",
    "name": "0001-com-ubuntu-pro-advanced-sla-csw",
    "name": "0001-com-ubuntu-pro-advanced-sla-dd",
    "name": "0001-com-ubuntu-pro-advanced-sla-nestle",
    "name": "0001-com-ubuntu-pro-advanced-sla-servicenow",
    "name": "0001-com-ubuntu-pro-advanced-sla-shell",
    "name": "0001-com-ubuntu-pro-advanced-sla-ub01",
    "name": "0001-com-ubuntu-pro-advanced-sla-unp",
    "name": "0001-com-ubuntu-pro-bionic",
    "name": "0001-com-ubuntu-pro-bionic-fips",
    "name": "0001-com-ubuntu-pro-focal",
    "name": "0001-com-ubuntu-pro-focal-fips",
    "name": "0001-com-ubuntu-pro-hidden-msft-fips",
    "name": "0001-com-ubuntu-pro-microsoft",
    "name": "0001-com-ubuntu-pro-trusty",
    "name": "0001-com-ubuntu-pro-xenial",
    "name": "0001-com-ubuntu-pro-xenial-fips",
    "name": "0001-com-ubuntu-server-eoan",
    "name": "0001-com-ubuntu-server-focal",
    "name": "0001-com-ubuntu-server-focal-daily",
    "name": "0001-com-ubuntu-server-groovy",
    "name": "0001-com-ubuntu-server-groovy-daily",
    "name": "0001-com-ubuntu-server-hirsute",
    "name": "0001-com-ubuntu-server-hirsute-daily",
    "name": "0001-com-ubuntu-server-impish",
    "name": "0001-com-ubuntu-server-impish-daily",
    "name": "0001-com-ubuntu-server-jammy-daily",
    "name": "0002-com-ubuntu-minimal-bionic-daily",
    "name": "0002-com-ubuntu-minimal-disco-daily",
    "name": "0002-com-ubuntu-minimal-focal-daily",
    "name": "0002-com-ubuntu-minimal-xenial-daily",
    "name": "0003-com-ubuntu-minimal-eoan-daily",
    "name": "0003-com-ubuntu-server-trusted-vm",
    "name": "test-ubuntu-premium-offer-0002",
    "name": "Ubuntu15.04Snappy",
    "name": "Ubuntu15.04SnappyDocker",
    "name": "UbuntuServer",

Specific information about an image:

az vm image list -p canonical -l eastus --offer 0001-com-ubuntu-pro-bionic --all --sku pro-18_04-lts

Inside linux or windows folder depending on the resource you want to deploy apply your terraform configuration

terraform init
terraform apply

After the successful run of the terraform script.

In order to delete the environment you can run

terraform destroy

By committing destroy your eight resources that deal with your virtual machine will disappear.

Repository for the code:

Video tutorial on YouTube: