Supplier Communications Agent in Dynamics 365 Supply Chain Management is cool new a feature that leverages AI to automate and streamline communication with suppliers. It helps with tasks like following up on purchase orders, processing vendor responses, and suggesting changes to purchase orders, ultimately improving procurement efficiency and freeing up procurement teams for higher-value activities.
In this article, I would be discussing how to setup SCAs in D365F&O, prerequisites and the challenges you might face, and how to mitigate them.

Immersive home still not appearing? Change the Initial Page from User options >> Preferences:



Check out if any update available to proceed (recommended).

Select Email settings >> Mailbox >> open the mailbox/user account you want to use >>Test and enable mailbox.
Select Users + permissions >> Teams to continue:

Create new team >> and fill out the necessary data and hit Ok:

Select additional users in the prompt, whom you want you to be part of the Team:

Click Next to Continue.
Select Finance and Operations Basic User and Basic user from the Roles to Save:


Click on “Create a new connection” and search for ‘Dataverse’ >> and select the one with iconic green color of Dataverse:

Select Authentication type as oAuth:

And click create, by choosing the Admin account (Agent identity account) with which you would like to operate and finish the step.
Repeat the same exercise for Microsoft Copilot Studio and finish by choosing the Agent identity account explained above:

And now the connections page should like:

winget search Microsoft.PowerShell
With the below command, it can help you update you to the latest version:
winget install --id Microsoft.PowerShell --source winget
And then you can get the version of the PowerShell as:
$PSVersionTable
Keep your Entra ID details handy. Environment Id and Dataverse URL : you can get from PPAC >> your environment. Save the following command as .ps1:
Param(
[Parameter(Mandatory=$true, HelpMessage="Dataverse environment id")]
[string]$environmentId = "",
[Parameter(Mandatory=$true, HelpMessage="Dataverse environment URL")]
[string]$dataverseUrl = "",
[Parameter(Mandatory=$true, HelpMessage="Microsoft Dataverse connection name")]
[string]$DVConnectionName = "",
[Parameter(Mandatory=$true, HelpMessage="Microsoft Copilot Studio connection name")]
[string]$MCSConnectionName = ""
)
# Check PS version
if ($PSVersionTable.PSVersion.Major -lt 7) {
Write-Error 'This script requires at least PowerShell version 7' -ErrorAction Stop
}
# Install the required modules if not already installed
if (-not (Get-Module -ListAvailable -Name Microsoft.PowerApps.PowerShell)) {
Write-Warning -Message 'Installing module Microsoft.PowerApps.PowerShell'
Install-Module -Name Microsoft.PowerApps.PowerShell -AllowClobber -Scope CurrentUser
}
# Install the required modules if not already installed
if (-not (Get-Module -ListAvailable -Name Az.Accounts | Where-Object Version -ge 2.17)) {
Write-Warning -Message 'Installing required version of module Az.Accounts'
Install-Module -Name Az.Accounts -AllowClobber -Scope CurrentUser -Force -MinimumVersion 2.17
}
# Import required modules
Import-Module Az.Accounts -MinimumVersion 2.17
Import-Module Microsoft.PowerApps.PowerShell
function Get-AccessToken {
# Retrieve the access token for the Dataverse environment
$accessToken = Get-AzAccessToken -ResourceUrl "$dataverseUrl" -AsSecureString
$token = $accessToken.Token
$userId = $accessToken.UserId
Write-Host "Access token for $userId retrieved successfully." -ForegroundColor Green
return $token
}
function Get-ConnectionId {
param (
[string]$userProvidedName,
[string]$providerName
)
$matchedConnectionId = $null
$connections = Get-PowerAppConnection -EnvironmentName $environmentId -ConnectorNameFilter $providerName
foreach ($con in $connections) {
if (($con.ConnectionName -eq $userProvidedName) -or ($con.DisplayName -eq $userProvidedName))
{
$matchedConnectionId = $con.ConnectionName
break
}
}
if ($null -eq $matchedConnectionId)
{
Write-Error -Message "Unable to find connection $userProvidedName ($providerName)" -ErrorAction Stop
}
Write-Host "Found connection id $matchedConnectionId for connection $userProvidedName"
return $matchedConnectionId
}
function Get-ConnectionReferenceId {
param(
[string]$connectionReferenceLogicalName,
[securestring]$accessToken
)
$uri = "$dataverseUrl/api/data/v9.2/connectionreferences?`$filter=connectionreferencelogicalname eq '$connectionReferenceLogicalName'"
$response = Invoke-RestMethod -Method Get -Uri $uri -Authentication Bearer -Token $accessToken -ContentType 'application/json'
if ($null -eq $response) {
Write-Error -Message "Connection reference not found for logical name $connectionReferenceLogicalName" -ErrorAction Stop
}
$connectionReferenceDisplayName = $response.value[0].connectionreferencedisplayname
$connectionReferenceId = $response.value[0].connectionreferenceid
Write-Host "Found connection reference id $connectionReferenceId for $connectionReferenceDisplayName ($connectionReferenceLogicalName)"
return $connectionReferenceId
}
function Set-ConnectionReferenceConnection {
param (
[string]$connectionReferenceLogicalName,
[string]$userProvidedConnectionName,
[string]$providerName,
[securestring]$accessToken
)
Write-Host "Updating connection reference ${connectionReferenceLogicalName}..."
$connectionReferenceId = Get-ConnectionReferenceId -connectionReferenceLogicalName $connectionReferenceLogicalName -accessToken $accessToken
$connectionId = Get-ConnectionId -userProvidedName $userProvidedConnectionName -providerName $providerName
$body = @{
"connectionid" = "$connectionId"
} | ConvertTo-Json -Depth 1
$uri = "$dataverseUrl/api/data/v9.2/connectionreferences($connectionReferenceId)"
Write-Host "Updating connection reference URI: $uri with connection id $connectionId"
Invoke-RestMethod -Method Patch -Uri $uri -Authentication Bearer -Token $accessToken -ContentType 'application/json' -Body $body
Write-Host "Connection reference updated successfully." -ForegroundColor Green
Write-Host
}
function ValidateUserEnvironment {
param (
[string]$environmentId
)
$env = Get-PowerAppEnvironment -EnvironmentName $environmentId
if ($null -eq $env) {
Write-Error -Message "Environment $environmentId was not found" -ErrorAction Stop
}
$displayName = $env.DisplayName
Write-Host "Connected to environment: $displayName ($environmentId)"
}
function Enable-TriggerFlow {
param (
[string]$flowId,
[securestring]$accessToken
)
$flowUri = "$dataverseUrl/api/data/v9.2/workflows($flowId)"
$flow = $null
Write-Host "Enabling flow $flowId with uri $flowUri"
try {
$flow = Invoke-RestMethod -Method Get -Uri $flowUri -Authentication Bearer -Token $accessToken -ContentType 'application/json'
}
catch {
Write-Error -Message $_.Exception -ErrorAction Stop
}
$displayName = $flow.name
Write-Host "Activating flow $displayName for id $flowId"
$body = @{
"statecode" = 1 # Activated
"statuscode" = 2 # Activated
} | ConvertTo-Json -Depth 1 -Compress
try {
Invoke-RestMethod -Method Patch -Uri $flowUri -Authentication Bearer -Token $accessToken -ContentType 'application/json' -Body $body
}
catch {
Write-Error -Message $_.Exception -ErrorAction Stop
}
Write-Host "Activated flow $displayName" -ForegroundColor Green
Write-Host
}
# Actual script body
Write-Host
Write-Host "Authenticating interactively..."
Write-Host
Connect-AzAccount -UseDeviceAuthentication
$accessToken = Get-AccessToken
ValidateUserEnvironment -environmentId $environmentId
Write-Host
Write-Host 'Setting up connection references...'
Write-Host
Set-ConnectionReferenceConnection -userProvidedConnectionName $DVConnectionName -providerName "/providers/Microsoft.PowerApps/apis/shared_commondataserviceforapps" -connectionReferenceLogicalName "new_sharedcommondataserviceforapps_6ae5d" -accessToken $accessToken
Set-ConnectionReferenceConnection -userProvidedConnectionName $MCSConnectionName -providerName "/providers/Microsoft.PowerApps/apis/shared_microsoftcopilotstudio" -connectionReferenceLogicalName "msdyn_sharedmicrosoftcopilotstudio_0be09" -accessToken $accessToken
Write-Host
Write-Host 'Activating flows...'
Write-Host
Enable-TriggerFlow -flowId 'c1061034-ff20-f011-9989-002248095ade' -accessToken $accessToken # (Self Heal) Speed up updates in purchase orders with Supplier Communications Agent
Enable-TriggerFlow -flowId '1db577aa-83fe-ef11-bae1-000d3a34a571' -accessToken $accessToken # Speed up updates in purchase orders with Supplier Communications Agent
Enable-TriggerFlow -flowId 'acd7bb36-07a1-ef11-a72d-6045bd0390ae' -accessToken $accessToken # Send follow-up emails to vendors with Supplier Communications Agent
Write-Host
Write-Host 'Supplier communications agent is ready for use' -ForegroundColor Green
And then either double click the file to run/you can launch it from Powershell prompt by:
powershell.exe -File <file path>\<file name>.ps1

