Note
L’accès à cette page nécessite une autorisation. Vous pouvez essayer de vous connecter ou de modifier les répertoires.
L’accès à cette page nécessite une autorisation. Vous pouvez essayer de changer de répertoire.
Cet article s’étend sur l’API web de démarrage rapide avec l’article PowerShell pour décrire les fonctionnalités avancées à l’aide de PowerShell et de Visual Studio Code avec l’API Web Dataverse pour :
- Créer des fonctions réutilisables
- Gérer les exceptions
- Gérer les limites de protection des services Dataverse
- Déboguer à l’aide de Fiddler
- Télécharger le document $metadata CSDL de l’API web Dataverse
Note
Les instructions de cet article doivent fonctionner pour Windows, Linux et macOS, mais ces étapes n’ont été testées que sur Windows. Si des modifications sont nécessaires, faites-nous savoir à l’aide de la section Commentaires en bas de cet article.
Prerequisites
Le contenu de cet article présente les mêmes prérequis que l’API web de démarrage rapide avec l’article PowerShell .
Installer ou vérifier que les éléments suivants sont installés
Installez Visual Studio Code. Voir Télécharger Visual Studio Code
Installez l’extension PowerShell pour Visual Studio Code. Voir PowerShell pour Visual Studio Code
Installez PowerShell 7.4 ou version ultérieure. Voir Installer PowerShell sur Windows, Linux et macOS
Installez le module Az PowerShell version 11.1.0 ou ultérieure. Voir Procédure d’installation d’Azure PowerShell
Pour mettre à jour une installation existante vers la dernière version, utilisez
Update-Module -Name Az -Force
Vérifier l’installation
Ouvrez Visual Studio Code.
Dans le menu Terminal, sélectionnez Nouveau terminal.
Dans le volet de navigation de Visual Studio Code, sélectionnez l’icône
de l’extension PowerShell.Copiez et collez le script suivant dans la fenêtre de terminal Visual Studio Code :
Write-Host 'PowerShell Version:'$PSVersionTable.PSVersion.ToString() Write-Host 'PowerShell Az version:'(Get-InstalledModule Az).VersionAppuyez sur Entrée. La sortie doit ressembler à ce qui suit :
PowerShell Version: 7.4.0 PowerShell Az version: 11.1.0
Si vous ne voyez pas les résultats comme celui-ci, installez ou mettez à jour les prérequis.
Vous aurez également besoin de
- Un compte d’utilisateur valide pour un environnement Dataverse
- URL de l’environnement Dataverse auquel vous souhaitez vous connecter. Consultez Afficher les ressources du développeur pour découvrir comment le trouver. Il semble quelque chose comme ceci :
https://yourorg.crm.dynamics.com/, oùyourorg.crmest différent. - Compréhension de base du langage de script PowerShell
Créer des fonctions réutilisables
L’API web de démarrage rapide avec PowerShell a introduit comment authentifier et appeler la fonction WhoAmI avec Visual Studio Code. Cette approche peut être tout ce dont vous avez besoin pour un test ad hoc d’une ou plusieurs opérations. Toutefois, à mesure que vos scripts deviennent plus complexes, vous pouvez vous retrouver à taper le même code à nouveau et à nouveau.
Dans cette section, nous commençons à créer un ensemble de fonctions réutilisables dans des fichiers distincts auxquels nous pouvons accéder à l’aide du dot sourcing. Utilisez le dot-sourcing pour charger un fichier contenant des scripts PowerShell, qui peuvent inclure des fonctions et des variables faisant partie de l'étendue du script local.
Conseil / Astuce
Vous trouverez des définitions entièrement documentées de ces fonctions et bien plus encore dans notre dépôt GitHub PowerApps-Samples sur PowerApps-Samples/dataverse/webapi/PS/
Créer une fonction Connect
Nous allons placer le code pour l’authentification auprès de Dataverse dans une fonction appelée Connect à l’intérieur d’un fichier nommé Core.ps1 afin de pouvoir la réutiliser dans une seule ligne de code.
Créez un dossier. Dans cet exemple, nous créons un dossier dans
C:\scripts.Créez un fichier texte dans le dossier scripts nommé
Core.ps1.Copiez et collez la fonction suivante
Connectdans leCore.ps1fichier.function Connect { param ( [Parameter(Mandatory)] [String] $environmentUrl ) ## Login interactively if not already logged in if ($null -eq (Get-AzTenant -ErrorAction SilentlyContinue)) { Connect-AzAccount | Out-Null } # Get an access token $secureToken = (Get-AzAccessToken ` -ResourceUrl $environmentUrl ` -AsSecureString).Token # Convert the secure token to a string $token = ConvertFrom-SecureString ` -SecureString $secureToken ` -AsPlainText # Define common set of headers $global:baseHeaders = @{ 'Authorization' = 'Bearer ' + $token 'Accept' = 'application/json' 'OData-MaxVersion' = '4.0' 'OData-Version' = '4.0' } # Set baseURI $global:baseURI = $environmentUrl + 'api/data/v9.2/' }Note
Le script ajoute les variables
baseURIetbaseHeadersau contexte global à l’aide du$globalmodificateur de portée afin qu'elles soient disponibles pour d'autres scripts dans la même session.Créez un autre fichier texte dans Visual Studio Code nommé
test.ps1dans votrescriptsdossier.Copiez et collez le script suivant dans le
test.ps1fichier :. $PSScriptRoot\Core.ps1 Connect 'https://yourorg.crm.dynamics.com/' # change to your organization # Invoke WhoAmI Function Invoke-RestMethod -Uri ($baseURI + 'WhoAmI') -Method Get -Headers $baseHeaders | ConvertTo-Json. $PSScriptRoot\Core.ps1en haut du fichier utilise le dot sourcing pour indiquer au script de charger le contenu de ce fichier.N’oubliez pas de changer
https://yourorg.crm.dynamics.com/pour correspondre à l’URL de votre environnement.Pour exécuter le script, appuyez sur F5.
La sortie peut ressembler à cette sortie :
PS C:\scripts> . 'C:\scripts\test.ps1' { "@odata.context": "https://yourorg.crm.dynamics.com/api/data/v9.2/$metadata#Microsoft.Dynamics.CRM.WhoAmIResponse", "BusinessUnitId": "11bb11bb-cc22-dd33-ee44-55ff55ff55ff", "UserId": "22cc22cc-dd33-ee44-ff55-66aa66aa66aa", "OrganizationId": "00aa00aa-bb11-cc22-dd33-44ee44ee44ee" }
Créer une fonction WhoAmI
Nous allons placer le code pour appeler la fonction WhoAmI dans une fonction appelée Get-WhoAmI à l’intérieur d’un fichier nommé CommonFunctions.ps1 afin que nous puissions taper seulement 11 caractères plutôt que 100 chaque fois que vous souhaitez utiliser la fonction WhoAmI
Créez un fichier texte nommé
CommonFunctions.ps1dans votrescriptsdossier.Copiez et collez la définition de fonction suivante dans le
CommonFunctions.ps1.function Get-WhoAmI{ $WhoAmIRequest = @{ Uri = $baseURI + 'WhoAmI' Method = 'Get' Headers = $baseHeaders } Invoke-RestMethod @WhoAmIRequest }Note
Cette définition de fonction utilise une technique appelée Splatting. Le Splatting rend vos commandes plus courtes et plus faciles à lire, car il transmet une collection de valeurs de paramètres à une commande en tant qu’unité.
Enregistrez le fichier
CommonFunctions.ps1.Modifiez le fichier pour qu’il
test.ps1ressemble au script suivant :. $PSScriptRoot\Core.ps1 . $PSScriptRoot\CommonFunctions.ps1 Connect 'https://yourorg.crm.dynamics.com/' # change to your organization # Invoke WhoAmI Function Get-WhoAmI | ConvertTo-JsonN’oubliez pas de modifier la
https://yourorg.crm.dynamics.com/valeur pour qu’elle corresponde à l’URL de votre environnement.Pour exécuter le script, appuyez sur F5.
La sortie doit être exactement comme avant.
Créer des fonctions d’opérations de table
Nous allons placer des fonctions pour effectuer des opérations de table courantes, un fichier nommé TableOperations.ps1 afin que nous puissions les réutiliser.
Créez un fichier texte nommé
TableOperations.ps1dans votrescriptsdossier.Copiez et collez les définitions de fonction suivantes dans le
TableOperations.ps1.function Get-Records { param ( [Parameter(Mandatory)] [String] $setName, [Parameter(Mandatory)] [String] $query ) $uri = $baseURI + $setName + $query # Header for GET operations that have annotations $getHeaders = $baseHeaders.Clone() $getHeaders.Add('If-None-Match', $null) $getHeaders.Add('Prefer', 'odata.include-annotations="*"') $RetrieveMultipleRequest = @{ Uri = $uri Method = 'Get' Headers = $getHeaders } Invoke-RestMethod @RetrieveMultipleRequest } function New-Record { param ( [Parameter(Mandatory)] [String] $setName, [Parameter(Mandatory)] [hashtable] $body ) $postHeaders = $baseHeaders.Clone() $postHeaders.Add('Content-Type', 'application/json') $CreateRequest = @{ Uri = $baseURI + $setName Method = 'Post' Headers = $postHeaders Body = ConvertTo-Json $body } Invoke-RestMethod @CreateRequest -ResponseHeadersVariable rh | Out-Null $url = $rh['OData-EntityId'] $selectedString = Select-String -InputObject $url -Pattern '(?<=\().*?(?=\))' return [System.Guid]::New($selectedString.Matches.Value.ToString()) } function Get-Record { param ( [Parameter(Mandatory)] [String] $setName, [Parameter(Mandatory)] [Guid] $id, [String] $query ) $uri = $baseURI + $setName $uri = $uri + '(' + $id.Guid + ')' + $query $getHeaders = $baseHeaders.Clone() $getHeaders.Add('If-None-Match', $null) $getHeaders.Add('Prefer', 'odata.include-annotations="*"') $RetrieveRequest = @{ Uri = $uri Method = 'Get' Headers = $getHeaders } Invoke-RestMethod @RetrieveRequest } function Update-Record { param ( [Parameter(Mandatory)] [String] $setName, [Parameter(Mandatory)] [Guid] $id, [Parameter(Mandatory)] [hashtable] $body ) $uri = $baseURI + $setName $uri = $uri + '(' + $id.Guid + ')' # Header for Update operations $updateHeaders = $baseHeaders.Clone() $updateHeaders.Add('Content-Type', 'application/json') $updateHeaders.Add('If-Match', '*') # Prevent Create $UpdateRequest = @{ Uri = $uri Method = 'Patch' Headers = $updateHeaders Body = ConvertTo-Json $body } Invoke-RestMethod @UpdateRequest } function Remove-Record { param ( [Parameter(Mandatory)] [String] $setName, [Parameter(Mandatory)] [Guid] $id ) $uri = $baseURI + $setName $uri = $uri + '(' + $id.Guid + ')' $DeleteRequest = @{ Uri = $uri Method = 'Delete' Headers = $baseHeaders } Invoke-RestMethod @DeleteRequest }Pour plus d’informations sur la rédaction de ces demandes, consultez les articles suivants :
Enregistrez le fichier
TableOperations.ps1.Copiez le code suivant et collez-le dans le
test.ps1fichier.. $PSScriptRoot\Core.ps1 . $PSScriptRoot\CommonFunctions.ps1 . $PSScriptRoot\TableOperations.ps1 Connect 'https://yourorg.crm.dynamics.com/' # change to your organization # Retrieve Records Write-Host 'Retrieve first three account records:' (Get-Records ` -setName accounts ` -query '?$select=name&$top=3').value | Format-Table -Property name, accountid # Create a record Write-Host 'Create an account record:' $newAccountID = New-Record ` -setName accounts ` -body @{ name = 'Example Account'; accountcategorycode = 1 # Preferred } Write-Host "Account with ID $newAccountID created" # Retrieve a record Write-Host 'Retrieve the created record:' Get-Record ` -setName accounts ` -id $newAccountID.Guid '?$select=name,accountcategorycode' | Format-List -Property name, accountid, accountcategorycode, accountcategorycode@OData.Community.Display.V1.FormattedValue # Update a record Write-Host 'Update the record:' $updateAccountData = @{ name = 'Updated Example account'; accountcategorycode = 2; #Standard } Update-Record ` -setName accounts ` -id $newAccountID.Guid ` -body $updateAccountData Write-Host 'Retrieve the updated the record:' Get-Record ` -setName accounts ` -id $newAccountID.Guid ` -query '?$select=name,accountcategorycode' | Format-List -Property name, accountid, accountcategorycode, accountcategorycode@OData.Community.Display.V1.FormattedValue # Delete a record Write-Host 'Delete the record:' Remove-Record ` -setName accounts ` -id $newAccountID.Guid Write-Host "The account with ID $newAccountID was deleted"N’oubliez pas de modifier la
https://yourorg.crm.dynamics.com/valeur pour qu’elle corresponde à l’URL de votre environnement.Pour exécuter le script, appuyez sur F5.
La sortie peut ressembler à cette sortie :
PS C:\scripts> . 'C:\scripts\test.ps1' Retrieve first three account records: name accountid ---- --------- Fourth Coffee (sample) d2382248-cd99-ee11-be37-000d3a9b7981 Litware, Inc. (sample) d4382248-cd99-ee11-be37-000d3a9b7981 Adventure Works (sample) d6382248-cd99-ee11-be37-000d3a9b7981 Create an account record: Account with ID a2c3ebc2-39a8-ee11-be37-000d3a8e8e07 created Retrieve the created record: name : Example Account accountid : a2c3ebc2-39a8-ee11-be37-000d3a8e8e07 accountcategorycode : 1 accountcategorycode@OData.Community.Display.V1.FormattedValue : Preferred Customer Update the record: Retrieve the updated the record: name : Updated Example account accountid : a2c3ebc2-39a8-ee11-be37-000d3a8e8e07 accountcategorycode : 2 accountcategorycode@OData.Community.Display.V1.FormattedValue : Standard Delete the record: The account with ID a2c3ebc2-39a8-ee11-be37-000d3a8e8e07 was deleted
Gérer les exceptions
Jusqu’à présent, dans cet article, vous avez copié et collé du code fourni pour vous. Mais lorsque vous commencez à écrire et à utiliser vos propres fonctions, vous pouvez rencontrer des erreurs. Lorsque ces erreurs se produisent, elles peuvent provenir de Dataverse ou de votre script.
Ajoutez une fonction d’assistance qui peut aider à détecter la source des erreurs et à extraire les détails pertinents des erreurs retournées par Dataverse.
Ajoutez la fonction suivante
Invoke-DataverseCommandsauCore.ps1fichier :function Invoke-DataverseCommands { param ( [Parameter(Mandatory)] $commands ) try { Invoke-Command $commands } catch [Microsoft.PowerShell.Commands.HttpResponseException] { Write-Host "An error occurred calling Dataverse:" -ForegroundColor Red $statuscode = [int]$_.Exception.StatusCode; $statusText = $_.Exception.StatusCode Write-Host "StatusCode: $statuscode ($statusText)" # Replaces escaped characters in the JSON [Regex]::Replace($_.ErrorDetails.Message, "\\[Uu]([0-9A-Fa-f]{4})", {[char]::ToString([Convert]::ToInt32($args[0].Groups[1].Value, 16))} ) } catch { Write-Host "An error occurred in the script:" -ForegroundColor Red $_ } }La
Invoke-DataverseCommandsfonction utilise l’applet de commande Invoke-Command pour traiter un ensemble de commandes dans un bloc try/catch. Toutes les erreurs retournées par Dataverse sont des erreurs de type HttpResponseException. Par conséquent, le premier bloccatchécrit un messageAn error occurred calling Dataverse:dans le terminal avec les données d’erreur JSON.Les données JSON dans
$_.ErrorDetails.Messagecontiennent des caractères Unicode échappés. Par exemple :\u0026au lieu de&et\u0027au lieu de'. Cette fonction comprend du code qui remplace ces caractères par les caractères non échappés afin qu'ils correspondent exactement aux erreurs que vous identifiez ailleurs.Sinon, les erreurs sont réécrites dans la fenêtre de terminal avec un message :
An error occurred in the script:Enregistrez le fichier
Core.ps1.Modifiez le
test.ps1fichier pour ajouter le script suivant qui utilise une valeur de paramètre non validesetName. Leaccountparamètre doit êtreaccounts. Cette erreur est courante.. $PSScriptRoot\Core.ps1 . $PSScriptRoot\CommonFunctions.ps1 . $PSScriptRoot\TableOperations.ps1 Connect 'https://yourorg.crm.dynamics.com/' # change this Invoke-DataverseCommands { # Retrieve Records Write-Host 'Retrieve first three account records:' (Get-Records ` -setName account ` -query '?$select=name&$top=3').value | Format-Table -Property name, accountid }N’oubliez pas de modifier la
https://yourorg.crm.dynamics.com/valeur pour qu’elle corresponde à l’URL de votre environnement.Pour exécuter le script, appuyez sur F5.
La sortie peut ressembler à cette sortie :
PS C:\scripts> . 'C:\scripts\test.ps1' Retrieve first three account records: An error occurred calling Dataverse: StatusCode: 404 (NotFound) { "error": { "code": "0x80060888", "message": "Resource not found for the segment 'account'." } }Modifiez le
test.ps1fichier pour lever une erreur de script dans leInvoke-DataverseCommandsbloc :Invoke-DataverseCommands { throw 'A script error' }Pour exécuter le script, appuyez sur F5.
La sortie doit être presque la même que si elle n’était pas incluse dans le
Invoke-DataverseCommandsbloc :PS C:\scripts> . 'C:\scripts\test.ps1' An error occurred in the script: Exception: C:\scripts\test.ps1:8:4 Line | 8 | throw 'A script error' | ~~~~~~~~~~~~~~~~~~~~~~ | A script error
Gérer les limites de protection des services Dataverse
Les limites de l’API de protection du service Dataverse permettent de s’assurer que Dataverse offre une disponibilité et des performances cohérentes. Lorsque les applications clientes font des demandes excessives sur les ressources serveur à l’aide de l’API Web, Dataverse retourne une erreur 429 trop de requêtes, et les applications clientes doivent suspendre les opérations pendant la durée spécifiée dans l’en-tête Retry-After.
Le paramètre MaximumRetryCount de l’applet de commande PowerShellInvoke-RestMethod spécifie le nombre de tentatives d’une requête lorsqu’un code d’échec est compris entre 400 et 599, inclus ou 304 est reçu. Cela signifie que PowerShell retente les erreurs de protection du service Dataverse 429 lorsque vous incluez une valeur pour ce paramètre. Le MaximumRetryCount paramètre peut être utilisé avec RetryIntervalSec pour spécifier le nombre de secondes à attendre. La valeur par défaut est 5 secondes. Si la réponse d’erreur inclut un Retry-After en-tête pour une erreur 429, comme les erreurs de protection du service Dataverse le font, cette valeur est utilisée à la place.
Vous ne rencontrerez peut-être jamais d’erreur de limite de protection du service pendant que vous apprenez à utiliser l’API Web Dataverse avec PowerShell. Toutefois, les scripts que vous écrivez peuvent envoyer un grand nombre de requêtes qui produisent des erreurs. Découvrez comment les gérer le mieux à l’aide de PowerShell.
Si vous ajoutez le paramètre MaximumRetryCount à chaque appel Dataverse à l’aide de Invoke-RestMethod, PowerShell retente un large éventail d’erreurs. Une nouvelle tentative de chaque erreur ralentit vos scripts, en particulier lors du développement et du test. Vous devez attendre 10 à 15 secondes chaque fois qu’une erreur se produit, en fonction du nombre de nouvelles tentatives que vous spécifiez. Une autre approche consiste à encapsuler dans Invoke-RestMethod votre propre méthode qui gère les nouvelles tentatives pour des erreurs spécifiques.
La fonction suivante Invoke-ResilientRestMethod prend un request objet de table de hachage comme paramètre obligatoire et un indicateur booléen returnHeader pour indiquer si l’en-tête de réponse doit être retourné ou non. Lorsque $returnHeader est true, elle envoie la requête en utilisant la commande Invoke-RestMethod avec le paramètre ResponseHeadersVariable pour capturer les en-têtes retournés. La fonction utilise Out-Null pour que la sortie qui représente le corps de la réponse vide ne soit pas retournée avec la fonction. Sinon, la fonction envoie la requête à l’aide de Invoke-RestMethod avec l’objet request et retourne le corps de la réponse.
Si Invoke-RestMethod échoue avec une erreur 429, il vérifie si l’objet request possède une propriété MaximumRetryCount. Si la fonction réussit, elle crée une MaximumRetryCount propriété définie sur 3. On réessaie Invoke-RestMethod en utilisant l'objet de requête et la valeur de l'en-tête de réponse Retry-After. Si l’indicateur returnHeader est true, il retourne l’en-tête de réponse. Si Invoke-RestMethod échoue avec une autre erreur, elle renvoie l’exception.
function Invoke-ResilientRestMethod {
param (
[Parameter(Mandatory)]
$request,
[bool]
$returnHeader
)
try {
if ($returnHeader) {
Invoke-RestMethod @request -ResponseHeadersVariable rhv | Out-Null
return $rhv
}
Invoke-RestMethod @request
}
catch [Microsoft.PowerShell.Commands.HttpResponseException] {
$statuscode = $_.Exception.Response.StatusCode
# 429 errors only
if ($statuscode -eq 'TooManyRequests') {
if (!$request.ContainsKey('MaximumRetryCount')) {
$request.Add('MaximumRetryCount', 3)
# Don't need - RetryIntervalSec
# When the failure code is 429 and the response includes the Retry-After property in its headers,
# the cmdlet uses that value for the retry interval, even if RetryIntervalSec is specified
}
# Will attempt retry up to 3 times
if ($returnHeader) {
Invoke-RestMethod @request -ResponseHeadersVariable rhv | Out-Null
return $rhv
}
Invoke-RestMethod @request
}
else {
throw $_
}
}
catch {
throw $_
}
}
Vous pouvez utiliser une fonction similaire dans vos fonctions réutilisables. Lorsque les fonctions doivent renvoyer des valeurs de l’en-tête de la réponse, elles doivent définir la valeur returnHeader sur $true. Par exemple, la fonction suivante New-Record modifie l’exemple de fonction dans Créer des fonctions d’opérations de table à utiliser Invoke-ResilientRestMethod plutôt que Invoke-RestMethod directement.
function New-Record {
param (
[Parameter(Mandatory)]
[String]
$setName,
[Parameter(Mandatory)]
[hashtable]
$body
)
$postHeaders = $baseHeaders.Clone()
$postHeaders.Add('Content-Type', 'application/json')
$CreateRequest = @{
Uri = $baseURI + $setName
Method = 'Post'
Headers = $postHeaders
Body = ConvertTo-Json $body
}
# Before:
# Invoke-RestMethod @CreateRequest -ResponseHeadersVariable rh | Out-Null
# After:
$rh = Invoke-ResilientRestMethod -request $CreateRequest -returnHeader $true
$url = $rh['OData-EntityId']
$selectedString = Select-String -InputObject $url -Pattern '(?<=\().*?(?=\))'
return [System.Guid]::New($selectedString.Matches.Value.ToString())
}
Sinon, Invoke-ResilientRestMethod peut remplacer la Invoke-RestMethod valeur indiquée dans cet Get-Record exemple :
function Get-Record {
param (
[Parameter(Mandatory)]
[String]
$setName,
[Parameter(Mandatory)]
[Guid]
$id,
[String]
$query
)
$uri = $baseURI + $setName
$uri = $uri + '(' + $id.Guid + ')' + $query
$getHeaders = $baseHeaders.Clone()
$getHeaders.Add('If-None-Match', $null)
$getHeaders.Add('Prefer', 'odata.include-annotations="*"')
$RetrieveRequest = @{
Uri = $uri
Method = 'Get'
Headers = $getHeaders
}
# Before:
# Invoke-RestMethod @RetrieveRequest
# After:
Invoke-ResilientRestMethod $RetrieveRequest
}
La seule différence est que vous transmettez la table de hachage ($RetrieveRequest) à la méthode au lieu d’utiliser le splatting (@RetrieveRequest). Sinon, vous obtenez une erreur de script : A parameter cannot be found that matches parameter name 'Headers'.
Déboguer à l’aide de Fiddler
Fiddler est un proxy de débogage web utilisé pour afficher le trafic HTTP sur votre ordinateur. L’affichage de ces données est utile lors du débogage de scripts. Par défaut, les requêtes et réponses HTTP envoyées à l’aide d'Invoke-RestMethod applet de commande ne sont pas visibles lorsque vous utilisez Fiddler.
Pour afficher le trafic HTTP dans Fiddler, définissez le Invoke-RestMethodparamètre proxy sur l’URL configurée comme proxy Fiddler sur votre ordinateur local. Par défaut, l’URL est http://127.0.0.1:8888. Votre URL peut être différente.
Par exemple, si vous appelez la fonction WhoAmI alors que Fiddler capture le trafic et que le paramètre -Proxy est défini :
Invoke-RestMethod `
-Uri ($environmentUrl + 'api/data/v9.2/WhoAmI') `
-Method Get `
-Headers $baseHeaders `
-Proxy 'http://127.0.0.1:8888'
Dans Fiddler, vous pouvez voir tous les détails :
GET https://yourorg.api.crm.dynamics.com/api/data/v9.2/WhoAmI HTTP/1.1
Host: yourorg.api.crm.dynamics.com
OData-MaxVersion: 4.0
Accept: application/json
Authorization: Bearer [REDACTED]
OData-Version: 4.0
User-Agent: Mozilla/5.0 (Windows NT 10.0; Microsoft Windows 10.0.22631; en-US) PowerShell/7.4.0
Accept-Encoding: gzip, deflate, br
HTTP/1.1 200 OK
Cache-Control: no-cache
Allow: OPTIONS,GET,HEAD,POST
Content-Type: application/json; odata.metadata=minimal
Expires: -1
Vary: Accept-Encoding
x-ms-service-request-id: 7341c0c1-3343-430b-98ea-292567ed4776
Set-Cookie: ARRAffinity=f60cbee43b7af0a5f322e7ce57a018546ed978f67f0c11cbb5e15b02ddb091a915134d20c556b0b34b9b6ae43ec3f5dcdad61788de889ffc592af7aca85fc1c508DC0FC94CB062A12107345846; path=/; secure; HttpOnly
Set-Cookie: ReqClientId=4fc95009-0b3d-4a19-b223-0d80745636ac; expires=Sun, 07-Jan-2074 21:10:42 GMT; path=/; secure; HttpOnly
Set-Cookie: orgId=00aa00aa-bb11-cc22-dd33-44ee44ee44ee; expires=Sun, 07-Jan-2074 21:10:42 GMT; path=/; secure; HttpOnly
x-ms-service-request-id: 1ee13aa7-47f3-4a75-95fa-2916775a1f79
Strict-Transport-Security: max-age=31536000; includeSubDomains
REQ_ID: 1ee13aa7-47f3-4a75-95fa-2916775a1f79
CRM.ServiceId: framework
AuthActivityId: 0b562cc3-56f6-44f0-a26e-4039cfc4be6a
x-ms-dop-hint: 48
x-ms-ratelimit-time-remaining-xrm-requests: 1,200.00
x-ms-ratelimit-burst-remaining-xrm-requests: 5999
OData-Version: 4.0
X-Source: 110212218438874147222728177124203420477168182861012399121919014511175711948418152
Public: OPTIONS,GET,HEAD,POST
Set-Cookie: ARRAffinity=f60cbee43b7af0a5f322e7ce57a018546ed978f67f0c11cbb5e15b02ddb091a915134d20c556b0b34b9b6ae43ec3f5dcdad61788de889ffc592af7aca85fc1c508DC0FC94CB062A12107345846; path=/; secure; HttpOnly
X-Source: 2302101791355821068628523819830862152291172232072372448021147103846182145238216119
Date: Sun, 07 Jan 2024 21:10:42 GMT
Content-Length: 277
{"@odata.context":"https://yourorg.api.crm.dynamics.com/api/data/v9.2/$metadata#Microsoft.Dynamics.CRM.WhoAmIResponse","BusinessUnitId":"11bb11bb-cc22-dd33-ee44-55ff55ff55ff","UserId":"22cc22cc-dd33-ee44-ff55-66aa66aa66aa","OrganizationId":"00aa00aa-bb11-cc22-dd33-44ee44ee44ee"}
Si Fiddler n’est pas en cours d’exécution, vous obtenez une erreur :
Invoke-RestMethod: C:\scripts\test.ps1:8:1
Line |
8 | Invoke-RestMethod `
| ~~~~~~~~~~~~~~~~~~~
| No connection could be made because the target machine actively refused it.
Si vous choisissez d’acheminer tous vos Invoke-RestMethod appels par le biais d’une seule fonction, par exemple la Invoke-ResilientRestMethod description décrite dans Gérer les limites de protection du service Dataverse, vous pouvez définir certaines variables dans le Core.ps1 fichier pour configurer cette option dans un emplacement unique.
# Set to true only while debugging with Fiddler
$debug = $true
# Set this value to the Fiddler proxy URL configured on your computer
$proxyUrl = 'http://127.0.0.1:8888'
Dans votre fonction centralisée, vous pouvez définir le paramètre -Proxy avec l'éclatement et utiliser la table de hachage $request uniquement lors du débogage avec Fiddler.
function Invoke-ResilientRestMethod {
param (
[Parameter(Mandatory)]
$request,
[bool]
$returnHeader
)
if ($debug) {
$request.Add('Proxy', $proxyUrl)
}
...
En savoir plus sur la capture du trafic web avec Fiddler
Télécharger le document $metadata CSDL de l’API web Dataverse
Le langage CSDL (Common Schema Definition Language) $metadata est la source de vérité sur les fonctionnalités de l’API Web Dataverse. Vous pouvez l’afficher dans un navigateur, mais il peut être plus facile de télécharger le fichier et de l’afficher dans Visual Studio Code. Le script suivant est une version modifiée du script introduit dans l’API web démarrage rapide avec PowerShell. La différence est qu’elle utilise l’applet de commandeInvoke-WebRequest, qui est plus appropriée pour télécharger un document XML.
$environmentUrl = 'https://yourorg.crm.dynamics.com/' # change to your organization
$writeFileTo = 'C:\temp\yourorg.xml' # change to your organization
## Login if not already logged in
if ($null -eq (Get-AzTenant -ErrorAction SilentlyContinue)) {
Connect-AzAccount | Out-Null
}
# Get an access token
$secureToken = (Get-AzAccessToken `
-ResourceUrl $environmentUrl `
-AsSecureString).Token
# Convert the secure token to a string
$token = ConvertFrom-SecureString `
-SecureString $secureToken `
-AsPlainText
# Common headers
$xmlHeaders = @{
'Authorization' = 'Bearer ' + $token
'Accept' = 'application/xml'
'OData-MaxVersion' = '4.0'
'OData-Version' = '4.0'
}
$doc = [xml](Invoke-WebRequest `
-Uri ($environmentUrl + 'api/data/v9.2/$metadata?annotations=true') `
-Method 'Get' `
-Headers $xmlHeaders ).Content
$StringWriter = New-Object System.IO.StringWriter
$XmlWriter = New-Object System.XMl.XmlTextWriter $StringWriter
$xmlWriter.Formatting = 'indented'
$xmlWriter.Indentation = 2
$doc.WriteContentTo($XmlWriter)
$XmlWriter.Flush()
$StringWriter.Flush()
Set-Content -Path $writeFileTo -Value $StringWriter.ToString()
code $writeFileTo
- Copiez le script.
- Modifiez les variables
$environmentUrlet$writeFileTopour qu’elles correspondent à vos besoins. - Exécutez le script dans Visual Studio Code.
Le document $metadata CSDL de l’API web Dataverse s’ouvre dans Visual Studio Code.
Vous pouvez recevoir une notification indiquant : Pour des raisons de performances, les symboles de document sont limités à 5 000 éléments. Si une nouvelle limite est définie, fermez et rouvrez ce fichier pour recompiler les symboles de document.
La notification offre la possibilité de modifier la limite d’extension xml.symbols.maxItemsComputed XML de Visual Studio Code. Pour la plupart des documents CSDL de l’API web Dataverse $metadata, la définition de la limite 500000 doit être suffisante.
Résolution des problèmes
Cette section contient des conseils pour les problèmes que vous pouvez rencontrer.
Boîte de dialogue d’erreur : connectez ENOENT\\.\pipe\<RANDOM_text> avec le bouton Ouvrir 'launch.json'
Cette erreur peut se produire lors du débogage avec Visual Studio Code. Pour résoudre l’erreur :
- Sélectionnez Afficher> lapalette de commandes... dans le menu Visual Studio Code, ou appuyez sur Ctrl+Maj+P.
- Tapez
restartet sélectionnezPowershell: Restart session. Pour plus d’informations, consultez PowerShell/vscode-powershell GitHub Issue 4332 .
Étapes suivantes
En savoir plus sur les fonctionnalités de l’API Web Dataverse en comprenant les documents de service.
Passez en revue et exécutez des exemples de code.