Application Lifecycle Management für Analysen zu Datenmodellanpassungen
Gilt für: Dynamics 365 Customer Service
Dieser Artikel enthält ausführliche Informationen über das Application Lifecycle Management (ALM) für benutzerdefinierte Berichte, die auf Anpassungen des Datenmodells von Omnichannel für Dynamics 365 Customer Service basieren.
Übersicht über ALM
ALM ist ein wichtiger Schritt, wenn Sie die Änderungen verschieben wollen, die für benutzerdefinierte Berichte über Umgebungen hinweg notwendig wird, der manuelle Aufwand aber minimal sein soll. Ein angemessen konfiguriertes ALM hilft Ihnen, manuelle Fehler zu reduzieren und Zeit zu sparen.
Ziehen Sie für die Berichtsanpassung das ALM für die Bereitstellung von Power BI-Berichten in Betracht. Sie können diese Bereitstellung auf unterschiedliche Weise erreichen:
- Sie können Power BI-Berichte über Umgebungen hinweg verschieben, indem Sie Power BI-Bereitstellungspipelines verwenden. Alternativ können Sie Power BI-Berichte manuell bereitstellen, indem Sie auf die richtigen Datenquellen verweisen.
- Da es sich beim Customer Service-Admin Center um eine modellgesteuerte App handelt, können Sie benutzerdefinierte Berichte darin einbetten.
Zu ALM für Dynamics 365 gehört die Konfiguration von Berichten im Customer Service-Admin Center.
Im folgenden Diagramm werden die Schritte illustriert. Blaue Felder mit weißem Text stellen Aufgaben dar, die Sie in Dynamics 365 ausführen. Gelbe Felder mit schwarzem Text stellen Aufgaben dar, die Sie in Power BI ausführen.
Die Berichtskonfiguration migrieren
Berichte, die in Dynamics 365 hinzugefügt wurden, werden in Dataverse-Entitäten gespeichert.
Die folgenden Entitäten/Tabellen werden zum Speichern der benutzerdefinierten Berichtsinformationen verwendet:
msdyn_dataanalyticsworkspaces
enthält die Arbeitsbereichsinformationen, die während der Ersteinrichtung für Verlaufs-/Echtzeitanalysen konfiguriert wurden.msdyn_dataanalyticsreport
speichert die benutzerdefinierten Bericht, die in der Siteübersicht hinzugefügt wurden.msdyn_reportid
: Die Berichts-ID im Power BI-Arbeitsbereich.msdyn_dataanalyticsreportid
: Der Primärschlüssel in Dynamics 365.msdyn_displayname
: Der Anzeigename, der auf dem benutzerdefinierten Bericht in der modellgesteuerten Customer Service workspace-App erscheint.msdyn_name
: Der Name des Berichts im Power BI-Arbeitsbereich.msdyn_workspaceid
: Die Arbeitsbereichs-ID des im vorherigen Schritt konfigurierten Power BI-Arbeitsbereichs.msdyn_datainsightsandanalyticsfeatureid
: f2266eb4-226f-4cf1-b422-89c5f48b40cb ist die Feature-ID für die Anpassung des historischen Datenmodells und 09c168be-efe2-4f08-a986-3aab7095c863 ist die Feature-ID für die Anpassung des Echtzeit-Datenmodells.
Um die der Siteübersicht hinzugefügten Berichte zu migrieren, müssen Sie die Daten aus den Entitäten/Tabellen verschieben. Zu diesem Zweck können Sie das Konfigurationsmigrationstool verwenden. Dieser Artikel enthält eine Beispielschemadatei. Weitere Informationen finden Sie unter Verschieben von Konfigurationsdaten über Umgebungen und Organisationen hinweg mit dem Konfigurationsmigrationstool.
Nach der Migration müssen Sie die Berichtsreferenzen aktualisieren. Mit anderen Worten: Sie müssen den Power BI-Arbeitsbereich, in dem der Bericht gehostet wird, und die Berichts-ID aus dem Arbeitsbereich aktualisieren. Dieser Artikel stellt als Referenz ein Beispiel-PowerShell-Skript bereit. Sie können dasselbe jedoch mit jeder beliebigen Sprache erreichen.
Beispielskripts
Dieser Abschnitt enthält die folgenden Beispielskripten:
Beispielschemadatei
Die folgende XML-Schemadatei besteht aus benutzerdefinierten Berichten, die im Power BI-Arbeitsbereich erstellt und bereitgestellt werden. Sie können sie verwenden, um Daten aus dem Konfigurationsmigrationstool exportieren. Weitere Informationen finden Sie unter Verschieben von Konfigurationsdaten über Umgebungen und Organisationen hinweg mit dem Konfigurationsmigrationstool und Festlegen eines Schemas zum Exportieren von Konfigurationsdaten.
<entities>
<entity name="msdyn_dataanalyticsreport" displayname="Data Analytics Report" etc="10427" primaryidfield="msdyn_dataanalyticsreportid" primarynamefield="msdyn_name" disableplugins="false">
<fields>
<field displayname="Report Id" name="msdyn_reportid" type="string" customfield="true" />
<field displayname="Data Analytics Report" name="msdyn_dataanalyticsreportid" type="guid" primaryKey="true" />
<field displayname="Display name" name="msdyn_displayname" type="string" customfield="true" />
<field displayname="Name" name="msdyn_name" type="string" customfield="true" />
<field displayname="Report Display Order" name="msdyn_displayorder" type="number" customfield="true" />
<field displayname="Report Provision Status" name="msdyn_provisionstatus" type="bool" customfield="true" />
<field displayname="Report Page" name="msdyn_reportpage" type="string" customfield="true" />
<field displayname="Report Group" name="msdyn_reportgroup" type="string" customfield="true" />
<field displayname="Report Entity Name" name="msdyn_reportentityname" type="string" customfield="true" />
<field displayname="Report Template Id" name="msdyn_reporttemplateid" type="string" customfield="true" />
<field displayname="Dataset Id" name="msdyn_datasetid" type="string" customfield="true" />
<field displayname="Is Enabled" name="msdyn_isenabled" type="bool" customfield="true" />
<field displayname="Workspace Id" name="msdyn_workspaceid" type="string" customfield="true" />
<field displayname="datainsightsandanalyticsfeatureId" name="msdyn_datainsightsandanalyticsfeatureid" type="entityreference" lookupType="msdyn_datainsightsandanalyticsfeature" customfield="true" />
<field displayname="Analytics Checksum" name="msdyn_analyticschecksum" type="number" customfield="true" />
</fields>
<filter><filter type = 'and'>
<condition attribute = 'msdyn_datainsightsandanalyticsfeatureid' operator = 'eq' value = '<<Feature ID of the model customization>> '/>
<condition attribute = 'msdyn_displayname' operator = 'eq' value = '<<custom report name>>'/>
</filter></filter>
</entity>
</entities>
Verwenden Sie f2266eb4-226f-4cf1-b422-89c5f48b40cb als Feature-ID für historische Daten und xxxx als Feature-ID für Echtzeitdaten.
Beispiel-PowerShell-Skript
Das folgende Skript verwendet den geheimen Authentifizierungsmechanismus der Client-ID. Sie können jedoch jede Art der Authentifizierung verwenden, indem Sie das Skript ändern.
Dieses Skript stellt eine Verbindung zu Power BI über die Power BI-Rest-APIs her. Es stellt eine Verbindung zu Dataverse über die Dataverse-Web-APIs her.
#Get Power BI access token
function Get-PBIAccessToken {
[CmdletBinding()]
param(
[Parameter(Mandatory=$true)]
$TenantId,
[Parameter(Mandatory=$true)]
$PBIAppId,
[Parameter(Mandatory=$true)]
$PBIClientSecret
)
$authority = "https://login.microsoftonline.com/$TenantId/oauth2/token"
$resource = "https://analysis.windows.net/powerbi/api"
$body = @{
"grant_type" = "client_credentials"
"client_id" = $PBIAppId
"client_secret" = $PBIClientSecret
"resource" = $resource
}
Write-Host "Retreiving PBI Access Token"
$tokenResponse = Invoke-RestMethod -Method Post -Uri $authority -Body $body
return $tokenResponse.access_token
}
#Get Dataverse access token
function Get-DVAccessToken{
[CmdletBinding()]
param(
[Parameter(Mandatory=$true)]
$tenantId,
[Parameter(Mandatory=$true)]
$clientId,
[Parameter(Mandatory=$true)]
$clientSecret,
[Parameter(Mandatory=$true)]
$dataVerseURL
)
$oAuthTokenEndpoint = "https://login.microsoftonline.com/$tenantId/oauth2/v2.0/token"
# OAuth Body Access Token Request
$authBody = @{
client_id = $clientId;
client_secret = $ClientSecret;
scope = "$($dataVerseURL)/.default"
grant_type = 'client_credentials'
}
# Parameters for OAuth Access Token Request
$authParams = @{
URI = $oAuthTokenEndpoint
Method = 'POST'
ContentType = 'application/x-www-form-urlencoded'
Body = $authBody
}
Write-Host "Retreiving CRM Access Token"
# Get Access Token
$authResponseObject = Invoke-RestMethod @authParams -ErrorAction Stop
return $authResponseObject
}
function Get-DVWorkspaceId {
[CmdletBinding()]
param(
[Parameter(Mandatory=$true)]
$dvAuthResponseObject,
[Parameter(Mandatory=$true)]
$dataVerseURL
)
$getDataRequestUri = 'msdyn_dataanalyticsworkspaces?$top=5&$select=msdyn_workspaceid,msdyn_name&$filter=(msdyn_name ne ''Customer Service Managed Workspace'' and _msdyn_datainsightsandanalyticsfeatureid_value eq ''f2266eb4-226f-4cf1-b422-89c5f48b40cb'')'
# Set up web API call parameters, including a header for the access token
$getApiCallParams = @{
URI = "$($dataVerseURL)/api/data/v9.1/$($getDataRequestUri)"
Headers = @{
"Authorization" = "$($dvAuthResponseObject.token_type) $($dvAuthResponseObject.access_token)"
"Accept" = "application/json"
"OData-MaxVersion" = "4.0"
"OData-Version" = "4.0"
}
Method = 'GET'
}
Write-Host "Retreiving Dataverse DCCP Workspace Id"
# Call API to Get Response
$getApiResponseObject = Invoke-RestMethod @getApiCallParams -ErrorAction Stop
return $getApiResponseObject.value[0].msdyn_workspaceid
}
function Get-DVDCCPReports {
[CmdletBinding()]
param(
[Parameter(Mandatory=$true)]
$dvAuthResponseObject,
[Parameter(Mandatory=$true)]
$workspaceId,
[Parameter(Mandatory=$true)]
$dataVerseURL
)
Write-Host "Retreiving DV DCCP Reports"
$getDataRequestUri = 'msdyn_dataanalyticsreports?$select=msdyn_dataanalyticsreportid,msdyn_name,msdyn_workspaceid&$filter=(msdyn_workspaceid ne '''+$workspaceId+''' and _msdyn_datainsightsandanalyticsfeatureid_value eq ''f2266eb4-226f-4cf1-b422-89c5f48b40cb'')'
# Set up web API call parameters, including a header for the access token
$getApiCallParams = @{
URI = "$($dataVerseURL)/api/data/v9.1/$($getDataRequestUri)"
Headers = @{
"Authorization" = "$($dvAuthResponseObject.token_type) $($dvAuthResponseObject.access_token)"
"Accept" = "application/json"
"OData-MaxVersion" = "4.0"
"OData-Version" = "4.0"
}
Method = 'GET'
}
$getApiResponseObject = Invoke-RestMethod @getApiCallParams -ErrorAction Stop
# Output
$dvReports = $getApiResponseObject.value
return $dvReports
}
function Get-PBIReports {
[CmdletBinding()]
param(
[Parameter(Mandatory=$true)]
$accessToken,
[Parameter(Mandatory=$true)]
$workspaceId
)
Write-Host "Retreiving PBI Workspace Reports"
$headers = @{
"Authorization" = "Bearer $accessToken"
'Content-Type' = 'application/json'
}
$uri = "https://api.powerbi.com/v1.0/myorg/groups/$workspaceId/reports"
$response = Invoke-RestMethod -Uri $uri -Headers $headers -Method Get
$pbiReports = $response.value
return $pbiReports
}
function Update-DVReportReferences
{
[CmdletBinding()]
param(
[Parameter(Mandatory=$true)]
$pbiAccessToken,
[Parameter(Mandatory=$true)]
$dvAuthResponseObject,
[Parameter(Mandatory=$true)]
$workspaceId,
[Parameter(Mandatory=$true)]
$dataVerseURL
)
$pbiReports = Get-PBIReports -accessToken $pbiAccessToken -workspaceId $workspaceId
Write-Host $pbiReports.Count
$dvReports = Get-DVDCCPReports -dvAuthResponseObject $dvAuthResponseObject -workspaceId $workspaceId -dataVerseURL $dataVerseURL
Write-Host $dvReports.Count
Write-Host "Updating DCCP report references"
$pbiReports
foreach ($item in $dvReports)
{
$item.msdyn_name
$report = $pbiReports.value | Where-Object {$_.name -eq $item.msdyn_name}
if($report -ne $null)
{
Write-Host "Updating report reference for $($item.msdyn_name) with PBI $($report.id)"
$dvReportId = $item.msdyn_dataanalyticsreportid
$patchRequestUri = "msdyn_dataanalyticsreports($($dvReportId))"+'?$select=msdyn_workspaceid,msdyn_dataanalyticsreportid'
$updateBody = @{
'msdyn_workspaceid' = ''+$workspaceId+''
'msdyn_reportid' = ''+$report.id+''
} | ConvertTo-Json
# Set up web API call parameters, including a header for the access token
$patchApiCallParams = @{
URI = "$($dataVerseURL)/api/data/v9.1/$($patchRequestUri)"
Headers = @{
"Authorization" = "$($dvAuthResponseObject.token_type) $($dvAuthResponseObject.access_token)"
"Accept" = "application/json"
"OData-MaxVersion" = "4.0"
"OData-Version" = "4.0"
"Content-Type" = "application/json; charset=utf-8"
"Prefer" = "return=representation" # in order to return data
"If-Match" = "*"
}
Method = 'PATCH'
Body = $updateBody
}
$patchApiResponseObject = Invoke-RestMethod @patchApiCallParams -ErrorAction Stop
}
else
{
Write-Host "Corresponding PBI report not found in PBI workspace with name $($item.msdyn_name)"
}
}
return $pbiReports
}
###Sample usage########
#$PBIAppId = '<<Client ID which has access to Power BI workspace>>'
#$TenantId = '<<Tenant Id of the DV/PBI organization>>'
#$PBIClientSecret = "<<Secret of application user PBI>>"
#$AppId = '<<Dataverse App id>>'
#$ClientSecret = '<<DV client Secret>>'
#$PowerPlatformEnvironmentUrl = "<<DV URL>>"
#$PBIAccessToken = Get-PBIAccessToken -TenantId $TenantId -PBIAppId $PBIAppId -PBIClientSecret $PBIClientSecret
#$CRMAccessToken = Get-DVAccessToken -tenantId $TenantId -dataVerseURL $PowerPlatformEnvironmentUrl -clientId $AppId -clientSecret $ClientSecret
#$workspaceId = Get-DVWorkspaceId -dvAuthResponseObject $CRMAccessToken -dataVerseURL $PowerPlatformEnvironmentUrl
#Update-DVReportReferences -pbiAccessToken $PBIAccessToken -dvAuthResponseObject $CRMAccessToken -workspaceId $workspaceId -dataVerseURL $PowerPlatformEnvironmentUrl
Beispiel-Azure DevOps-YAML-Pipeline
# Starter pipeline
# Start with a minimal pipeline that you can customize to build and deploy your code.
# Add steps that build, run tests, deploy, and more:
# https://aka.ms/yaml
trigger:
- main
pool:
vmImage: windows-latest
steps:
- task: CopyFiles@2
inputs:
Contents: '**'
TargetFolder: '$(Build.ArtifactStagingDirectory)'
CleanTargetFolder: true
ignoreMakeDirErrors: true
displayName: 'Copy files from Repo'
- task: PowerPlatformToolInstaller@2
inputs:
DefaultVersion: true
- task: PowerPlatformExportData@2
inputs:
authenticationType: 'PowerPlatformSPN'
PowerPlatformSPN: 'Optimize25CRM'
Environment: '$(BuildTools.EnvironmentUrl)'
SchemaFile: '$(Build.ArtifactStagingDirectory)\source\Optimize25Schema\schema_sample.xml'
DataFile: 'data.zip'
displayName: 'Export reports sitemap data from Source'
- task: PowerPlatformImportData@2
inputs:
authenticationType: 'PowerPlatformSPN'
PowerPlatformSPN: 'Optimize25POC'
Environment: '$(BuildTools.EnvironmentUrl)'
DataFile: 'data.zip'
displayName: 'Import reports sitemap data to Target'
- task: PowerShell@2
inputs:
targetType: 'inline'
script: |
$ScriptContent = Get-Content "$(Build.ArtifactStagingDirectory)\source\automation\PipelineScript.ps1" -Raw
Invoke-Expression $ScriptContent
# Write your PowerShell commands here.
Write-Host "Assigning connection variables"
$PBIAppId = '$(PBIClientId)'
$PBIClientSecret = '$(PBIClientSecret)'
$TenantId = '$(TenantId)'
$AppId = '$(CRMClientId)'
$ClientSecret = '$(CRMClientSecret)'
$PowerPlatformEnvironmentUrl = '$(GetConnectionVar.PowerPlatformEnvironmentUrl)'
$PBIAccessToken = Get-PBIAccessToken -TenantId $TenantId -PBIAppId $PBIAppId -PBIClientSecret $PBIClientSecret
$CRMAccessToken = Get-DVAccessToken -tenantId $TenantId -dataVerseURL $PowerPlatformEnvironmentUrl -clientId $AppId -clientSecret $ClientSecret
$featureId = 'f2266eb4-226f-4cf1-b422-89c5f48b40cb'
$workspaceId = Get-DVWorkspaceId -dvAuthResponseObject $CRMAccessToken -dataVerseURL $PowerPlatformEnvironmentUrl -featureId $featureId
Write-Host $workspaceId
Update-DVReportReferences -pbiAccessToken $PBIAccessToken -dvAuthResponseObject $CRMAccessToken -workspaceId $workspaceId -dataVerseURL $PowerPlatformEnvironmentUrl -featureId $featureId
Zugehörige Ressourcen
Die folgenden Ressourcen können Ihnen dabei helfen, mehr über die integrierten Analysefunktionen von Omnichannel für Dynamics 365 Customer Service zu erfahren.
- Überblick über das Echtzeit-Analysedashboard
- Verlaufsanalysen für einheitliches Routing in Omnichannel for Customer Service
- Modellanpassung von Verlaufs- und Echtzeit-Analyseberichten in Customer Service
- Microsoft Power Platform Build Tools für Azure DevOps
- Verschieben von Konfigurationsdaten über Organisationen hinweg
- Microsoft Power Platform CLI-Datenbefehlsgruppe
- Übersicht über Power BI-Bereitstelungspipelines
- Power BI-REST-APIs für eingebettete Analysen und Automatisierung