Use parameter in PowerShell in Azure DevOps pipeline - azure

We have recently started using Azure DevOps Pipelines for our Dynamics 365 CRM implementation, but it is still new to me
I recently came across this blog post by Joe Griffin on how you can use PowerShell in Azure DevOps pipelines to ensure, that Access Team Templates works when deploying a solution - and I would like to use that.
However, I don't know where I add my parameters to script. Can I do that inline or do I need to add the script to my repo to do that? If so - how can I do that?
param(
#objectTypeCode: Unique Code that identifies the table in the environment for the Access Team Template. Always potentially different.
[Parameter(Mandatory=$true)]
[int]$objectTypeCode,
#atName: Name of the Access Team Template
[Parameter(Mandatory=$true)]
[String]$atName,
#accessRights: Number which represents the access rights defined for the template. Refer to this article for details on how to construct: https://learn.microsoft.com/en-us/dynamics365/customer-engagement/web-api/accessrights?view=dynamics-ce-odata-9
[Parameter(Mandatory=$true)]
[int]$accessRights,
#d365URL: URL of the environment to connect to
[Parameter(Mandatory=$true)]
[String]$d365URL,
#clientID: AAD Client ID for the Application User linked to this environment
[Parameter(Mandatory=$true)]
[String]$clientID,
#clientSecret: AAD Client Secret for the Application User linked to this environment
[Parameter(Mandatory=$true)]
[String]$clientSecret
)
#Install dependencies
Install-Module Microsoft.Xrm.Data.PowerShell -Scope CurrentUser -Force
#Connect to the D365 environment
$conn = Connect-CrmOnline -ServerUrl $d365URL -ClientSecret $clientSecret -OAuthClientId $clientID -OAuthRedirectUri "http://localhost"
#We first attempt to retrieve the rows if they already exist, and update it accordingly; if this errors, then the row does not exist, so we need to create it instead
Write-Host "Processing Access Team Template for $atName..."
try
{
$atTemplate = Get-CrmRecord -conn $conn -EntityLogicalName teamtemplate -Id "44396647-CEDF-EB11-BACB-000D3A5810F2" -Fields teamtemplateid,teamtemplatename,objecttypecode,defaultaccessrightsmask,issystem
$atTemplateId = $atTemplate.teamtemplateid
Write-Host "Got existing Access Team Template row with ID $atTemplateId!"
$atTemplate.teamtemplatename = $atName
$atTemplate.objecttypecode = $objectTypeCode
$atTemplate.defaultaccessrightsmask = $accessRights
$atTemplate.issystem = 0
Set-CrmRecord -conn $conn -CrmRecord $atTemplate
Write-Host "Successfully updated Access Team Template row with ID $atTemplateId!"
}
catch [System.Management.Automation.RuntimeException]
{
Write-Host "Access Template row with ID $atTemplateId does not exist, creating..."
$atTemplateId = New-CrmRecord -conn $conn -EntityLogicalName teamtemplate `
-Fields #{"teamtemplateid"=[guid]"{44396647-CEDF-EB11-BACB-000D3A5810F2}";"teamtemplatename"=$atName;"objecttypecode"=$objectTypeCode;"defaultaccessrightsmask"=$accessRights;"issystem"=0}
Write-Host "Successfully created new Access Template row with ID $atTemplateId"
}
Write-Host "Script execution finished!"

You can use "Azure Powershell" task (If the script has to do something on azure) and can specify path to your powershell file and can add parameter values as in this screenshot,
or you can use "Powershell"task and can add path to the file and parameter,

You can add a Powershell task in your yaml and invoke the Powershell script to perform required task. Script arguments can be set in and passed through DevOps library.
- task: AzurePowerShell#5
displayName: 'Powershell task'
inputs:
azureSubscription: '${{ parameters.ServiceConn }}'
ScriptType: 'FilePath'
ScriptPath: '[Path to script]/PowershellScriptName.ps1'
ScriptArguments: '-objectTypeCode $(objectTypeCode) -atName $(atName) -accessRights $(accessRights) -d365URL $(d365URL) -clientID $(clientID) -clientSecret $(clientSecret)'
azurePowerShellVersion: 'LatestVersion'
pwsh: true

Related

Logic App Standard Automate Reference to workflow accross environments

I have automated the deployment of a logic app standard via Azure Devops Pipeline using an arm template.
I have another pipeline that uses the Azure Devops zip deployment task to deploy the workflows (as recommended by Microsoft documentation).
My current struggle is when I have workflows that call other workflows.
When I deploy the zip file across different logic app standard instances the workflow url referenced is always the same.
How can I reference/call the workflow in a way that is not hardcoded and dynamically changes in the deploy? Can I use workflow() to reference other workflows?
As the access key is a property of the workflow and not the logic app standard I'm not able to set it as an app setting or parameter to be consumed inside the workflow.
Any ideas on how to bypass this issue?
What I ended up doing was the following.
I have created key vault secrets. In those key vault secrets I store the workflow url containing the authorization secret.
As I've created the other workflows pointing to the key vault secret name instead of a hardcoded url the logic app at run time will query the key vault, retrieve the url from the workflow i want to authenticate to and use it as input. As it already contains the signature it authenticates correctly.
It's probably a workaround but it was the only way I was able to achieve success in this operation.
For those with the same problem as me here are the steps:
First I have developed the workflow to obtain the secret containing the url from the keyvault
Get keyvault secret
Then it calls the url using the secret as input.
Secret as input for the url
When I have my workflows ready to deploy. I export them and put the code on Azure Devops.
Then in a build pipeline I use the following tasks
task: ArchiveFiles#2
displayName: "Archive Functions"
inputs:
rootFolderOrFile: "$(Build.Repository.LocalPath)/LogicApps"
includeRootFolder: false
archiveFile: "$(Build.ArtifactStagingDirectory)/LogicApps.zip"
task: AzureFunctionApp#1
displayName: "Deploy Functions"
inputs:
azureSubscription: "${ { parameters.Subscription }}"
appName: "mylogicappstandard"
package: "$(Agent.BuildDirectory)/${ { parameters.ArtifactName}}/LogicApps.zip"
task: AzureCLI#2
displayName: 'Update Signature url in ${ { parameters.KeyvaultName}}'
inputs:
azureSubscription: "${ { parameters.Subscription }}"
scriptType: 'ps'
scriptLocation: 'inlineScript'
inlineScript: "$(Agent.BuildDirectory)/${ { parameters.ArtifactName}}/Scripts/Get-WorkflowUrlSignature.ps1 $(AzureSubscriptionId) ${ { parameters.ResourceGroup }} mylogicappstandard ${ { parameters.KeyvaultName}}"
You can find the details for the script here Get-WorkflowUrlSignature.ps1
[CmdletBinding()]
param (
[Parameter(Mandatory)][string]$SubscriptionId,
[Parameter(Mandatory)][string]$ResourceGroup,
[Parameter(Mandatory)][string]$LogicAppName,
[Parameter(Mandatory)][string]$KeyVaultName
)
$json = az rest --method get --uri "https://management.azure.com/subscriptions/$SubscriptionId/resourceGroups/$ResourceGroup/providers/Microsoft.Web/sites/$LogicAppName/hostruntime/runtime/webhooks/workflow/api/management/workflows?api-version=2018-11-01"
$workflows = $json | convertfrom-json
foreach ($workflow in $workflows.Name){
$uri ="https://management.azure.com/subscriptions/$SubscriptionId/resourceGroups/$ResourceGroup/providers/Microsoft.Web/sites/$LogicAppName/hostruntime/runtime/webhooks/workflow/api/management/workflows/$workflow/triggers/manual/listCallbackUrl?api-version=2018-11-01"
if (az rest --method post --uri $uri){
# Gets the url with signature
$sigurl = az rest --method post --uri $uri | convertfrom-json
$secret = $sigurl.value.Replace('&','"&"')
$workflowName = $workflow.Replace("_","")
#Creates or updates secret in the keyvault
Write-Output "Updating secret $workflowName in the keyvault"
az keyvault secret set --name $workflowName --vault-name $KeyVaultName --value $secret
}else{
Write-Output "The workflow $workflow does not have any trigger url"
}
}
I hope this helps other people automate the process. Please let me know if you have an easier way to do it or to query the access key or url sig.

Remove trigger reference from pipeline in azure data factory using powershell

I have a pipeline which has trigger associated in azure data factory. I am trying to automate some of operations in azure data factory using powershell commands. In one use case , I am blocked.
Use Case: User changed pipeline name which has trigger associated. (This is sample only, in reality many pipelines/triggers may be there in data factory, user may change single or many pipelines)
Trigger Name: TRG_Test1
Pipeline Name: PL_Test1
So TRG_Test1 trigger is attached to pipeline PL_Test1.
Requirement: user changed name from PL_Test1 to PL_Test1_Updated , the associated trigger should be detach(remove) from pipeline and then remove pipeline and create new pipeline with new name and attach(associate) same trigger.
Note: There are no changes in trigger details, only pipelines details changed.
By workaround using powershell, I am able to identify for which pipeline has which trigger associated using powershell script. But I am unable to detach pipeline before removing pipeline.
Error:
The document cannot be deleted since it is referenced by
Set-AzDataFactoryV2Trigger : I am using this powershell command when trigger is detached from pipeline and changes to affect in pipeline.
Is there any powershell command to remove only pipeline references?
Any alternative /Work around process to remove references of pipelines?
## Detach/Update the trigger
Set-AzDataFactoryV2Trigger -ResourceGroupName $ADFDeployResourceGroupName -Name $triggerName -DataFactoryName $DataFactoryName -File /$triggerName.json" -Force
##Remove Pipeline
#Remove-AzDataFactoryV2Pipeline -ResourceGroupName $ADFDeployResourceGroupName -Name $PipelineFileName -DataFactoryName $DataFactoryName -Force
If you want to remove the pipeline references in the trigger, please refer to the following code
Connect-AzAccount
$sub=""
$groupName=""
$factoryName=""
$triggerName=""
Select-AzSubscription -Subscription $sub
$sw=Get-AzResource -ResourceId "/subscriptions/$sub/resourceGroups/$groupName/providers/Microsoft.DataFactory/factories/$factoryName/triggers/$triggerName“ -ExpandProperties
#remove the piplines reference
$pipName="Test" // the pipeline you want to remove
$sw.Properties.pipelines =($sw.Properties.pipelines -ne ($sw.Properties.pipelines|Where-Object{$_.pipelineReference.referenceName -eq $pipName}))
$s=Set-AzResource -ResourceId "/subscriptions/$sub/resourceGroups/$groupName/providers/Microsoft.DataFactory/factories/$factoryName/triggers/$triggerName“ -Properties $sw.Properties -Force

New-AzPolicyAssignment - Paramter is not being assigned

I am trying to assign a built-in policy to scope through PowerShell, it is being assigned however the parameter is not being added to the assignment.
In Particular, "Deploy Log Analytics agent for Linux VMs", is being assigned correctly but upon checking assignment, the policy is correctly assigned but parameter "logAnalytics" is empty however we already have a LogAnalytics workspace.
Connect-AzAccount
$subscriptionID ='ABCDFGG-ADSFSDF--SFSDF'
get-azsubscription -SubscriptionId $subscriptionID| set-azcontext
$PolicyName = 'Deploy Log Analytics agent for Linux VMs'
$NewName = 'Deploy Log Analytics agent for Linux VMs-Aug04-2'
# Get a reference to the policy definition to assign
$PolicyAssign = Get-AzPolicyDefinition | Where-Object { $_.Properties.DisplayName -eq $PolicyName}
$Paramter = #{'logAnalytics'=('LA-TEST-EU1')}
New-AzPolicyAssignment -Name $NewName -DisplayName $NewName -Scope /subscriptions/$($SubscriptionId) -PolicyDefinition $PolicyAssign -PolicyParameterObject $Paramter -Location 'eastUS' -AssignIdentity
The logAnalytics parameter value should be in the format of the Resource ID:
/subscriptions/[SUBSCRIPTIION-ID]/resourcegroups/[RESOURCEGROUP-NAME]/providers/microsoft.operationalinsights/workspaces/[WORKSPACENAME]
If you go to your Log Analytics Workspace > Properties you will find the Resource ID. That ID is what you need to use.

Azure DevOps Variable Group not applying in Azure Function Configuration

I am trying to leverage the Variable Group functionality in Azure DevOps.
I have created the variable group within the Release pipeline and I have associated. However, when I release the code to the Function App in Azure; when I go to the Configuration settings in the Function app, the custom settings are not there.
Is there a step I am missing here on getting these to show up?
UPDATE: To fix this; I needed to write the variables. This is the step I did it.
I usually do this using a powershell task after publishing the new code. So add a new powershell task and define it as inline:
$appname = "name of your function app"
$rg = "name of resource group"
$webApp = Get-AzureRmwebApp -ResourceGroupName $rg -Name $appname
$webAppSettings = $webApp.SiteConfig.AppSettings
$hash = #{}
foreach ($setting in $webAppSettings) {
$hash[$setting.Name] = $setting.Value
}
$hash['New name'] = $("pipelineVariable")
Set-AzureRMWebAppSlot -ResourceGroupName $rg -Name $appname -AppSettings $hash -Slot production
PS: define the deployment slot as a variable too

Deploying ARM templates using powershell: asking for subscriptionID even when it is defined

I'm trying to deploy a service on Azure using ARM templates and "deploy.ps1" script previously downloaded from Azure (using portal).
There is the section in the "deploy.ps1" file where you can specify subscription ID, resource group, etc:
param(
[Parameter(Mandatory=$True)]
[string]
$subscriptionId = "ID",
[Parameter(Mandatory=$True)]
[string]
$resourceGroupName = "Name"
......
$templateFilePath = "template.json",
[string]
$parametersFilePath = "parameters.json"
)
Even though SubscriptionID is defined, when I'm executing the "deploy.ps1" script, system keeps asking for subscription ID:
cmdlet deploy.ps1 at command pipeline position 1
Supply values for the following parameters:
subscriptionId:
Could you please help me to solve this issue?
in this case the error was due to the fact that powershell script had some of the parameters defined as Mandatory and you cannot assign default values to mandatory parameters (as #Tomalak hinted).

Resources