Get Status of Pipeline in Azure Data Factory - powershell

I am using Set-AzureRmDataFactoryPipelineActivePeriod to schedule the pipeline via PowerShell. However I am trying to get hold of Azure Commandlet that can give me the completion status of the pipeline once scheduled OR the code should run into some loop till the time the pipeline has not completed.

ADF v2
For v2 of Azure DataFactory, you can use Get-AzureRmDataFactoryV2PipelineRun cmdlet to get pipeline runs from some time period.
Parameters you need to set are ResourceGroupName, DataFactoryName, LastUpdatedAfter and -LastUpdatedBefore and optionally PipelineName.
For example, if you wanted to get pipeline runs from the last hour, for your pipeline my-pipeline in my-adf DataFactory in resource group my-rg, you would execute something like
Get-AzureRmDataFactoryV2PipelineRun -ResourceGroupName "my-rg" `
-DataFactoryName "my-adf" `
-PipelineName "my-pipeline" `
-LastUpdatedAfter (Get-Date).AddHours(-1) `
-LastUpdatedBefore (Get-Date).AddHours(1)
For more information, here's the cmdlet documentation: https://learn.microsoft.com/en-us/powershell/module/azurerm.datafactories/get-azurermdatafactoryv2pipelinerun?view=azurermps-4.4.1
ADF v1
If you are using ADF v1, you can invoke Get-AzureRmDataFactoryRun cmdlet to get pipeline status.However, since in DataFactory v1 output dataset slice is what runs the schedule for pipeline execution, you need to pass your output dataset name as well. Below is an example how you would invoke that cmdlet to get slices from the past hour
Get-AzureRmDataFactoryRun -ResourceGroupName "my-rg" `
-DataFactoryName "my-adf" `
-DatasetName "my-dataset" `
-StartDateTime (Get-Date).AddHours(-1)
For more information, here's the cmdlet documentation: https://learn.microsoft.com/en-us/powershell/module/azurerm.datafactories/get-azurermdatafactoryrun?view=azurermps-5.0.0

Got below code, but from where do we get the $Runid?
while ($True) {
$run = Get-AzureRmDataFactoryV2PipelineRun -ResourceGroupName $resourceGroupName -DataFactoryName $DataFactoryName -PipelineRunId $runId
if ($run) {
if ($run.Status -ne 'InProgress') {
Write-Host "Pipeline run finished. The status is: " $run.Status -foregroundcolor "Yellow"
$run
break
}
Write-Host "Pipeline is running...status: InProgress" -foregroundcolor "Yellow"
}
Start-Sleep -Seconds 30
}

The RunID comes from every pipeline run. With PowerShell, you can Invoke a pipeline and capture the RunID from that cmdlet:
https://learn.microsoft.com/en-us/powershell/module/azurerm.datafactoryv2/Invoke-AzureRmDataFactoryV2Pipeline?view=azurermps-4.4.1
There is an example of setting $RunID in this PS script: https://learn.microsoft.com/en-us/azure/data-factory/scripts/incremental-copy-powershell?toc=%2fpowershell%2fmodule%2ftoc.json

Related

Unable to update Azure Cloud Service Extended Support via Azure Powershell Task

I am attempting to update Azure Cloud Service Extended Support using Azure PowerShell task in Azure DevOps Release pipeline. I receive the follow error when using Update-AzCloudService:
Specified api-version 2021-03-01 does not meet the minimum required api-version 2022-04-04 to set this property SlotType
Here is the code block used in the PowerShell task:
...
$cloudServiceIdentity = #{
CloudServiceName = $cloudServiceName
Location = $location
ResourceGroupName = $resourceGroupName
SubscriptionId = $subscription.Subscription.Id
}
Write-Host "-------------------------------"
Write-Host = "cloudServiceIdentity.CloudServiceName= " $cloudServiceIdentity.CloudServiceName
Write-Host = "cloudServiceIdentity.Location = " $cloudServiceIdentity.Location
Write-Host = "cloudServiceIdentity.ResourceGroupName = " $cloudServiceIdentity.ResourceGroupName
Write-Host = "cloudServiceIdentity.SubscriptionId = " $cloudServiceIdentity.SubscriptionId
Write-Host "-------------------------------"
$cloudService = #{
Location = $location
configurationUrl = $configSas
PackageUrl = $packageSas
OSProfile = $osProfile
}
Write-Host "-------------------------------"
Write-Host = "cloudService.Location= " $location
Write-Host = "cloudService.configurationUrl = " $configSas
Write-Host = "cloudService.PackageUrl = " $packageSas
Write-Host = "cloudService.OSProfile = " $osProfile
Write-Host "-------------------------------"
Write-Host "Starting Azure CSES Update"
Update-AzCloudService -InputObject $cloudServiceIdentity -Parameter $cloudService
Write-Host "Completed Azure CSES Update"
...
I have confirmed that Az.CloudService is running version is 1.1.0 (latest version)
Environment info:
| Environment | Value |
|:----------- |:------|
|Azure DevOps Version|18.181.31626.1 (Azure DevOps Server 2020 Update 1.1)|
|Azure DevOps Azure PowerShell Task |Version 5|
|Azure PowerShell version options - Preferred Azure PowerShell Version| 3.1.0|
|Az.CloudService | 1.1.0|
I have been struggling with this issue for several days and cannot seem to find any information on fixing the problem.
Any insights are greatly appreciated!
Given the error message you shared, I suppose that you could check this comment about api version error.
And run the command below to check the latest released api version.
((get-azresourceprovider -providernamespace Microsoft.Compute).resourcetypes | ?{$_.ResourceTypeName -eq "virtualmachines"}).apiversions
And remodify your api-version parameter in your json or bicep template.
The issue does appear to be related to the AzCloudService Powershell Module or the CloudService Resource by itself. When creating the resource, Azure does seem to select the 2021-03-01 API version even if you have a newer version selected in your ARM Template.
It could be that this tight versioning requirements with the way Powershell makes its queries to the resource doesn't seem to work well with the resource.
In my case, I was using the New-AzCloudService cmdlet and always encountered the issue (note, to update the CloudService resource, you may still need to use the New-AzCloudService cmdlet. If the resource exists, an update operation will be performed. If the resource doesn't exist, a new resource will be created).
I noticed though that if using Powershell, all the parameters need to be specified if using the New-AzCloudService cmdlet.
As specified here in the example Step 13:
https://learn.microsoft.com/en-us/azure/cloud-services-extended-support/deploy-powershell#create-cloud-service-using-profile-objects--sas-uris
you must have to pass in the other parameters before your query will be accepted (at least this is what worked for me). -Tag was not required.
So initially I was passing in my query as follows:
$cloudService = New-AzCloudService `
-Name “ContosoCS” `
-ResourceGroupName “ContosOrg” `
-Location “East US” `
-PackageUrl $cspkgUrl `
-ConfigurationUrl $cscfgUrl
because I only wanted to perform a release update and I always got the error:
Specified api-version 2021-03-01 does not meet the minimum required api-version 2022-04-04 to set this property SlotType
When I passed in all other parameters (I referenced the existing cloud service's parameters since I'm performing an in-place update), it got accepted.
$cloudService = New-AzCloudService `
-Name “ContosoCS” `
-ResourceGroupName “ContosOrg” `
-Location “East US” `
-PackageUrl $cspkgUrl `
-ConfigurationUrl $cscfgUrl `
-UpgradeMode 'Auto' `
-RoleProfile $roleProfile `
-NetworkProfile $networkProfile `
-ExtensionProfile $extensionProfile `
-OSProfile $osProfile
Hope this helps.

