How to run powershell script from Azure DevOps Pipelines
Tags: azure, devops, pipeline, powershell
Published: 2022-07-15 06:04:14

Hello everyone, today we will be learning how to run a powershell script from Azure DevOps pipelines. To know what are the benefits of Powershell scripts over any other scripting language, view Microsoft's official [documentation](https://devblogs.microsoft.com/powershell/powershell-benefits-over-com-scripting/). Objectives of this article:

- How to run Powershell from Azure DevOps pipelines

- Creating a Powershell script that communicates with Azure DevOps API 

- How to save variables, secrets for Azure pipelines that can be passed to Powershell as arguments

- Create published artifacts out of csv generated by the powershell script

Firstly, open your Azure DevOps project's repo, and add your script there. Below is the Powershell script, name of the script can be anything with ps1 extension. I am keeping azureoperationsscript.ps1:

```
[CmdletBinding()]
param (
    $OrganizationUrl,
    $PAT,
    $OrganizationName
)

$orgUrl = $OrganizationUrl
$pat = $PAT

# Create header with PAT
$token = [System.Convert]::ToBase64String([System.Text.Encoding]::ASCII.GetBytes(":$($pat)"))
$header = @{authorization = "Basic $token"}


# Get the list of all projects in the organization
$projectsUrl = "$OrganizationUrl/_apis/projects?api-version=5.1"
$projects = Invoke-RestMethod -Uri $projectsUrl -Method Get -ContentType "application/json" -Headers $header
$projects.value | ForEach-Object {
   Write-Host $_.id $_.name
   $user =[pscustomobject]@{
        'id' = $_.id
        'name' = $_.name
    }
    $user | Export-CSV -Path allprojnameid.csv -Append -NoTypeInformation -Force
}
```
If not aware of basic Powershell scripting syntax and structure please view, the tutorial [series](https://www.tutorialspoint.com/powershell/index.htm). **Invoke-RestMethod** cmdlet sends HTTP and HTTPS requests to REST web services that return richly structured data.
The script takes the parameters passed from the command argument, then calls the Azure DevOps Rest API to return all the projects inside an organization, and lastly saves it in a CSV file.

Once the script is ready, it's time to create the pipeline that is going to call the Script to perform the Azure DevOps API operations. 

In Project -> Pipelines -> Go to the pipeline where you want to add the variable and run the Powershell script, you will get an Edit option, click on it. 

![Pipeline page](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/0pbmyusdkmf2n420cm8g.png)

Follow the below images to set any variable(you can also keep the value of the variable as secret) that is accessible by all the pipelines.

![Set variable option](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/mf7olzb3ykaftpdzm7wz.png)


![Fields while setting a variable](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/ekvt1tr2itmeewjv87u4.png)

Now create a new pipeline by going in pipeline section of project.
Based on the code in your repo, Azure will suggest some pipelines, you can select the "Starter Pipeline". And replace below yml pipeline content with the starter pipeline code.

```
trigger:
- main

stages:
  - stage: Build
    pool:
      vmImage: 'windows-latest'
    jobs:
    - job: Build
      displayName: 'Powershell Script Execute'
      steps:
        - task: PowerShell@2
          displayName: 'Run Powershell Build'
          inputs:
            targetType: 'inline'
            script: '.\azureoperationsscript.ps1 -OrganizationUrl $(OrganizationUrl) -PAT $(PAT) -OrganizationName $(OrganizationName)'
            
        - task: PublishBuildArtifacts@1
          inputs:
            PathtoPublish: 'D:\a\1\s\allprojnameid.csv'
            ArtifactName: 'drop'
            publishLocation: 'Container'
```
To tell what is happening in above pipeline. The first task, **-task: PowerShell@2** is Azure DevOps pipeline task that is used to run powershell scripts placed inside Azure DevOps repositories. In the inputs, give the path where your script is located in the repo. 

**Note: We are passing the variables that we saved above as argument, which will be then accessible to the parameters in the GetAllProjects.ps1.**

The second task **- task: PublishBuildArtifacts@1** is the task 
responsible to publish build artifacts to Azure Pipelines, file share, or a TFS. In inputs, **PathtoPublish** field expects the path of the file where you have exported your csv file. 

All set!!!
Once you save the pipeline, you can go to Pipeline section again to view your pipeline running. Once it has run successfully, you will be able to see an artifact published which came out of a csv file created by the script.


![Published Artifact](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/jfymi0zwi5u9w1uy1tqi.png)

Thank you.