Mitarbeitende müssen ihre Katalogelemente zur Genehmigung einreichen und eine Fachkraft für die Administration muss sie genehmigen, bevor sie von anderen verwendet werden können.
Zum Übermitteln eines Elements an den Katalog benötigen Sie Folgendes:
Ein Lösungsbereitstellungs- oder Package Deployer-Paket, welches das Element enthält, das Sie übermitteln möchten.
Ein Metadaten-JSON-Dokument für die Übermittlung.
Verwenden Sie den Befehl pac catalog create-submission, um ein Beispiel für ein JSON-Dokument mit Metadaten für die Übermittlung abzurufen. Sie müssen dieses Dokument bearbeiten und weitere Übermittlungsattribute können hinzugefügt werden. Weitere Informationen Übermittlungsattribute
Übermittlungsattribute
Bevor Sie Elemente an einen Katalog übermitteln können, müssen Sie ein JSON-Dokument vorbereiten, das die Elemente beschreibt, die Sie übermitteln möchten.
Elemente, die an den Katalog übermittelt werden, müssen in einem Package Deployer-Paket enthalten sein. Ein Package Deployer-Paket enthält eine ZIP-Lösungsdatei und einige optionale Anweisungen, die beim Bereitstellen des Pakets angewendet werden müssen. Wenn Sie nicht über ein Package Deployer-Paket verfügen, können Sie eines für die Lösung erstellen, die Ihre Elemente enthält.
pac catalog submit -p "BuildDemoSubmission.json" -sz "ContosoConference_1_0_0_1_managed.zip"
Creating package for catalog submit request...
Connected to... TestCatalog
Connected as user@domain
Tracking id for this submission is 0e6b119d-80f3-ed11-8849-000d3a0a2d9d
Die statische SubmitCatalogApprovalRequest-Methode zeigt die Verwendung der mspcat_SubmitCatalogApprovalRequest-Meldung. In diesem Beispiel werden die mspcat_SubmitCatalogApprovalRequestRequest- und mspcat_SubmitCatalogApprovalRequestResponse-Klassen verwendet, die mit dem Befehl pac modelbuilder build generiert wurden.
Diese Beispielmethode gibt eine Instanz der mspcat_SubmitCatalogApprovalRequestResponse-Klasse zurück, die CertificationRequestId- und AsyncOperationId-Eigenschaften enthält, mit denen Sie den Status der Übermittlung überprüfen können.
Die mspcat_SubmitCatalogApprovalRequest-Meldung erfordert, dass die CatalogItemDefinitionpackageFile-Eigenschaft der JSON-Übermittlungsdatei so festgelegt ist, dass eine URL zum Herunterladen einer Datei des Package Deployer-Pakets angegeben wird.
/// <summary>
/// Submits a Catalog item for approval
/// </summary>
/// <param name="service">The authenticated IOrganizationService instance.</param>
/// <param name="pathToSubmissionFile">The location of the submission file</param>
/// <returns>
/// mspcat_SubmitCatalogApprovalRequestResponse contains AsyncOperationId
/// and CertificationRequestId
/// </returns>
static mspcat_SubmitCatalogApprovalRequestResponse SubmitCatalogApprovalRequest(
IOrganizationService service,
FileInfo pathToSubmissionFile)
{
byte[] fileBytes = File.ReadAllBytes(pathToSubmissionFile.FullName);
string encodedSubmissionFile = Convert.ToBase64String(fileBytes);
var request = new mspcat_SubmitCatalogApprovalRequestRequest
{
EncodedApprovalRequest = encodedSubmissionFile
};
return (mspcat_SubmitCatalogApprovalRequestResponse)service.Execute(request);
}
Die folgende SubmitCatalogApprovalRequest-PowerShell-Funktion zeigt, die Sie die mspcat_SubmitCatalogApprovalRequest-Meldung verwenden.
Als Ergebnis wird eine Instanz des komplexen mspcat_SubmitCatalogApprovalRequestResponse-Typs zurückgegeben, die CertificationRequestId- und AsyncOperationId-Eigenschaften enthält, mit denen Sie den Status der Übermittlung überprüfen können.
Die mspcat_SubmitCatalogApprovalRequest-Meldung erfordert, dass die CatalogItemDefinitionpackageFile-Eigenschaft der JSON-Übermittlungsdatei so festgelegt ist, dass eine URL zum Herunterladen einer Datei des Package Deployer-Pakets angegeben wird.
Diese Funktion hängt von den $baseURI- und $baseHeaders-Werten ab, die mit der Connect-Funktion festgelegt wurden, wie in Eine Connect-Funktion erstellen beschrieben.
Paketbereitstellungspaket aus einer nicht verwalteten Lösung erstellen
Wenn Sie die mspcat_SubmitCatalogApprovalRequest-Meldung mit dem SDK für .NET oder der Web-API verwenden, wie unter Elemente an den Katalog übermitteln beschrieben, muss die JSON-Datei für die Übermittlung eine CatalogItemDefinitionpackageFile-Eigenschaft enthalten, die so festgelegt ist, dass eine URL in der filesaslink zum Herunterladen einer Datei des Package Deployer-Pakets angegeben wird. Sie müssen dazu nicht den Befehl pac catalog submit nicht ausführen, da sie dies für Sie erledigt.
Diese URL kann für einen beliebigen Ort stehen, von dem Dataverse eine Datei ohne Anmeldeinformationen herunterladen kann. Sie sollten die Dateien jedoch nicht an einem öffentlichen Downloadspeicherort ablegen. Stattdessen können Sie die Tabelle des Paketübermittlungsspeichers (mspcat_PackageStore) verwenden, um ein Package Deployer-Paket mit einer nicht verwalteten Lösung aus einer beliebigen Umgebung in Ihrem Mandanten zu generieren. Dieser Prozess generiert einen Datensatz in dieser Tabelle, der ein Paket in der PackageFile-Dateispalte (mspcat_PackageFile) enthält. Sie können die GetFileSasUrl Nachricht dann verwenden, um eine SAS-URL (Shared Access Signature) abzurufen, damit die Datei innerhalb von 1 Stunde anonym heruntergeladen werden kann. Da die URL nur innerhalb einer Stunde gültig ist, sollte dieser Vorgang automatisiert werden, damit der Zugriff zum Herunterladen der Datei nicht abläuft.
Die statische CatalogItemFromSolution Methode zeigt, wie Sie ein Katalogelement aus einer Lösung erstellen, indem Sie die unter Prozess beschriebenen Schritte ausführen. Für den catalogItemSubmissionJsonString Parameter dieser Funktion sollte keine packageFile Eigenschaft festgelegt sein, da er von dieser Funktion hinzugefügt wird.
/// <summary>
/// Processes a solution and returns the catalog item ID
/// </summary>
/// <param name="service">The authenticated IOrganizationService instance</param>
/// <param name="solutionName">The name of the solution</param>
/// <param name="solutionUniqueName">The unique name of the solution</param>
/// <param name="catalogItemSubmissionJsonString">The string containing the submission json file</param>
/// <returns>Catalog Item ID</returns>
/// <exception cref="Exception"></exception>
static string CatalogItemFromSolution(
IOrganizationService service,
string solutionName,
string solutionUniqueName,
string catalogItemSubmissionJsonString
)
{
Entity packageStoreRecord = new("mspcat_packagestore")
{
Attributes = {
{"mspcat_name", solutionName},
{"mspcat_solutionuniquename", solutionUniqueName},
{"mspcat_intendeddeploymenttype", new OptionSetValue(526430000)}, // Standard
{"mspcat_operation", new OptionSetValue(958090001)} //Create Package
}
};
Guid packageStoreRecordId = service.Create(packageStoreRecord);
Console.WriteLine($"Created package store record with ID {packageStoreRecordId}");
packageStoreRecord.Attributes.Clear(); //Don't send values again
packageStoreRecord.Id = packageStoreRecordId;
int statusCodeValue = 958090004; // Submitted
string statusReason; // Set in the loop
packageStoreRecord["statuscode"] = new OptionSetValue(statusCodeValue);
service.Update(packageStoreRecord); //Set status to Submitted
Console.WriteLine("Updated package store record status to Submitted");
// Columns to retrieve while polling the package store record
ColumnSet packageStoreColumns = new("statuscode");
do
{
Task.Delay(10000).Wait(); //Wait 10 seconds between polling
// Retrieve the record
packageStoreRecord = service.Retrieve(
"mspcat_packagestore",
packageStoreRecord.Id,
packageStoreColumns);
// Get the status code value
statusCodeValue = packageStoreRecord
.GetAttributeValue<OptionSetValue>("statuscode").Value;
statusReason = packageStoreRecord
.FormattedValues["statuscode"];
Console.WriteLine($" - Package store record status is {statusReason}");
// Continue while statusCodeValue is Submitted, Pending, or Running
} while (statusCodeValue.Equals(958090004) ||
statusCodeValue.Equals(1) ||
statusCodeValue.Equals(958090000));
// If it isn't Completed, throw an exception
if (!statusCodeValue.Equals(958090001))
{
statusReason = packageStoreRecord
.FormattedValues["statuscode"];
// 958090002 is 'Failed'
throw new Exception($"Package submission {statusReason}");
}
Console.WriteLine($"Package submission {statusReason}");
// If successful, retrieve the details about the file to download
GetFileSasUrlRequest getFileSasUrlRequest = new()
{
Target = new EntityReference("mspcat_packagestore", packageStoreRecord.Id),
FileAttributeName = "mspcat_packagefile"
};
var getFileSasUrlResponse = (GetFileSasUrlResponse)service
.Execute(getFileSasUrlRequest);
FileSasUrlResponse getFileSasUrlResponseResult = getFileSasUrlResponse.Result;
Console.WriteLine($"Retrieved SAS URL for {getFileSasUrlResponseResult.FileName}");
// Add the packageFile to the catalog item submission
var catalogItemSubmissionJsonObject = JsonNode.Parse(catalogItemSubmissionJsonString).AsObject();
var packageFile = new JsonObject
{
["name"] = getFileSasUrlResponseResult.FileName,
["filesaslink"] = getFileSasUrlResponseResult.SasUrl
};
// Add the packageFile to the catalog item submission
catalogItemSubmissionJsonObject["catalogItemDefinition"]["packageFile"] = packageFile;
catalogItemSubmissionJsonString = catalogItemSubmissionJsonObject.ToJsonString();
string encodedSubmissionJson = Convert
.ToBase64String(Encoding.UTF8.GetBytes(catalogItemSubmissionJsonString));
var submitCatalogApprovalRequest = new mspcat_SubmitCatalogApprovalRequestRequest
{
EncodedApprovalRequest = encodedSubmissionJson
};
var submitCatalogApprovalResponse = (mspcat_SubmitCatalogApprovalRequestResponse)service
.Execute(submitCatalogApprovalRequest);
Guid certificationRequestId = submitCatalogApprovalResponse.CertificationRequestId;
Console.WriteLine($"Submitted catalog approval request with ID {certificationRequestId}");
// Approval must be in either InProgress or Submitted to be processed
// Columns to retrieve while polling the certification request record
ColumnSet certificationRequestColumns = new("statuscode", "mspcat_application");
Entity certificationRequestRecord;
do
{
Task.Delay(10000).Wait(); //Wait 10 seconds between polling
// Retrieve the record
certificationRequestRecord = service.Retrieve(
"mspcat_certificationrequest",
certificationRequestId,
certificationRequestColumns);
// Get the status code value
statusCodeValue = certificationRequestRecord
.GetAttributeValue<OptionSetValue>("statuscode").Value;
statusReason = packageStoreRecord
.FormattedValues["statuscode"];
Console.WriteLine($" - Approval Request status is {statusReason}");
// Continue while statusCodeValue is:
} while (statusCodeValue.Equals(526430002) || // Waiting On Submitter,
statusCodeValue.Equals(526430003) || // Pending Deployment,
statusCodeValue.Equals(526430008) || // Draft
statusCodeValue.Equals(526430009)); // Processing
// If it isn't Submitted or InProgress, throw an exception
if (!(statusCodeValue.Equals(1) || statusCodeValue.Equals(526430001)))
{
string statusreason = certificationRequestRecord
.FormattedValues["statuscode"];
throw new Exception($"Certification request {statusreason}");
}
// Approve the request
mspcat_ResolveApprovalRequest resolveApprovalRequest = new()
{
Target = new EntityReference("mspcat_certificationrequest", certificationRequestId),
requestsuccess = true, //Approve the request
message = "Approved by CatalogItemFromSolution function"
};
// mspcat_ResolveApprovalResponse has no properties to return
service.Execute(resolveApprovalRequest);
Console.WriteLine("Approved the certification request");
// Get the Catalog Item
EntityReference catalogItemReference = certificationRequestRecord
.GetAttributeValue<EntityReference>("mspcat_application");
Entity catalogItem = service.Retrieve(
"mspcat_applications",
catalogItemReference.Id,
new ColumnSet("mspcat_tpsid"));
string tpsid = catalogItem.GetAttributeValue<string>("mspcat_tpsid");
Console.WriteLine($"Returning Catalog Item ID: {tpsid}");
return tpsid;
}
Output
Die Ausgabe dieser Funktion sollte in etwa so aussehen:
Created package store record with ID 46f662aa-2137-ef11-8409-6045bdd3aec3
Updated package store record status to Submitted
- Package store record status is Submitted
- Package store record status is Pending
- Package store record status is Running
- Package store record status is Running
- Package store record status is Completed
Package submission Completed
Retrieved SAS URL for <solutionName>_1_0_0_0.zip
Submitted catalog approval request with ID b932c7c8-2137-ef11-8409-6045bdd3aec3
- Approval Request status is Completed
Approved the certification request
Returning Catalog Item ID: <solutionUniqueName>
Diese New-CatalogItemFromSolution PowerShell-Funktion zeigt, wie Sie ein Katalogelement aus einer Lösung erstellen, indem Sie die unter Prozess beschriebenen Schritte ausführen. Für den catalogItemSubmissionJsonString Parameter dieser Funktion sollte keine packageFile Eigenschaft festgelegt sein, da er von dieser Funktion hinzugefügt wird.
Diese New-CatalogItemFromSolution PowerShell-Funktion hängt von den folgenden Variablen und Funktionen ab:
Den $baseURI- und $baseHeaders-Werte, die mithilfe der Connect-Funktion wie in Eine Connect-Funktion erstellen beschrieben festgelegt wurden
.SYNOPSIS
Creates a new catalog item from a solution and submits it for approval.
.DESCRIPTION
The `New-CatalogItemFromSolution` function automates the process of creating a new catalog item from a specified solution and submitting it for approval. It performs the following steps:
1. Validates the existence of the solution.
2. Creates a package store record.
3. Submits the package for approval.
4. Monitors the approval status.
5. Retrieves the SAS URL for the package file.
6. Submits the catalog item for certification.
.PARAMETER solutionName
The name of the solution.
.PARAMETER solutionUniqueName
The unique name of the solution.
.PARAMETER catalogItemSubmissionJsonString
The JSON string containing the catalog item submission details.
.EXAMPLE
New-CatalogItemFromSolution `
-solutionName "MySolution" `
-solutionUniqueName "my_solution" `
-catalogItemSubmissionJsonString '{"catalogItemDefinition":{...}}'
This example creates a new catalog item from the solution named "MySolution" with the unique name "my_solution" and submits it for approval using the provided JSON string.
.NOTES
Ensure that the `Get-Records`, `New-Record`, `Update-Record`, `Get-Record`, and `Get-FileSasUrl` functions are defined and accessible in your environment.
The function uses specific status codes and operations that should be defined in your system.
function New-CatalogItemFromSolution {
param(
[Parameter(Mandatory)]
[string]
$solutionName,
[Parameter(Mandatory)]
[string]
$solutionUniqueName,
[Parameter(Mandatory)]
[string]
$catalogItemSubmissionJsonString
)
$statusCodeLabelName = 'statuscode@OData.Community.Display.V1.FormattedValue'
$solutionQuery = "?`$filter=uniquename eq '$solutionUniqueName'&`$select=solutionid"
$solutionCollection = (Get-Records `
-setName 'solutions' `
-query $solutionQuery).value
if (!$solutionCollection.Count -eq 1) {
throw "Solution with unique name $solutionUniqueName does not exist"
}
$packageStoreRecord = @{
mspcat_name = $solutionName
mspcat_solutionuniquename = $solutionUniqueName
mspcat_intendeddeploymenttype = 526430000 # Standard
mspcat_operation = 958090001 # Create Package
}
$packageId = New-Record `
-setName 'mspcat_packagestores' `
-body $packageStoreRecord
Write-Host ('Created package store record with ID ' + $packageId)
# Set statuscode to Submitted
$packageStoreRecord = @{
statuscode = 958090004
}
Update-Record `
-setName 'mspcat_packagestores' `
-id $packageId `
-body $packageStoreRecord | Out-Null
Write-Host 'Updated package store record status to Submitted'
do {
Start-Sleep -Seconds 10
$packageStore = Get-Record `
-setName 'mspcat_packagestores' `
-id $packageId `
-query '?$select=statuscode,mspcat_processingmessage'
$statusCodeValue = $packageStore.statuscode
$statusCodeLabel = $packageStore.$statusCodeLabelName
Write-Host (' - Package store record status is ' + $statusCodeLabel)
} while ($statusCodeValue -eq 958090004 -or # Submitted
$statusCodeValue -eq 1 -or # Pending
$statusCodeValue -eq 958090000) # Running
if ($statusCodeValue -ne 958090001) {
# 958090002 is 'Failed'
throw "Package submission $statusCodeLabel"
}
# If successful, retrieve the details about the file to download
$fileSasUrlResponse = Get-FileSasUrl `
-setName 'mspcat_packagestores' `
-id $packageId `
-columnName 'mspcat_packagefile'
Write-Host ('Retrieved SAS URL for ' + $fileSasUrlResponse.FileName)
$catalogItemSubmission = $catalogItemSubmissionJsonString | ConvertFrom-Json
$packageFile = @{
name = $fileSasUrlResponse.FileName
filesaslink = $fileSasUrlResponse.SasUrl
}
$catalogItemSubmission.catalogItemDefinition.packageFile = $packageFile
$catalogItemSubmissionJsonString = $catalogItemSubmission | ConvertTo-Json -Depth 10
$encodedCatalogItemSubmission = [System.Convert]::ToBase64String([System.Text.Encoding]::UTF8.GetBytes($catalogItemSubmissionJsonString))
$body = @{
EncodedApprovalRequest = $encodedCatalogItemSubmission
} | ConvertTo-Json
$postHeaders = $baseHeaders.Clone()
$postHeaders.Add('Content-Type', 'application/json')
$results = Invoke-RestMethod `
-Method Post `
-Uri ($baseURI + 'mspcat_SubmitCatalogApprovalRequest') `
-Headers $postHeaders `
-Body $body
$certificationRequestId = $results.CertificationRequestId
Write-Host ('Submitted catalog approval request with ID ' + $certificationRequestId)
# Approval must be in either InProgress or Submitted to be processed
do {
Start-Sleep -Seconds 10
# Retrieve the record
$approvalRequestRecord = Get-Record `
-setName 'mspcat_certificationrequests' `
-id $certificationRequestId `
-query '?$select=statuscode'
# Get the status code value
$statusCodeValue = $approvalRequestRecord.statuscode
$statusCodeLabel = $approvalRequestRecord.$statusCodeLabelName
Write-Host (' - Approval request status is ' + $statusCodeLabel)
} while ($statusCodeValue -eq 526430002 -or # Waiting On Submitter
$statusCodeValue -eq 526430003 -or # Pending Deployment
$statusCodeValue -eq 526430008 -or # Draft
$statusCodeValue -eq 526430009) # Processing
# If statuscode isn't Submitted or InProgress, throw an exception
if (!($statusCodeValue -eq 1 -or $statusCodeValue -eq 526430001)) {
throw "Certification request $statusCodeLabel"
}
# Approve the request
ResolveApproval `
-certificationRequestId $certificationRequestId `
-requestsuccess $true `
-message 'Approved by script'
Write-Host 'Approved the certification request'
# Get the Catalog Item
$query = '?$select=mspcat_certificationrequestid'
$query += '&$expand=mspcat_Application($select=mspcat_tpsid)'
$approvalRequestRecord = Get-Record `
-setName 'mspcat_certificationrequests' `
-id $certificationRequestId `
-query $query
$tpsid = $approvalRequestRecord.mspcat_Application.mspcat_tpsid
Write-Host ('Returning Catalog Item ID:' + $tpsid)
return $tpsid
}
Output
Die Ausgabe dieser Funktion sollte in etwa so aussehen:
Created package store record with ID 46f662aa-2137-ef11-8409-6045bdd3aec3
Updated package store record status to Submitted
- Package store record status is Submitted
- Package store record status is Pending
- Package store record status is Running
- Package store record status is Running
- Package store record status is Completed
Package submission Completed
Retrieved SAS URL for <solutionName>_1_0_0_0.zip
Submitted catalog approval request with ID b932c7c8-2137-ef11-8409-6045bdd3aec3
- Approval Request status is Completed
Approved the certification request
Returning Catalog Item ID: <solutionUniqueName>
Verwenden Sie den Befehl pac catalogue status, um den Status der Katalogübermittlungen zu überprüfen.
pac catalog status --tracking-id 0e6b119d-80f3-ed11-8849-000d3a0a2d9d --type submit
Connected to... TestCatalog
Connected as user@domain
Status of the Submit request: Submitted
Die folgende Get-ApprovalRequest PowerShell-Funktion ruft ausgewählte Spalten aus der Tabelle der Genehmigungsanforderung (mspcat_certificationrequest) für das Element ab, bei dem der $trackingId Parameter mit dem Primärschlüssel des Datensatzes übereinstimmt.
Es gibt keinen PAC-CLI-Befehl zum Ausführen dieses Vorgangs.
Diese statische ResolveApproval-Methode zeigt, wie eine Anforderung für eine Katalogübermittlung mithilfe der mspcat_ResolveApproval-Meldung aufgelöst wird. In diesem Beispiel werden die mspcat_ResolveApprovalRequest-Klasse verwendet, die von dem Befehl pac modelbuilder build generiert wurde.
/// <summary>
/// Resolves a catalog submission approval
/// </summary>
/// <param name="service">The authenticated IOrganizationService instance.</param>
/// <param name="certificationRequestId">The ID of the certification request.</param>
/// <param name="requestsuccess">The decision to approve or reject the request.</param>
/// <param name="message">Information for the submitter about the resolution</param>
static void ResolveApproval(
IOrganizationService service,
Guid certificationRequestId,
bool requestsuccess,
string message)
{
mspcat_ResolveApprovalRequest request = new()
{
Target = new EntityReference("mspcat_certificationrequest", certificationRequestId),
requestsuccess = requestsuccess,
message = message
};
// mspcat_ResolveApprovalResponse has no properties to return
service.Execute(request);
}
Diese ResolveApproval-PowerShell-Funktion zeigt, wie eine Anforderung für eine Katalogübermittlung mithilfe der mspcat_ResolveApproval-Meldung aufgelöst wird.
Diese Funktion hängt von den $baseURI- und $baseHeaders-Werten ab, die mit der Connect-Funktion festgelegt wurden, wie in Eine Connect-Funktion erstellen beschrieben
<#
.SYNOPSIS
This function resolves an approval request.
.DESCRIPTION
mspcat_ResolveApproval is an action bound to the mspcat_certificationrequests table.
.PARAMETER certificationRequestId
This is a mandatory GUID parameter that represents the ID of the certification request.
.PARAMETER requestsuccess
This is a mandatory Boolean parameter that indicates the decision to approve or reject the request..
.PARAMETER message
This is a mandatory string parameter that contains information for the submitter about the resolution.
.EXAMPLE
ResolveApproval `
-certificationRequestId "<Guid>" `
-requestsuccess $true `
-message "Request processed successfully."
.NOTES
The function does not return any value.
Any output from the Invoke-RestMethod cmdlet is sent to Out-Null.
#>
function ResolveApproval {
param (
[Parameter(Mandatory)]
[guid]
$certificationRequestId,
[Parameter(Mandatory)]
[bool]
$requestsuccess,
[Parameter(Mandatory)]
[string]
$message
)
$uri = $baseURI + "mspcat_certificationrequests($certificationRequestId)"
$uri += "/Microsoft.Dynamics.CRM.mspcat_ResolveApproval"
$body = @{
requestsuccess = $requestsuccess
message = $message
} | ConvertTo-Json
$postHeaders = $baseHeaders.Clone()
$postHeaders.Add('Content-Type', 'application/json')
Invoke-RestMethod `
-Method Post `
-Uri $uri `
-Headers $postHeaders `
-Body $body | Out-Null
}