次の方法で共有


Dataverse Web API で PowerShell と Visual Studio Code を使う

この記事は、PowerShell を使ったクイックスタート Web API 記事を展開し、 Dataverse Web API を持つ PowerShell と Visual Studio Code を使った詳細期のを説明します。

注意

この記事の手順は Windows、Linux、macOS で機能するはずですが、これらの手順は Windows でのみテストされています。 変更が必要な場合は、この記事の下部にある フィードバック セクションを使用してお知らせください。

前提条件

この記事の内容は、PowerShell を使用した Web API クイック スタート の記事と同じ前提条件があります。

以下をインストールするか、インストールされていることを確認する

インストールを検証する

  1. Visual Studio Code を開きます。

  2. ターミナル メニューで、新規ターミナル を選択します。

  3. Visual Studio Code ナビゲーション ウィンドウで、PowerShell 拡張子の アイコンを選択します。

  4. Visual Studio Code ターミナル ウィンドウで、次のスクリプトをコピーして貼り付けます。

    Write-Host 'PowerShell Version:'$PSVersionTable.PSVersion.ToString()
    Write-Host 'PowerShell Az version:'(Get-InstalledModule Az).Version
    
  5. Enter キーを押します。 出力は、次の例のようになります。

    PowerShell Version: 7.4.0
    PowerShell Az version: 11.1.0
    

このような結果が表示されない場合は、前提条件をインストールまたは更新してください。

さらに必要なこと

  • Dataverse 環境に有効なユーザー アカウント
  • 接続に使用したい Dataverse 環境への URL。 検索方法については、開発者向けリソースを表示 をご覧ください。 次のようになります: https://yourorg.crm.dynamics.com/、これは yourorg.crm が異なります。
  • PowerShell スクリプト言語の基本的な解釈

再利用可能な関数を作成する

PowerShell を使用したクイック スタート Web API では、コードを使用して WhoAmI関数 Visual Studio を認証して呼び出す方法を紹介しました。 1 つ以上の操作のアドホック テストに必要なのは、このアプローチだけである可能性があります。 ただし、スクリプトが複雑になると、同じコードを何度も入力することになる場合があります。

このセクションでは、ドット ソーシング を使用してアクセスできる個別のファイルに再利用可能な関数のセットの作成を開始します。 ドット ソーシングを使用して、ローカル スクリプト スコープの一部となる関数と変数を含むことができる PowerShell スクリプトを含むファイルを読み込みます。

ヒント

これらの関数の完全に文書化された定義などは、PowerApps-Samples/dataverse/webapi/PS/GitHub PowerApps-Samples リポジトリ

接続機能の作成

Dataverse を認証するコードを、Connect という名前のファイル内の Core.ps1 という関数に配置して、1 行のコードで再利用できるようにしましょう。

  1. フォルダーを作成します。 この例では、C:\scripts というフォルダーを作成します。

  2. Visual Studio コード内のスクリプト フォルダーを開きます

  3. Core.ps1という名前のスクリプト フォルダーにテキスト ファイルを作成します。

  4. 以下の Connect 関数を Core.ps1 ファイルにコピーし貼り付けます。

    function Connect {
       param (
          [Parameter(Mandatory)] 
          [String] 
          $uri
       )
    
       ## Login interactively if not already logged in
       if ($null -eq (Get-AzTenant -ErrorAction SilentlyContinue)) {
          Connect-AzAccount | Out-Null
       }
    
       # Get an access token
       $token = (Get-AzAccessToken -ResourceUrl $uri).Token
    
       # 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 = $uri + 'api/data/v9.2/'
    }
    

    注意

    このスクリプトは、baseURIbaseHeaders 変数を $global スコープ修飾子 ウィtyじゃってグローバル コンテキストに追加し、同じセッション内で他のスクリプトで使用できるようにします。

  5. Visual Studio コード名 test.ps1scripts フォルダー内に別のテキスト ファイルを作成します。

  6. 以下のスクリプトを test.ps1 ファイルにコピーし貼り付けます。

    . $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.ps1 ファイルの先頭では、 ドット ソース を使用して、スクリプトにそのファイルの内容を読み込むように指示します。

    https://yourorg.crm.dynamics.com/ を 環境 のURLと一致するように変更することを忘れないでください。

  7. スクリプトを実行するには、 F5 を押します。

    出力は次のようになります。

    PS C:\scripts> . 'C:\scripts\test.ps1'
    {
    "@odata.context": "https://yourorg.crm.dynamics.com/api/data/v9.2/$metadata#Microsoft.Dynamics.CRM.WhoAmIResponse",
    "BusinessUnitId": "3a277578-5996-ee11-be36-002248227994",
    "UserId": "2c2e7578-5996-ee11-be36-002248227994",
    "OrganizationId": "97bf0e8b-aa99-ee11-be32-000d3a106c3a"
    }
    

