Cannot set powershell output variables in Devops step - azure

I am trying to use an output variable from a powershell script. I'm using Devops online using the classic UI and tried both powershell 4.* and Powershell 5.* tasks in a release pipeline.
I am using a self-hosted agent that is working and doing lots of other build and release powershell stuff just fine. Azure Powershell modules version 3.5.0 (there is a reason for not using 4.x right now).
To simplify it, here is my test inline script in total...:
Write-Host '##vso[task.setvariable variable=MobileAppInsightsKey;isOutput=true;]thisisthekey'
Write-Host "This is host"
Write-Output '##vso[task.setvariable variable=MobileAppInsightsKey;isOutput=true;]thisisthekey'
Write-Output "This is output"
Here is the output from the Azure powershell task. (4.*)
2020-07-01T00:06:57.2970494Z ##[section]Starting: Azure PowerShell script: InlineScript
2020-07-01T00:06:57.3335882Z
==============================================================================
2020-07-01T00:06:57.3336692Z Task : Azure PowerShell
2020-07-01T00:06:57.3337292Z Description : Run a PowerShell script within an Azure environment
2020-07-01T00:06:57.3337566Z Version : 4.171.1
2020-07-01T00:06:57.3338039Z Author : Microsoft Corporation
2020-07-01T00:06:57.3338575Z Help : https://aka.ms/azurepowershelltroubleshooting
2020-07-01T00:06:57.3338930Z
==============================================================================
2020-07-01T00:06:58.5902105Z ## Validating Inputs
2020-07-01T00:06:58.5915067Z ## Validating Inputs Complete
2020-07-01T00:06:58.5924850Z ## Initializing Az module
2020-07-01T00:06:59.0747435Z ##[command]Import-Module -Name C:\Program
Files\WindowsPowerShell\Modules\Az.Accounts\1.9.0\Az.Accounts.psd1 -Global
2020-07-01T00:07:00.0802372Z ##[command]Clear-AzContext -Scope Process
2020-07-01T00:07:01.5597330Z ##[command]Clear-AzContext -Scope CurrentUser -Force -ErrorAction SilentlyContinue
2020-07-01T00:07:01.9691282Z ##[command]Connect-AzAccount -Identity #processScope
2020-07-01T00:07:03.1860248Z ##[command] Set-AzContext -SubscriptionId 5ec8ec06-XXXX-XXXX-XXXX- c0ff86c50e4 -TenantId ***
2020-07-01T00:07:03.9196710Z ## Az module initialization Complete
2020-07-01T00:07:03.9203692Z ## Beginning Script Execution
2020-07-01T00:07:03.9674782Z ##[command]& 'C:\DevOps\_work\_temp\1b1b130b-4306-448b-b4b2-e7daefc2382e.ps1'
2020-07-01T00:07:03.9974844Z This is host
2020-07-01T00:07:04.0101140Z This is output
2020-07-01T00:07:04.0517610Z ##[command]Disconnect-AzAccount -Scope Process -ErrorAction Stop
2020-07-01T00:07:04.4795714Z ##[command]Clear-AzContext -Scope Process -ErrorAction Stop
2020-07-01T00:07:04.9468120Z ## Script Execution Complete
2020-07-01T00:07:04.9857991Z ##[section]Finishing: Azure PowerShell script: InlineScript
Note that "This is Host" and "This is Output" both display but the "##vso[...." does not.
Also the MobileAppInsightsKey I am trying to read in a subsequent step is empty (uninitialized).
Hopefully someone can point me in the right direction.
Thanks, Mark.