Powershell - get string information to a console for user from one script to another

I have 2 scripts, one serves as a Worker - uses variables to complete commands, second serves as a function Library. Worker via variable loads Library and uses functions from there.
As a user, when I run the script I would like to see the output in the console which I defined as the outcome for Library script.
Example Worker script:
Param(
[string]$server_01,
[string]$releaseDefinitionName,
[string]$pathRelease,
[string]$buildNumber,
[string]$command_01,
[string]$scheduledTask_01
)
$pathScriptLibrary = $pathRelease + "\" + $buildNumber + "\" + "_scripts"
. $pathScriptLibrary\_library.ps1
$user = xxx
$password = xxx
$cred = xxx
Invoke-Command -ComputerName $server_01 -Credential $cred -ErrorAction Stop -ScriptBlock {powershell $command_01}
Example Library script:
function Stop-ScheduledTasks{
Write-Output [INFO]: Stopping scheduled tasks... -ForegroundColor White
Get-ScheduledTask -TaskName "$scheduledTask_01" | ForEach {
if ($_.State -eq "Ready") {
Write-Output [WARNING]: Scheduled task $scheduledTask_01 was already stopped. -ForegroundColor Yellow
}
else {
Stop-ScheduledTask -TaskName "$scheduledTask_01"
Write-Output [OK]: Running task $scheduledTask_01 stopped. -ForegroundColor Green
}
}
}
function Start-ScheduledTasks{
Write-Output [INFO]: Starting scheduled tasks... -ForegroundColor White
Get-ScheduledTask -TaskName "$scheduledTask_01" | ForEach {
if ($_.State -eq "Running") {
Write-Output [WARNING]: Scheduled task $scheduledTask_01 already started. -ForegroundColor Yellow
}
else {
Start-ScheduledTask -TaskName "$scheduledTask_01"
Write-Output [OK]: Stopped scheduled task $scheduledTask_01 started. -ForegroundColor Green
}
}
}
Use case:
User starts the deployment by clicning the deploy button in Azure DevOps UI
The task using the Worker script takes function from Library script (in this case stops Scheduled Task) and performs it
User checks log on the Azure DevOps side and sees the custom output lines from Library script. (2 of them now - 1. starting with [INFO], 2. either starting with [WARNING] or [OK]).
Could you please advice a solution how to achieve that? Thank you.
NOTE: Those examples are run in Azure DevOps (on premise) release pipelines and desired outcomes are ment for users running those pipelines.
If you're trying to write to the azure devops pipeline log, then you should avoid using Write-Output. That does something subtly different; it adds to the function's return value.
So for example the Write-Output in the function Stop-ScheduledTask; that is roughly equivalent to you putting at the end of the function:
return "[WARNING]: Scheduled task $scheduledTask_01 was already stopped."
That might end up being printed to the pipeline log, or it might not; and importantly, it might completely mess up a function which is genuinely trying to return a simple value.
Instead of using Write-Output, I recommend using Write-Host. What that does is immediately write a line to the pipeline log, without affecting what a library function will return.
Write-Output "[WARNING]: Scheduled task $scheduledTask_01 was already stopped."
You can also use Write-Warning and Write-Error.