WhoAmI 関数の作成

WhoAmI 関数 を呼び出すコードを、Get-WhoAmI という名前のファイル内の CommonFunctions.ps1 という関数に配置して、WhoAmI 関数 を使用する場合は、毎回 100 文字ではなく 11 文字を使用します。

  1. CommonFunctions.ps1 という名前の scripts フォルダーに新規テキスト ファイルを作成します。

  2. CommonFunctions.ps1 で次の関数定義をコピーして貼り付けます。

    function Get-WhoAmI{
    
       $WhoAmIRequest = @{
          Uri = $baseURI + 'WhoAmI'
          Method = 'Get'
          Headers = $baseHeaders
       }
    
       Invoke-RestMethod @WhoAmIRequest
    }
    

    注意

    この関数定義では、スプラッティング と呼ばれる手法を使用します。 スプラッティングにより、パラメーター値のコレクションが 1 つの単位としてコマンドに渡されるため、コマンドが短くなり、読みやすくなります。

  3. CommonFunctions.ps1 ファイルを保存します。

  4. test.ps1 ファイルを次のスクリプトのように変更します。

. $PSScriptRoot\Core.ps1
. $PSScriptRoot\CommonFunctions.ps1

Connect 'https://yourorg.crm.dynamics.com/' # change to your organization
# Invoke WhoAmI Function
Get-WhoAmI | ConvertTo-Json

環境の URL に一致するように https://yourorg.crm.dynamics.com/ 値を変更してください。

  1. スクリプトを実行するには、 F5 を押します。

    出力は以前とまったく同じになるはずです。

テーブル操作関数の作成

共通のテーブル操作を実行する関数を TableOperations.ps1 という名前のファイルに配置して、再利用できるようにしましょう。

  1. TableOperations.ps1 という名前の scripts フォルダーに新規テキスト ファイルを作成します。

  2. 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
    }
    
    

    これらのリクエストの作成方法の詳細については、次の記事にアクセスしてください。

  3. TableOperations.ps1 ファイルを保存します。

  4. 次のコードをコピーして、test.ps1 ファイルに貼り付けます。

    . $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"
    

    環境の URL に一致するように https://yourorg.crm.dynamics.com/ 値を変更してください。

  5. スクリプトを実行するには、 F5 を押します。

    出力は次のようになります。

    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
    

例外処理

これまでこの記事では、提供されたコードをコピーして貼り付けてきました。 しかし、独自の関数を書いて使用し始めると、エラーが発生する可能性があります。 これらのエラーが発生した場合、 Dataverse またはスクリプトが原因である可能性があります。