And to make a clear description about this issue:
To define a job-scoped variable in your scenario, we don't need to add isOutput=true;
1.For job-scoped variable(Variable is only valid in current job):
Write-Host '##vso[task.setvariable variable=MobileAppInsightsKey]thisisthekey' is enough. And we can output its value via format $(MobileAppInsightsKey) in CMD task.
2.For multi-job output variable(Variable is valid in multi-job):
We should use Write-Host '##vso[task.setvariable variable=MobileAppInsightsKey;isOutput=true;]thisisthekey'.
In current job: You can use $(referencename.variablename) to get its value. (Support classic pipeline and yaml pipeline)
In subsequent jobs: Use below format to access the variable, and this format only supports yaml pipeline!!!
- job: B
dependsOn: A
pool:
vmImage: 'ubuntu-16.04'
variables:
myVarFromJobA: $[ dependencies.A.outputs['setvarStep.myOutputVar'] ] # map in the variable
# remember, expressions require single quotes
steps:
- script: echo $(myVarFromJobA)
name: echovar
So for your scenario in which you want to access the variable in same job, just remove the isOutput=true;(it's not necessary). Or use $(referencename.variablename) format if you add isOutput=true; in the statement. (Not necessary, not recommended, but it should also work for current job)
In addition:
Details about $(referencename.variablename) format.
For Classic pipeline:(Set name as Test in Powershell task)
$(Test.MobileAppInsightsKey) represents the value of the variable.
For yaml pipeline:
- powershell: echo "##vso[task.setvariable variable=myOutputVar;isOutput=true]this is the value"
name: Test
- script: echo $(Test.myOutputVar)

More messing around and I made it work. The answer goes against everything I have read both in docs and on SO.
If I don't use the
isOutput=true;
then it works.
I don't know why but happy to be educated.
Thx, Mark.

Related

Azure DevOps - Set-Azcontext - The term 'Set-Azcontext' is not recognized

I have created one Azure DevOps pipeline.
99% of this pipeline calls PowerShell scripts (PowerShell Core script type).
Within the Power Shell scripts are calls to the AZ module - this all works fine.
I now have to add a new step within the DevOps pipeline to set the 'VulnerabilityAssessment' on an SQL server - however this time I need to call module 'Set-Azcontext' as part of the PowerShell script which is shown below...
[CmdletBinding()]
param(
$prgname,
$psqlservername,
$psaname,
$pnotificationmmail = 'john.doe#hotmail.com',
$psubscriptionname = 'ABC'
)
#debug
#Get-Module -Name AZ -ListAvailable
# working in powershell and need to set the correct subscription in powershell (ABC)
Set-Azcontext -Subscription "ABC"
#Enable-AzSqlServerAdvancedDataSecurity -ResourceGroupName $prgname -ServerName $pservername -DoNotConfigureVulnerabilityAssessment
# https://learn.microsoft.com/en-us/powershell/module/az.sql/update-
azsqlservervulnerabilityassessmentsetting?view=azps-7.5.0
#Update-AzSqlServerVulnerabilityAssessmentSetting -ResourceGroupName $prgname -ServerName $pservername -StorageAccountName $psaname -ScanResultsContainerName "vulnerability-assessment" -RecurringScansInterval Weekly -EmailAdmins $true -NotificationEmail #pnotificationmmail
When the Azure devOps pipeline runs it fails on step...Set-Azcontext -Subscription "ABC"
update-vulnerability-assessment.ps1 : The term 'Set-Azcontext' is not recognized as a name of a cmdlet, function, script file, or executable program.
Check the spelling of the name, or if a path was included, verify that the path is correct and try again.
The devOps process is running on a Azure agent. It looks like a module is not available or loaded.
Maybe I need to install/load the module containing 'Set-Azcontext' as part of the powershell script ? (if so how do I do this)
OR
Install a new capibility of the agent to have the module containing 'Set-Azcontext' installed?(if so how do I do this)
Going to instead via an ARM template in the Azure pipeline for setting the vulneratibilty of Azure SQL server

DevOps registration script error: Current() ).IsInRole(...)

