Azure DevOps Pipelines – How to enable Cloud Flows using PowerShell

The below example will demonstrate how to enable cloud flows in Dynamics 365 after a solution deployment using Azure DevOps Pipelines and Releases. I will be using an Application User for authentication.

[CmdletBinding()]
param(
  [string]$tenantId,
  [string]$applicationId,
  [string]$clientSecret,
  [string]$solutionName,
  [string]$azureactivedirectoryobjectid
)
$url = $Env:url
$connectionString  = "AuthType=ClientSecret;ClientId=$applicationId;ClientSecret=$clientSecret;Url=$url"

Write-Host "Starting Enabling Cloud Flows Power Shell Script..."

# Login to PowerApps for the Admin commands
Write-Host "Login to PowerApps for the Admin commands"
Install-Module  Microsoft.PowerApps.Administration.PowerShell -RequiredVersion "2.0.105" -Force -Scope CurrentUser -AllowClobber
Add-PowerAppsAccount -TenantID $tenantId -ApplicationId $applicationId -ClientSecret $clientSecret -Endpoint "prod"
 
# Login to PowerApps for the Xrm.Data commands
Write-Host "Login to PowerApps for the Xrm.Data commands"
Install-Module  Microsoft.Xrm.Data.PowerShell -RequiredVersion "2.8.14" -Force -Scope CurrentUser -AllowClobber
$conn = Get-CrmConnection -ConnectionString $connectionString
$user = Get-CrmRecords -conn $conn -EntityLogicalName systemuser -FilterAttribute azureactivedirectoryobjectid -FilterOperator eq -FilterValue $azureactivedirectoryobjectid
 
# Create a new Connection to impersonate the creator of the connection reference
$impersonatedconn = Get-CrmConnection -ConnectionString $connectionString
$impersonatedconn.OrganizationWebProxyClient.CallerId = $user.CrmRecords[0].systemuserid
 
$existingconnectionreferences = (ConvertTo-Json ($connectionsrefs | Select-Object -Property connectionreferenceid, connectionid)) -replace "`n|`r",""
Write-Host "##vso[task.setvariable variable=CONNECTION_REFS]$existingconnectionreferences"
Write-Host "Connection References:$existingconnectionreferences"

# Get the flows that are turned off
Write-Host "Get Flows that are turned off"
$fetchFlows = @"
<fetch>
  <entity name='workflow' >
    <attribute name='category' />
    <attribute name='name' />
    <attribute name='statecode' />
    <attribute name='workflowid' />
    <filter type='and' >
      <condition attribute='category' operator='eq' value='5' />
      <condition attribute='statecode' operator='eq' value='0' />
    </filter>
    <link-entity name='solutioncomponent' from='objectid' to='workflowid' >
      <filter>
        <condition attribute='solutionidname' operator='eq' value='$solutionName' />
      </filter>
    </link-entity>
  </entity>
</fetch>
"@;

$flows = (Get-CrmRecordsByFetch  -conn $conn -Fetch $fetchFlows -Verbose).CrmRecords
if ($flows.Count -eq 0)
{
    Write-Host "##vso[task.logissue type=warning]No Flows that are turned off in $solutionName."
    Write-Output "No Flows that are turned off"
    exit(0)
}
 
# Turn on flows
foreach ($flow in $flows){
  try {
    Write-Output "Turning on Flow:$(($flow).name)"
    Set-CrmRecordState -conn $impersonatedconn -EntityLogicalName workflow -Id $flow.workflowid -StateCode Activated -StatusCode Activated -Verbose -Debug
  }
  catch {
    Write-Warning "An error occored when activating flow:$(($flow).name)"
    Write-Warning $_
  }
    
}

You will need to add the PowerShell script as a PowerShell task inside of the Releases Agent Job.


Variables

You will need to add your Application User connection details as Release Variables so they can be referenced in the PowerShell task.


Script Path

You can either reference the code inside of the published Artifiact or you can add the code directly to the task as an inline.


Arguments

You will also need to pass arguments inside of the task otherwise the PowerShell code wont know what these variables are:

-tenantId $(tenantId) -applicationId $(applicationId) -clientSecret $(clientSecret) -solutionName $(solutionName) -azureactivedirectoryobjectid $(azureactivedirectoryobjectid)

Environment Variables

You will also need to set what target environment url you will be checking against by adding an Environment Variable

9 thoughts on “Azure DevOps Pipelines – How to enable Cloud Flows using PowerShell

  1. Hi,

    Do we have any way to modify the existing connection reference with connection (connection id) using PowerShell commands?

    I am really struggling to find a solution to this scenario.

  2. How to fix “Cannot bind argument to parameter ‘records’ because it is null.” when there are no records returned by the fetch xml?

  3. Hi,

    I don’t why it’s still using the SPN rather than impersonation as it complained the SPN cannot turn on the flow either because the shared connection is not a valid one or because it is not a connection you have access permission.

  4. We are getting ‘cannot conver null to type “system.guid”.’
    $impersonaredconn.oraganizationWebProxyClient.CallerID =$user.CrmRecords[0].systemuserid

    1. Hi Harish,

      Did you put in the correct guid for $azureactivedirectoryobjectid? This should be the azure activedirectory id of the Application User that you are using for the deployment

  5. What is the purpose for the section regarding $existingconnectionreferences? This doesn’t seem to be related to the other actions in the script.

Leave a Reply

Your email address will not be published. Required fields are marked *