エラーの原因を検出し、 Dataverse によって返されるエラーから関連する詳細を抽出するのに役立つヘルパー関数を追加します。

  1. 次の Invoke-DataverseCommands 関数を Core.ps1 ファイルに追加します。

    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
          $_
       }
    }
    

    Invoke-DataverseCommands 関数は、Invoke-Command コマンドレット を使用して、try/catch ブロック 内の一連のコマンドを処理します。 Dataverse から返されるエラーはすべて HttpResponseException エラーであるため、最初の catch ブロックはJSONエラー データを含む An error occurred calling Dataverse: メッセージを端末に書き込みます。

    $_.ErrorDetails.Message の JSON データには、エスケープされた Unicode 文字が含まれています。 たとえば、& の代わりに \u0026' の代わりに \u0027。 この関数には、他の場所で発生するエラーと正確に一致するように、これらの文字をエスケープされていない文字に置き換えるコードが含まれています。

    それ以外の場合、エラーは次のメッセージとともに端末ウィンドウに書き戻されます: An error occurred in the script:

  2. Core.ps1 ファイルを保存します。

  3. test.ps1 ファイルを編集して、無効な setName パラメータ値を使用する次のスクリプトを追加します。 account パラメータは accounts である必要があります。 このエラーはよく発生します

. $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
   
}

環境の URL に一致するように https://yourorg.crm.dynamics.com/ 値を変更してください。

  1. スクリプトを実行するには、 F5 を押します。

    出力は次のようになります。

    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'."
       }
    }
    
  2. test.ps1 ファイルを編集して、Invoke-DataverseCommands ブロック内でスクリプト エラーをスローします。

    Invoke-DataverseCommands {
    
       throw 'A script error'
    
    }
    
  3. スクリプトを実行するには、 F5 を押します。

    出力は、Invoke-DataverseCommands ブロックに含まれていない場合とほぼ同じになるはずです。

    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
    

Dataverse サービス保護の制限を管理する

Dataverse サービス保護APIの制限 により、Dataverse は一貫した可用性とパフォーマンスを提供することが確保されます。 クライアント アプリケーションが Web API を使用してサーバー リソースに対して異常な要求を行うと、 Dataverse 429 Too Many Requests エラーが返され、クライアント アプリケーションは Retry-Afterヘッダー で指定された期間、操作を一時停止する必要があります。

PowerShell Invoke-RestMethod コマンドレット MinimumRetryCount パラメータ は、失敗コードが 400 ~ 599 または 304 が受信されえた場合に PowerShell がリクエストを再試行する回数を指定します。 これは、このパラメーターの値を含めると、PowerShell が Dataverse サービス保護 429 エラーを再試行することを意味します。 MaximumRetryCount パラメータは、再試行間隔秒 を使用して待機する秒数を指定します。 既定値は 5 秒です。 エラー応答に次のものが含まれる場合、 429 エラーの Retry-After ヘッダー: Dataverse サービス保護エラーが発生した場合は、その値が代わりに使用されます。

PowerShell を使用した Dataverse Web API。の使用方法を学習している間は、サービス保護制限エラーが発生しない可能性があります。 ただし、作成したスクリプトによってエラーが発生するリクエストが大量に送信される可能性があるため、PowerShellを使用してそれらを最適に管理する方法を学習してください。

MaximumRetryCount パラメータを Invoke-RestMethod を使用して各 Dataverse 通話に追加すると、PowerShell は広範囲のエラーを再試行します。 エラーが発生するたびに再試行すると、特に開発時やテスト時にスクリプトが遅くなります。 指定した再試行回数に応じて、エラーが発生するたびに 10 ~ 15 秒待つ必要があります。 別のアプローチは、特定のエラーに対する再試行を管理する独自のメソッドで Invoke-RestMethod をカプセル化します。

次の Invoke-ResilientRestMethod 関数は、 request ハッシュテーブル オブジェクトを必須パラメーターとして受け取り、応答 ヘッダーを返すかどうかを示す ブール値 returnHeader フラグを受け取ります。 $returnHeader がtrueの場合、 Invoke-RestMethod コマンドと ResponseHeadersVariable パラメータを使用してリクエストを送信し、返されたヘッダーをキャプチャします。 この関数は Out-Null を使用するため、空の 応答 本体を表す出力は関数とともに返されません。 それ以外の場合、関数は Invoke-RestMethod オブジェクトを使用して request リクエストを送信し、応答 本体を返します。