I can't get my registration script to run in PowerShell (admin). It works in Powershell ISE, but then the script is stuck at "Connecting to the server..."
Am I doing something wrong?
This is the script:
$ErrorActionPreference="Stop";If(-NOT ([Security.Principal.WindowsPrincipal][Security.Principal.WindowsIdentity]::GetCurrent() ).IsInRole( [Security.Principal.WindowsBuiltInRole] “Administrator”)){ throw "Run command in an administrator PowerShell prompt"};If($PSVersionTable.PSVersion -lt (New-Object System.Version("3.0"))){ throw "The minimum version of Windows PowerShell that is required by the script (3.0) does not match the currently running version of Windows PowerShell." };If(-NOT (Test-Path $env:SystemDrive\'azagent')){mkdir $env:SystemDrive\'azagent'}; cd $env:SystemDrive\'azagent'; for($i=1; $i -lt 100; $i++){$destFolder="A"+$i.ToString();if(-NOT (Test-Path ($destFolder))){mkdir $destFolder;cd $destFolder;break;}}; $agentZip="$PWD\agent.zip";$DefaultProxy=[System.Net.WebRequest]::DefaultWebProxy;$securityProtocol=#();$securityProtocol+=[Net.ServicePointManager]::SecurityProtocol;$securityProtocol+=[Net.SecurityProtocolType]::Tls12;[Net.ServicePointManager]::SecurityProtocol=$securityProtocol;$WebClient=New-Object Net.WebClient; $Uri='[url]';if($DefaultProxy -and (-not $DefaultProxy.IsBypassed($Uri))){$WebClient.Proxy= New-Object Net.WebProxy($DefaultProxy.GetProxy($Uri).OriginalString, $True);}; $WebClient.DownloadFile($Uri, $agentZip);Add-Type -AssemblyName System.IO.Compression.FileSystem;[System.IO.Compression.ZipFile]::ExtractToDirectory( $agentZip, "$PWD");.\config.cmd --deploymentgroup --deploymentgroupname "Production" --agent $env:COMPUTERNAME --runasservice --work '_work' --url '[devopsUrl]' --projectname 'Storms' --auth PAT --token [token]; Remove-Item $agentZip;
The quotation marks are the issue. There are multiple types of quotation marks and depending on your country of residence this can cause issues.
This can be solved by removing the quotation marks around "Administrator" and adding them back manualy.
You can see the difference here:
“Administrator” versus "administrator"
Notice the difference in the quotation marks? The first pair is american and the second is the european version.
To resolve the above issue we need to run the script on Windows PowerShell (Run as Administrator)
For more information Please refer the below links:
Blog:- DevOps Deployment Group script stuck on “Connecting to the server.
Blog:- Getting started with Azure DevOps -create a deployment group

Azure file copy task Devops Pipelines is failing with error

We have a build pipeline that includes an Azure File Copy task which copies some files from our build output to an Azure VM.
Every day now for at least a week this task has been failing with the following error:
##[error]Failed to enable copy prerequisites. Multiple VMExtensions per handler not supported for OS type 'Windows'. VMExtension
'WinRMCustomScriptExtension' with handler
'Microsoft.Compute.CustomScriptExtension' already added or specified
in input.
We have had this issue before a few times, however, the problem has, up until now seamed to corrected itself without any changes by us. This time however, it does not look like the problem is going to resolve itself without some changes or intevention.
Can you help?
Could you please provide some more information?
Which version of Copy Files are you using?
Are you using Classic or Azure Pipelines?
Which agent pool are you using?
Can you post the yaml of the Task here like this:
steps:
- task: CopyFiles#2
displayName: 'Copy Files to: 123'
inputs:
TargetFolder: /output
Azure File Copy task might fail to remove a custom extension after finishing using it. You can refer to an issue reported here.
You can try using the newest version of task Azure File Copy. Or try running below scripts to uninstall the extension before using this task as suggested in the issue thread above..
$ExtensionName = Get-AzureRmVMExtension -ResourceGroupName $VM.ResourceGroupName -VMName $VM.Name -Name WinRMCustomScriptExtension
Remove-AzureRmVMCustomScriptExtension -ResourceGroupName $VM.ResourceGroupName -VmName $VM.Name -Name $ExtensionName

Error in Powershell Task with setting $var 'The term 'keyVaultName' is not recognized as the name of a cmdlet"