Azure Runbook query running jobs

Azure Powershell runbook, scheduled to run every 1h.
The script runs "Invoke-AzVMRunCommand" to call a Powershell script on remote VM locally.
The problem -
sometimes it runs longer than 1h and overlaps with next in the schedule, and the second run fails with an error related to "Invoke-AzVMRunCommand" :
"Run command extension execution is in progress. Please wait for completion before invoking a run command."
The question - how to query if the runbook job is currently running.
We can not change schedule.
thank you!
This one does the check:
$jobs = Get-AzAutomationJob -ResourceGroupName $rgName -AutomationAccountName $aaName -RunbookName $runbook
$runningCount = ($jobs | Where-Object { $_.Status -eq "Running" }).count
if (($jobs.status -contains "Running" -And $runningCount -gt 1 ) -Or ($jobs.Status -eq "New"))
{
Write-Output "`n This runbook [$runbook] execution is stopped - there is another job currently running. Execution will start as per schedule next hour."
Exit 1
}
else
{
Write-Output "`n Let's proceed with runbook [$runbook] execution - there are no interfering jobs currently running." | Out-File -Filepath StarStop.txt -Append
} #end of check runbook status
You may use Az PowerShell cmdlet Get-AzAutomationJob to check the status of the job. Also, based on that status you may decide to remove or set existing schedule using schedule related cmdlets from here.

Retrieve something from different Azure subscriptions at the same time

I want to run a PowerShell Cmdlet against multiple Azure subscriptions, that's why I've thought about running it within a foreach loop but it did not work:
$Subscriptions = (Get-AzureRmSubscription).SubscriptionId
foreach ($sub in $Subscriptions)
{
Select-AzureRmSubscription -Subscription $sub
Do the task Cmdlet
}
Actually what it does is to run the task against the last subscription it was able to select.
Any better ways to workaround this?
Unfortunately the result cannot be exported to a csv file or a variable because it is displayed under the subscription info, as shown in the following figure.
Try using the Set-AzureRmContext cmdlet to set the subscription:
Get-AzureRmSubscription | ForEach-Object {
$_ | Set-AzureRmContext
# do your task
}