Invoke-RestMethod が 429 エラーで失敗した場合は、request オブジェクトに MaximumRetryCount プロパティがあるかどうかを確認します。 関数が成功すると、 MaximumRetryCount に設定されたプロパティ 3 が作成されます。 次に、リクエスト オブジェクトと 応答 ヘッダー値を使用して、 Invoke-RestMethod が再試行されます。 Retry-After もし returnHeader フラグが true の場合、応答ヘッダーを返します。 Invoke-RestMethod がその他のエラーで失敗した場合は、例外が再スローされます。

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 $_
   }
}

再利用可能な関数でも同様の関数を使用できます。 関数が応答のヘッダーから値を返す必要がある場合、関数は returnHeader 値を $true に設定する必要があります。 たとえば、次の New-Record 関数は、テーブル操作関数の作成 のサンプル関数を変更して、直接 Invoke-RestMethod の代わりに Invoke-ResilientRestMethod を使用します。

function New-Record {
   param (
      [Parameter(Mandatory)] 
      [String] 
      $setName,
      [Parameter(Mandatory)] 
      [hashtable]
      $body
   )
   $postHeaders = $baseHeaders.Clone()
   $postHeaders.Add('Content-Type', 'application/json')
   
   $CreateRequest = @{
      Uri     = $environmentUrl + 'api/data/v9.2/' + $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())
}

それ以外の場合は、Invoke-ResilientRestMethod の例に示すように、この Get-Record 例に示されているように Invoke-RestMethod を置き換えます。

function Get-Record {
   param (
      [Parameter(Mandatory)] 
      [String] 
      $setName,
      [Parameter(Mandatory)] 
      [Guid] 
      $id,
      [String] 
      $query
   )
   $uri = $environmentUrl + 'api/data/v9.2/' + $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
}

唯一の違いは、スプラッティング (@RetrieveRequest) を使用する代わりにハッシュテーブル ($RetrieveRequest) をメソッドに渡すことです。 そうしないと、スクリプト エラーが発生します。 A parameter cannot be found that matches parameter name 'Headers'.

Fiddler を使用したデバッグ

Fiddler は、コンピューター上の HTTP トラフィックを表示するために使用される Web デバッグ プロキシです。 このデータを表示すると、スクリプトをデバッグするときに役立ちます。 デフォルトでは、 Invoke-RestMethodコマンドレット を使用して送信されたHTTP要求と応答は、Fiddlerを使用するときには表示されません。

FiddlerでHTTPトラフィックを表示するには、 Invoke-RestMethod プロキシ パラメータ を、ローカル コンピューターでFiddlerプロキシとして構成されているURLに設定します。 既定では、URL は http://127.0.0.1:8888 です。 URLが異なる場合があります。

たとえば、Fiddler がトラフィックをキャプチャしているときに、-Proxy パラメータセットで WhoAmI 関数 を呼び出すと、次のようになります:

Invoke-RestMethod `
   -Uri ($environmentUrl + 'api/data/v9.2/WhoAmI') `
   -Method Get `
   -Headers $baseHeaders `
   -Proxy 'http://127.0.0.1:8888'

Fiddlerでは、すべての詳細を確認できます。

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=648e8efd-db86-466e-a5bc-a4d5eb9c52d4; 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":"1647bf36-e90a-4c4d-9b61-969d57ce7a66","UserId":"24e34f5e-7f1a-43fe-88da-7e4b862d51ad","OrganizationId":"648e8efd-db86-466e-a5bc-a4d5eb9c52d4"}

Fiddlerが実行されていない場合は、次のエラーが発生します。

