src/_Internals/XrmClientLibrary.ps1
|
function ConvertTo-XrmConnectionStringMapInternal { param( [string] $RawConnectionString ); $parameters = [ordered]@{}; if ([string]::IsNullOrWhiteSpace($RawConnectionString)) { return $parameters; } $RawConnectionString.Split(';', [System.StringSplitOptions]::RemoveEmptyEntries) | ForEach-Object { $connectionStringSegment = $_.Trim(); if (-not [string]::IsNullOrWhiteSpace($connectionStringSegment)) { $separatorIndex = $connectionStringSegment.IndexOf('='); if ($separatorIndex -gt 0) { $parameterName = $connectionStringSegment.Substring(0, $separatorIndex).Trim(); $parameterValue = $connectionStringSegment.Substring($separatorIndex + 1).Trim(); $normalizedParameterName = $parameterName.Replace(' ', '').ToLowerInvariant(); if (-not [string]::IsNullOrWhiteSpace($normalizedParameterName)) { $parameters[$normalizedParameterName] = [PSCustomObject]@{ Name = $parameterName; Value = $parameterValue; }; } } } }; return $parameters; } function Get-XrmConnectionStringValueInternal { param( [System.Collections.IDictionary] $Parameters, [string[]] $Names ); foreach ($name in $Names) { $normalizedName = $name.Replace(' ', '').ToLowerInvariant(); if ($Parameters.Contains($normalizedName)) { return [string]$Parameters[$normalizedName].Value; } } return $null; } function Set-XrmConnectionStringValueInternal { param( [System.Collections.IDictionary] $Parameters, [string] $Name, [string] $Value ); $normalizedName = $Name.Replace(' ', '').ToLowerInvariant(); if ($Parameters.Contains($normalizedName)) { $Parameters[$normalizedName].Name = $Name; $Parameters[$normalizedName].Value = $Value; } else { $Parameters[$normalizedName] = [PSCustomObject]@{ Name = $Name; Value = $Value; }; } } function ConvertFrom-XrmConnectionStringMapInternal { param( [System.Collections.IDictionary] $Parameters ); $segments = @(); foreach ($parameter in $Parameters.Values) { $segments += "$($parameter.Name)=$($parameter.Value)"; } if ($segments.Count -eq 0) { return $null; } return (($segments -join ';') + ';'); } function Get-XrmExceptionDetailsInternal { param( [System.Exception] $Exception ); if ($null -eq $Exception) { return $null; } $messages = @(); $currentException = $Exception; while ($null -ne $currentException) { $message = $currentException.Message; if (-not ($currentException.InnerException -and $message -like 'Exception calling*') -and -not [string]::IsNullOrWhiteSpace($message) -and $messages -notcontains $message) { $messages += $message; } $currentException = $currentException.InnerException; } return ($messages -join ' | '); } function Get-XrmClientFailureInternal { param( [Parameter(Mandatory = $false)] [Microsoft.PowerPlatform.Dataverse.Client.ServiceClient] $Client, [Parameter(Mandatory = $false)] [System.Exception] $Exception ); $lastError = $null; $lastException = $null; if ($null -ne $Client) { foreach ($propertyName in @('LastError', 'LastCrmError')) { $property = $Client.PSObject.Properties[$propertyName]; if ($null -ne $property -and -not [string]::IsNullOrWhiteSpace([string]$property.Value)) { $lastError = [string]$property.Value; break; } } foreach ($propertyName in @('LastException', 'LastCrmException')) { $property = $Client.PSObject.Properties[$propertyName]; if ($null -ne $property -and $null -ne $property.Value) { $lastException = $property.Value; break; } } } if ($null -ne $Exception -and $null -eq $lastException) { $lastException = $Exception; } $exceptionDetails = Get-XrmExceptionDetailsInternal -Exception $lastException; if (-not [string]::IsNullOrWhiteSpace($exceptionDetails)) { if (-not [string]::IsNullOrWhiteSpace($lastError) -and $exceptionDetails -notlike "*$lastError*") { $lastError = "$lastError | $exceptionDetails"; } else { $lastError = $exceptionDetails; } } if ([string]::IsNullOrWhiteSpace($lastError)) { $lastError = 'Failed to connect to Dataverse.'; } return [PSCustomObject]@{ Message = $lastError; Exception = $lastException; }; } function Resolve-XrmClientConnectionStringInternal { param( [Parameter(Mandatory = $true)] [string] $ConnectionString, [Parameter(Mandatory = $false)] [bool] $IsEncrypted = $false ); if ($IsEncrypted) { $ConnectionString = Repair-XrbConnectionString -ConnectionString $ConnectionString; } $authType = $ConnectionString | Out-XrmConnectionStringParameter -ParameterName 'AuthType'; if ($authType -eq 'Office365') { $ConnectionString = $ConnectionString.Replace('Office365', 'OAuth'); $authType = 'OAuth'; } $connectionStringParameters = ConvertTo-XrmConnectionStringMapInternal -RawConnectionString $ConnectionString; $password = Get-XrmConnectionStringValueInternal -Parameters $connectionStringParameters -Names @('Password'); $clientSecret = Get-XrmConnectionStringValueInternal -Parameters $connectionStringParameters -Names @('ClientSecret', 'Secret'); $thumbprint = Get-XrmConnectionStringValueInternal -Parameters $connectionStringParameters -Names @('Thumbprint', 'CertThumbprint'); $serviceUrl = Get-XrmConnectionStringValueInternal -Parameters $connectionStringParameters -Names @('Url', 'ServiceUri', 'Service Uri', 'Server'); $hasExplicitCredentials = -not [string]::IsNullOrWhiteSpace($password) -or -not [string]::IsNullOrWhiteSpace($clientSecret) -or -not [string]::IsNullOrWhiteSpace($thumbprint); $shouldUseInteractiveFallback = $hasExplicitCredentials -eq $false -and ([string]::IsNullOrWhiteSpace($authType) -or $authType -eq 'OAuth'); if ($shouldUseInteractiveFallback) { if ([string]::IsNullOrWhiteSpace($serviceUrl)) { throw 'New-XrmClient interactive authentication requires a connection string containing Url=<DataverseUrl>.'; } Set-XrmConnectionStringValueInternal -Parameters $connectionStringParameters -Name 'AuthType' -Value 'OAuth'; if ([string]::IsNullOrWhiteSpace((Get-XrmConnectionStringValueInternal -Parameters $connectionStringParameters -Names @('AppId', 'ClientId', 'ApplicationId')))) { Set-XrmConnectionStringValueInternal -Parameters $connectionStringParameters -Name 'AppId' -Value '51f81489-12ee-4a9e-aaae-a2591f45987d'; } if ([string]::IsNullOrWhiteSpace((Get-XrmConnectionStringValueInternal -Parameters $connectionStringParameters -Names @('RedirectUri', 'ReplyUrl')))) { Set-XrmConnectionStringValueInternal -Parameters $connectionStringParameters -Name 'RedirectUri' -Value 'http://localhost'; } if ([string]::IsNullOrWhiteSpace((Get-XrmConnectionStringValueInternal -Parameters $connectionStringParameters -Names @('LoginPrompt')))) { Set-XrmConnectionStringValueInternal -Parameters $connectionStringParameters -Name 'LoginPrompt' -Value 'Auto'; } $ConnectionString = ConvertFrom-XrmConnectionStringMapInternal -Parameters $connectionStringParameters; } return $ConnectionString; } function New-XrmClientConnectionStringInternal { param( [Parameter(Mandatory = $true)] [string] $Url, [Parameter(Mandatory = $false)] [string] $UserName, [Parameter(Mandatory = $false)] [string] $Password, [Parameter(Mandatory = $false)] [string] $ClientId, [Parameter(Mandatory = $false)] [string] $ClientSecret, [Parameter(Mandatory = $false)] [string] $CertificateThumbprint, [Parameter(Mandatory = $false)] [string] $RedirectUri, [Parameter(Mandatory = $false)] [string] $LoginPrompt ); if ([string]::IsNullOrWhiteSpace($Url)) { throw 'Connect-XrmClient requires Url=<DataverseUrl>.'; } $connectionStringParameters = [ordered]@{}; Set-XrmConnectionStringValueInternal -Parameters $connectionStringParameters -Name 'Url' -Value $Url; if (-not [string]::IsNullOrWhiteSpace($ClientSecret)) { if ([string]::IsNullOrWhiteSpace($ClientId)) { throw 'Connect-XrmClient client secret authentication requires -ClientId.'; } Set-XrmConnectionStringValueInternal -Parameters $connectionStringParameters -Name 'AuthType' -Value 'ClientSecret'; Set-XrmConnectionStringValueInternal -Parameters $connectionStringParameters -Name 'ClientId' -Value $ClientId; Set-XrmConnectionStringValueInternal -Parameters $connectionStringParameters -Name 'ClientSecret' -Value $ClientSecret; return ConvertFrom-XrmConnectionStringMapInternal -Parameters $connectionStringParameters; } if (-not [string]::IsNullOrWhiteSpace($CertificateThumbprint)) { if ([string]::IsNullOrWhiteSpace($ClientId)) { throw 'Connect-XrmClient certificate authentication requires -ClientId.'; } Set-XrmConnectionStringValueInternal -Parameters $connectionStringParameters -Name 'AuthType' -Value 'Certificate'; Set-XrmConnectionStringValueInternal -Parameters $connectionStringParameters -Name 'ClientId' -Value $ClientId; Set-XrmConnectionStringValueInternal -Parameters $connectionStringParameters -Name 'Thumbprint' -Value $CertificateThumbprint; return ConvertFrom-XrmConnectionStringMapInternal -Parameters $connectionStringParameters; } $hasUserName = -not [string]::IsNullOrWhiteSpace($UserName); $hasPassword = -not [string]::IsNullOrWhiteSpace($Password); if ($hasPassword -and -not $hasUserName) { throw 'Connect-XrmClient username/password authentication requires both -UserName and -Password.'; } Set-XrmConnectionStringValueInternal -Parameters $connectionStringParameters -Name 'AuthType' -Value 'OAuth'; if ($hasUserName) { Set-XrmConnectionStringValueInternal -Parameters $connectionStringParameters -Name 'Username' -Value $UserName; } if ($hasPassword) { Set-XrmConnectionStringValueInternal -Parameters $connectionStringParameters -Name 'Password' -Value $Password; } if ([string]::IsNullOrWhiteSpace($ClientId)) { $ClientId = '51f81489-12ee-4a9e-aaae-a2591f45987d'; } if ([string]::IsNullOrWhiteSpace($RedirectUri)) { $RedirectUri = 'http://localhost'; } if ([string]::IsNullOrWhiteSpace($LoginPrompt)) { $LoginPrompt = 'Auto'; } Set-XrmConnectionStringValueInternal -Parameters $connectionStringParameters -Name 'AppId' -Value $ClientId; Set-XrmConnectionStringValueInternal -Parameters $connectionStringParameters -Name 'RedirectUri' -Value $RedirectUri; Set-XrmConnectionStringValueInternal -Parameters $connectionStringParameters -Name 'LoginPrompt' -Value $LoginPrompt; return ConvertFrom-XrmConnectionStringMapInternal -Parameters $connectionStringParameters; } |