Click on select to reach out to the following screen:

Click on Activate to get the Agent started.
In this article, I would be discussing how to setup SCAs in D365F&O, prerequisites and the challenges you might face, and how to mitigate them.
Prerequisites
Check out the prerequisites in order to start with Supplier Comm Agents in D365Immersive home
We must be having Immersive home enabled in D365F&O beforehand to start. Ensure the following feature to be already enabled in your instance:Immersive home still not appearing? Change the Initial Page from User options >> Preferences:
Features
Ensure to turn on the below features from feature management:Power platform configurations
Ensure the following to be enabled/installed by visiting PPAC >> Environments >> your environment >> resources >> D365 Apps:Check out if any update available to proceed (recommended).
Agent identity
Use the User Management to create a agent user identity. What does this mean? In layman’s terms, this means to proceed with SCA installation, we have to have a user, which must not be a physical person (john.doe@abc.com) – this should be more likely an impersonated account, who is not susceptible to change or leave the organization (admin@abc.com).Activating user email and group
Open PPAC >> Your environment >> Settings >> Email >>Select Email settings >> Mailbox >> open the mailbox/user account you want to use >>Test and enable mailbox.
Select Users + permissions >> Teams to continue:
Create new team >> and fill out the necessary data and hit Ok:
Select additional users in the prompt, whom you want you to be part of the Team:
Click Next to Continue.
Select Finance and Operations Basic User and Basic user from the Roles to Save:
Manage connections
Hover over to https://make.powerapps.com >> correct environment and then choose connections. In case they are not visible, click on More >> Connections (pin them, so as not to lose sight of them):Click on “Create a new connection” and search for ‘Dataverse’ >> and select the one with iconic green color of Dataverse:
Select Authentication type as oAuth:
And click create, by choosing the Admin account (Agent identity account) with which you would like to operate and finish the step.
Repeat the same exercise for Microsoft Copilot Studio and finish by choosing the Agent identity account explained above:
And now the connections page should like:
Additional settings
For testing purpose, you can select any vendor >> contact information >> create a new address with any personal email address.Run Powershell script to make Power Automates be responsive by updating the Connection references
Ensure to install latest PowerShell software to on or more than Version 7. To check which version you are on, launch PowerShell >> and run the command (it searches for latest available PowerShell version):winget search Microsoft.PowerShell
With the below command, it can help you update you to the latest version:
winget install --id Microsoft.PowerShell --source winget
And then you can get the version of the PowerShell as:
$PSVersionTable
Keep your Entra ID details handy. Environment Id and Dataverse URL : you can get from PPAC >> your environment. Save the following command as .ps1:
Param(
[Parameter(Mandatory=$true, HelpMessage="Dataverse environment id")]
[string]$environmentId = "",
[Parameter(Mandatory=$true, HelpMessage="Dataverse environment URL")]
[string]$dataverseUrl = "",
[Parameter(Mandatory=$true, HelpMessage="Microsoft Dataverse connection name")]
[string]$DVConnectionName = "",
[Parameter(Mandatory=$true, HelpMessage="Microsoft Copilot Studio connection name")]
[string]$MCSConnectionName = ""
)
# Check PS version
if ($PSVersionTable.PSVersion.Major -lt 7) {
Write-Error 'This script requires at least PowerShell version 7' -ErrorAction Stop
}
# Install the required modules if not already installed
if (-not (Get-Module -ListAvailable -Name Microsoft.PowerApps.PowerShell)) {
Write-Warning -Message 'Installing module Microsoft.PowerApps.PowerShell'
Install-Module -Name Microsoft.PowerApps.PowerShell -AllowClobber -Scope CurrentUser
}
# Install the required modules if not already installed
if (-not (Get-Module -ListAvailable -Name Az.Accounts | Where-Object Version -ge 2.17)) {
Write-Warning -Message 'Installing required version of module Az.Accounts'
Install-Module -Name Az.Accounts -AllowClobber -Scope CurrentUser -Force -MinimumVersion 2.17
}
# Import required modules
Import-Module Az.Accounts -MinimumVersion 2.17
Import-Module Microsoft.PowerApps.PowerShell
function Get-AccessToken {
# Retrieve the access token for the Dataverse environment
$accessToken = Get-AzAccessToken -ResourceUrl "$dataverseUrl" -AsSecureString
$token = $accessToken.Token
$userId = $accessToken.UserId
Write-Host "Access token for $userId retrieved successfully." -ForegroundColor Green
return $token
}
function Get-ConnectionId {
param (
[string]$userProvidedName,
[string]$providerName
)
$matchedConnectionId = $null
$connections = Get-PowerAppConnection -EnvironmentName $environmentId -ConnectorNameFilter $providerName
foreach ($con in $connections) {
if (($con.ConnectionName -eq $userProvidedName) -or ($con.DisplayName -eq $userProvidedName))
{
$matchedConnectionId = $con.ConnectionName
break
}
}
if ($null -eq $matchedConnectionId)
{
Write-Error -Message "Unable to find connection $userProvidedName ($providerName)" -ErrorAction Stop
}
Write-Host "Found connection id $matchedConnectionId for connection $userProvidedName"
return $matchedConnectionId
}
function Get-ConnectionReferenceId {
param(
[string]$connectionReferenceLogicalName,
[securestring]$accessToken
)
$uri = "$dataverseUrl/api/data/v9.2/connectionreferences?`$filter=connectionreferencelogicalname eq '$connectionReferenceLogicalName'"
$response = Invoke-RestMethod -Method Get -Uri $uri -Authentication Bearer -Token $accessToken -ContentType 'application/json'
if ($null -eq $response) {
Write-Error -Message "Connection reference not found for logical name $connectionReferenceLogicalName" -ErrorAction Stop
}
$connectionReferenceDisplayName = $response.value[0].connectionreferencedisplayname
$connectionReferenceId = $response.value[0].connectionreferenceid
Write-Host "Found connection reference id $connectionReferenceId for $connectionReferenceDisplayName ($connectionReferenceLogicalName)"
return $connectionReferenceId
}
function Set-ConnectionReferenceConnection {
param (
[string]$connectionReferenceLogicalName,
[string]$userProvidedConnectionName,
[string]$providerName,
[securestring]$accessToken
)
Write-Host "Updating connection reference ${connectionReferenceLogicalName}..."
$connectionReferenceId = Get-ConnectionReferenceId -connectionReferenceLogicalName $connectionReferenceLogicalName -accessToken $accessToken
$connectionId = Get-ConnectionId -userProvidedName $userProvidedConnectionName -providerName $providerName
$body = @{
"connectionid" = "$connectionId"
} | ConvertTo-Json -Depth 1
$uri = "$dataverseUrl/api/data/v9.2/connectionreferences($connectionReferenceId)"
Write-Host "Updating connection reference URI: $uri with connection id $connectionId"
Invoke-RestMethod -Method Patch -Uri $uri -Authentication Bearer -Token $accessToken -ContentType 'application/json' -Body $body
Write-Host "Connection reference updated successfully." -ForegroundColor Green
Write-Host
}
function ValidateUserEnvironment {
param (
[string]$environmentId
)
$env = Get-PowerAppEnvironment -EnvironmentName $environmentId
if ($null -eq $env) {
Write-Error -Message "Environment $environmentId was not found" -ErrorAction Stop
}
$displayName = $env.DisplayName
Write-Host "Connected to environment: $displayName ($environmentId)"
}
function Enable-TriggerFlow {
param (
[string]$flowId,
[securestring]$accessToken
)
$flowUri = "$dataverseUrl/api/data/v9.2/workflows($flowId)"
$flow = $null
Write-Host "Enabling flow $flowId with uri $flowUri"
try {
$flow = Invoke-RestMethod -Method Get -Uri $flowUri -Authentication Bearer -Token $accessToken -ContentType 'application/json'
}
catch {
Write-Error -Message $_.Exception -ErrorAction Stop
}
$displayName = $flow.name
Write-Host "Activating flow $displayName for id $flowId"
$body = @{
"statecode" = 1 # Activated
"statuscode" = 2 # Activated
} | ConvertTo-Json -Depth 1 -Compress
try {
Invoke-RestMethod -Method Patch -Uri $flowUri -Authentication Bearer -Token $accessToken -ContentType 'application/json' -Body $body
}
catch {
Write-Error -Message $_.Exception -ErrorAction Stop
}
Write-Host "Activated flow $displayName" -ForegroundColor Green
Write-Host
}
# Actual script body
Write-Host
Write-Host "Authenticating interactively..."
Write-Host
Connect-AzAccount -UseDeviceAuthentication
$accessToken = Get-AccessToken
ValidateUserEnvironment -environmentId $environmentId
Write-Host
Write-Host 'Setting up connection references...'
Write-Host
Set-ConnectionReferenceConnection -userProvidedConnectionName $DVConnectionName -providerName "/providers/Microsoft.PowerApps/apis/shared_commondataserviceforapps" -connectionReferenceLogicalName "new_sharedcommondataserviceforapps_6ae5d" -accessToken $accessToken
Set-ConnectionReferenceConnection -userProvidedConnectionName $MCSConnectionName -providerName "/providers/Microsoft.PowerApps/apis/shared_microsoftcopilotstudio" -connectionReferenceLogicalName "msdyn_sharedmicrosoftcopilotstudio_0be09" -accessToken $accessToken
Write-Host
Write-Host 'Activating flows...'
Write-Host
Enable-TriggerFlow -flowId 'c1061034-ff20-f011-9989-002248095ade' -accessToken $accessToken # (Self Heal) Speed up updates in purchase orders with Supplier Communications Agent
Enable-TriggerFlow -flowId '1db577aa-83fe-ef11-bae1-000d3a34a571' -accessToken $accessToken # Speed up updates in purchase orders with Supplier Communications Agent
Enable-TriggerFlow -flowId 'acd7bb36-07a1-ef11-a72d-6045bd0390ae' -accessToken $accessToken # Send follow-up emails to vendors with Supplier Communications Agent
Write-Host
Write-Host 'Supplier communications agent is ready for use' -ForegroundColor Green
And then either double click the file to run/you can launch it from Powershell prompt by:
powershell.exe -File <file path>\<file name>.ps1
Next is what
Reach out to your Agents’ library and choose the Supplier’s Communication Agent, to customize the Agent:Click on select to reach out to the following screen:
Click on Activate to get the Agent started.
*This post is locked for comments