Invoke-RestMethod: C:\scripts\test.ps1:8:1
Line |
   8 |  Invoke-RestMethod `
     |  ~~~~~~~~~~~~~~~~~~~
     | No connection could be made because the target machine actively refused it.

「サービス保護の制限の管理」で説明されているように、すべての呼び出しを単一の関数経由でルーティングすることを選択した場合は、ファイルでいくつかの変数を設定して、このオプションを1か所で構成できます。 Invoke-RestMethod Invoke-ResilientRestMethod Dataverse Core.ps1

# <a name="set-to-true-only-while-debugging-with-fiddler"></a>Set to true only while debugging with Fiddler
$debug = $true
# <a name="set-this-value-to-the-fiddler-proxy-url-configured-on-your-computer"></a>Set this value to the Fiddler proxy URL configured on your computer
$proxyUrl = 'http://127.0.0.1:8888'

集中化された関数内では、スプラッティングを使用して -Proxy パラメータを設定し、Fiddlerでデバッグするときにのみ $request ハッシュ テーブル を使用できます。

function Invoke-ResilientRestMethod {
   param (
      [Parameter(Mandatory)] 
      $request,
      [bool]
      $returnHeader
   )

   if ($debug) {
      $request.Add('Proxy', $proxyUrl)
   }

   ...

Fiddler を使用した Web トラフィックのキャプチャについて学ぶ

Dataverse Web API CSDL $metadata ドキュメントをダウンロードする

共通スキーマ定義言語 (CSDL) $metadataは、Web API機能に関する真実の情報源です。 Dataverse ブラウザで表示することもできますが、ファイルをダウンロードして Visual Studio Code 内で表示する方が簡単かもしれません。 次のスクリプトは、PowerShell を使用したクイック スタート Web API で紹介されたスクリプトの修正バージョンです。 違いは、XML ドキュメントのダウンロードにより適した Invoke-WebRequest コマンドレット を使用することです。

$environmentUrl = 'https://yourorg.crm.dynamics.com/' # change to your organization
$writeFileTo =  'C:\temp\yourorg.xml' # change to your organization

## <a name="login-if-not-already-logged-in"></a>Login if not already logged in
if ($null -eq (Get-AzTenant -ErrorAction SilentlyContinue)) {
   Connect-AzAccount | Out-Null
}
# <a name="get-an-access-token"></a>Get an access token
$token = (Get-AzAccessToken -ResourceUrl $environmentUrl).Token
# <a name="common-headers"></a>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
  1. スクリプトをコピーします。
  2. 必要に応じて $environmentUrl 変数と $writeFileTo 変数を編集します。
  3. スクリプトを Visual Studio Code で実行します。

Dataverse Web API CSDL $metadataドキュメントが Visual Studio コードで開きます。

次のような通知が表示される場合があります: パフォーマンス上の理由から、ドキュメント シンボルは5,000項目に制限されています。新しい制限が設定されている場合は、閉じる を実行してこのファイルを再度開き、ドキュメント シンボルを再計算してください

通知には、 Visual Studio コードXML拡張子 xml.symbols.maxItemsComputed の制限を変更するオプションが提供されます。 ほとんどの Dataverse Web API CSDL $metadataドキュメントでは、制限を 500000 に設定すれば十分です。

トラブルシューティング​​

このセクションには、発生する可能性のある問題に関するガイダンスが含まれています。

エラー ダイアログ: ENOENT\\.\pipe\<RANDOM_text> を 'launch.json' を開くボタンで接続します

このエラーは、 Visual Studio Codeを使用してデバッグするときに発生する可能性があります。 エラーを解決するには:

  1. Visual Studio Code メニューから表示 > コマンド パレット... を選択するか、Ctrl+シフト+P キーを押します。
  2. restart をタイプして、Powershell: Restart session を選択します。 詳細については、PowerShell/vscode-powershell GitHub Issue 4332 を参照してください。

次の手順

サービス ドキュメントを理解することで、Dataverse Web API 機能の詳細を学びます。

サンプルコードを確認して実行します。