Error message:
[error]The term 'keyVaultName' is not recognized as the name of a cmdlet, function, script file, or operable program. Check the spelling of the name, or if a path was included, verify that the path is correct and try again.
Developing azure devops YAML pipeline.
My inline script in my powershell task
- task: AzurePowerShell#4
inputs:
azureSubscription: '<REDACTED>'
ScriptType: 'InlineScript'
Inline: |
Install-Module -Name "AzureAD"
$keyVaultAdGroup = 'rkimkeyvault'
$keyVaultName = 'rkaksKeyVault'
As you can see I clearly have $ in front of keyVaultName to make this a variable. Not sure why it is trying to see it as a cmdlet.
I guess you need to install, ensure that the AzureRM.KeyVault module is installed and loaded:
Install-Module AzureRM.KeyVault
Import-Module AzureRM.KeyVault
I figured there is something beyond those lines of code that is the problem. So with a divide and conquer approach, I found my problem was this the ( ) around roleNameGUID
Write-Host "##vso[task.setvariable variable=roleNameGuid]$(roleNameGuid)"
I took those brackets away and it is fine.

Calling a PowerShell script from Azure batch custom activity using PowerShell and application environment variable

I've been slowly working out how to call a PowerShell script to transform IIS logs using LogParser 2.2. I've settled on using Azure Data Factory Batch Service Custom Activity to run the PowerShell script. I've been able to figure out how to address many of the file path issues that arise in running PowerShell from within Azure Custom Batch Activity, but I can't figure this one out.
Currently I'm just trying to print via Write-Host the environment variable AZ_BATCH_APP_PACKAGE_powershellscripts#1.0 I've been able to print other environment variables, but I believe the #1.0 at the end of this one is causing all my grief. BTW the 1.0 is the version of the application loaded into the batch framework in Azure.
All of the following attempts have failed:
powershell powershell Write-Host "$AZ_BATCH_APP_PACKAGE_powershellscripts#1.0"
powershell Write-Host "$AZ_BATCH_APP_PACKAGE_powershellscripts#1.0"
powershell Write-Host "$env:AZ_BATCH_APP_PACKAGE_powershellscripts#1.0"
powershell powershell Write-Host "$env:AZ_BATCH_APP_PACKAGE_powershellscripts\#1.0"
powershell powershell Write-Host "$env:AZ_BATCH_APP_PACKAGE_powershellscripts/#1.0"
powershell powershell Write-Host "$env:AZ_BATCH_APP_PACKAGE_powershellscripts"
powershell powershell Write-Host "$env:AZ_BATCH_APP_PACKAGE_powershellscripts`#1.0"
powershell powershell Write-Host "$env:AZ_BATCH_APP_PACKAGE_powershellscripts`#1`.0"
powershell powershell Write-Host "$env:AZ_BATCH_APP_PACKAGE_powershellscripts\`#1.0"
powershell powershell Write-Host "$AZ_BATCH_APP_PACKAGE_powershellscripts`#1.0"
These works, but are either cmd window or not the variable I want:
powershell powershell Write-Host "$env:AZ_BATCH_TASK_DIR"
powershell powershell Write-Host "$env:AZ_BATCH_ACCOUNT_URL"
cmd /c echo %AZ_BATCH_APP_PACKAGE_powershellscripts#1.0%
So what is the secret syntax sugar to getting this to work in Azure?
Sure, you can do this:
powershell powershell Write-Host "$((Get-Variable -Name 'AZ_BATCH_APP_PACKAGE_powershellscripts#1.0').Value)"
Or this:
powershell powershell Write-Host (Get-Variable -Name "AZ_BATCH_APP_PACKAGE_powershellscripts#1.0").Value
I went through close to 50 tries before getting this to work like so:
powershell powershell Write-Host (Get-ChildItem Env:AZ_BATCH_TASK_DIR).Value
powershell powershell Write-Host (Get-ChildItem Env:AZ_BATCH_APP_PACKAGE_powershellscripts#1.0).Value
Now this was just a stepping stone to running a PowerShell script stored in an attached application to the Azure Batch module. I'm hopeful Microsoft will add a Databrick or better way to run a PowerShell script in Azure Data Factory, but until then this is the only method I found to run a powershell script:
powershell powershell -command ("(Get-ChildItem Env:AZ_BATCH_APP_PACKAGE_powershellscripts#1.0).Value" + '\Powershell\processWebLogsFromAzure.ps1')
This should work for anyone just trying to run from the Batch Task Dir:
powershell powershell -command ("$env:AZ_BATCH_TASK_DIR" + '\wd\processWebLogsFromAzure.ps1')
Hope it helps someone!

Resources