TFS/VSTS Custom variables that aren't string cannot be used

I have been using TFS to create some release variables from PowerShell. I can then use '$Env:Server' in subsequent tasks in TFS to reference this output, this seems great to start with! EG:
Task 1 returns a server name then creates the TFS Variable:
Write-Host "##vso[task.setvariable variable=Server]"MySevrer
Task 2 Uses this information:
Write-Output $env:Server
MyServer
Upon outputting something in another format like an array or a hash table this does not work. The variable that gets created is just string as the documentation states using "Write-Host".
Task1 returns:
##vso[task.setvariable variable=Server] System.Collections.DictionaryEntry
Task 2 can not use this:
Write-Output $env:Server
System.Collections.DictionaryEntry
Output that is created
I have tried outputting this as a string in the array format, EG:
[String]$Server = '#{MyServer=#("192.168.0.1")}'
Write-Host "##vso[task.setvariable variable=Server]"$Server
When i refer to this I try to convert this back to an array within PowerShell, however, I have had issues with doing this inside a script as it will see the string as being a single array object. (Not an array with a value)
Does anyone know if it posable to parse hashtables or arrays between Team Service's tasks/Task Task groups based on information output by a Powershell task?
I have currently got around this by writing a wrapper/orchestration function but this is not the ideal way for us. We are currently on Version 15.117.26714.0 but i cannot see anything in newer versions.
ConvertTo-Json will do the trick, as mentioned by Daniel Mann.
Example:
In Azure Devops release pipeline, there is an Azure PowerShell task with following code:
$apps = Get-AzureRmResource -ResourceGroupName "$(ResourceGroupName)" -ResourceType Microsoft.Web/sites
$objectIdArray = New-Object System.Collections.ArrayList
foreach ($app in $apps) {
if (!$app.Identity) {
Write-Host "Enabling identity for $($app.Name) app service..."
$app = Set-AzureRmWebApp -Name $($app.Name) -ResourceGroupName "$(ResourceGroupName)" -AssignIdentity $true
} else {
Write-Host "$($app.Name) app service has $($app.Identity.PrincipalId) as the identity."
}
$objectIdArray.Add($($app.Identity.principalId))
}
$objectIdArrayJson = ($objectIdArray | ConvertTo-Json -Compress)
Write-Host "##vso[task.setvariable variable=objectIdArray;]$objectIdArrayJson"
Write-Host $env:objectIdArray
The following task is an Azure Resource Group Deployment task that has an overridden parameter:
-objectIdArray "$(objectIdArray)"
The release variable "$(objectIdArray)" has a value like:
["0512706a-0344-418a-9f25-5708d95e44aa","6047cbe6-c109-4aa7-8cfb-b473c088b1b1","68ee0d25-351f-44c8-aecf-cfc259f3cd97","44a6f3d6-23a3-443d-824b-445e0141f09c","805c3e6d-ab31-41f4-9d6c-8c9fc13ce
460","aa13b9db-200d-4c38-abf8-562a915ed8cd","8d1d7ec1-faa6-4af6-b732-331e51e86a90","02222b28-6370-4995-a633-29a1cdd08fd0","a48c21b1-b6ef-4582-b9a0-050965cb3614","9111421b-8535-4326-bbe9-1e891
33a0b56","5b1f6fca-599c-4895-ae4b-fabc0d3a4dd3","b12a935a-b1c3-4dec-b764-7c0a5307a766","8af7d615-c042-43b5-8ac0-736c6cf4ec3f","f0dd4dd9-e540-4e13-a8be-69ce08a6221c","b131e123-a87e-4faf-afed-4
37d6dbae4ab","af7f679b-1ac8-4991-b467-93ba4a16ec22","1bbb649c-b5e6-4f5c-a050-3a0cee0af985","4a7b728e-e8c6-49c0-bde2-54811708d5ab","3b190d28-c390-43c7-9269-1177afaf7b00","49f3777f-8668-4c72-82
60-753f65b933aa","727db5c4-ad56-457e-ad87-47b17c71e29b","801efff8-a852-4e7b-bc81-3d81d3bcfeb5","0947556e-7ece-4a36-a687-3c50f59e32f6"]
Pass them as JSON and use ConvertTo-Json and ConvertFrom-Json to convert them back and forth between JSON representations and PowerShell objects. When using ConvertTo-Json, be sure to use the -Compress flag.