Merge pull request #461 from microsoft/release/update/240810122408

Resync from Main branch on 240809
This commit is contained in:
MattB 2024-08-09 17:57:06 -07:00 коммит произвёл GitHub
Родитель 0bf47243b7 c0cf11f40f
Коммит be9ee13289
Не найден ключ, соответствующий данной подписи
Идентификатор ключа GPG: B5690EEEBB952194
36 изменённых файлов: 3359 добавлений и 255 удалений

Просмотреть файл

@ -67,7 +67,14 @@ namespace Microsoft.PowerPlatform.Dataverse.Client.Builder
/// <returns></returns>
public T WithHeader(string key, string value)
{
_headers.Add(key, value);
if ( _headers.ContainsKey(key))
{
_headers[key] = value;
}
else
{
_headers.Add(key, value);
}
return (T)this;
}
@ -79,7 +86,16 @@ namespace Microsoft.PowerPlatform.Dataverse.Client.Builder
public T WithHeaders(IDictionary<string, string> headers)
{
foreach (var itm in headers)
_headers.Add(itm.Key, itm.Value);
{
if( _headers.ContainsKey(itm.Key))
{
_headers[itm.Key] = itm.Value;
}
else
{
_headers.Add(itm.Key, itm.Value);
}
}
return (T)this;
}

Просмотреть файл

@ -394,7 +394,7 @@ namespace Microsoft.PowerPlatform.Dataverse.Client
/// <summary>
/// Type of protocol to use
/// </summary>
internal string InternetProtocalToUse { get { return _InternetProtocalToUse; } set { _InternetProtocalToUse = value; } }
internal string InternetProtocolToUse { get { return _InternetProtocalToUse; } set { _InternetProtocalToUse = value; } }
/// <summary>
/// returns the connected organization detail object.
@ -2337,6 +2337,8 @@ namespace Microsoft.PowerPlatform.Dataverse.Client
string requestIdLogSegement = logEntry.GetFormatedRequestSessionIdString(requestTrackingId, SessionTrackingId);
do
{
retry = false; // Set intial state.
// Add authorization header. - Here to catch the situation where a token expires during retry.
if (!customHeaders.ContainsKey(Utilities.RequestHeaders.AUTHORIZATION_HEADER))
customHeaders.Add(Utilities.RequestHeaders.AUTHORIZATION_HEADER, new List<string>() { string.Format("Bearer {0}", await RefreshClientTokenAsync().ConfigureAwait(false)) });

Просмотреть файл

@ -4,11 +4,11 @@ using System.IdentityModel.Protocols.WSTrust;
using System.IdentityModel.Tokens;
using System.Linq;
using System.Security;
using System.Security.Permissions;
using System.ServiceModel;
using System.ServiceModel.Description;
using System.ServiceModel.Security;
using System.Text;
using Microsoft.Xrm.Sdk;
using Microsoft.Xrm.Sdk.Client;
using Microsoft.Xrm.Sdk.Common;
@ -52,6 +52,7 @@ namespace Microsoft.PowerPlatform.Dataverse.Client.Connector.OnPremises
ClientExceptionHelper.ThrowIfNull(ServiceEndpointMetadata, "ServiceEndpointMetadata");
#if NETFRAMEWORK
if (ServiceEndpointMetadata.ServiceEndpoints.Count == 0)
{
StringBuilder errorBuilder = new StringBuilder();
@ -65,6 +66,7 @@ namespace Microsoft.PowerPlatform.Dataverse.Client.Connector.OnPremises
throw new InvalidOperationException(ClientExceptionHelper.FormatMessage(0, "The provided uri did not return any Service Endpoints!\n{0}", errorBuilder.ToString()));
}
#endif
ServiceEndpoints = ServiceEndpointMetadata.ServiceEndpoints;
@ -665,20 +667,20 @@ namespace Microsoft.PowerPlatform.Dataverse.Client.Connector.OnPremises
{
return Issue(authenticationCredentials);
}
catch (SecurityTokenValidationException)
{
retry = false;
//catch (SecurityTokenValidationException) // Removed due to a type conflict with DV Server
//{
// retry = false;
// Fall back to windows integrated.
if (authenticationCredentials.IssuerEndpoints.ContainsKey(TokenServiceCredentialType.Windows.ToString()))
{
authenticationCredentials.EndpointType = TokenServiceCredentialType.Windows;
retry = ++retryCount < 2;
}
// // Fall back to windows integrated.
// if (authenticationCredentials.IssuerEndpoints.ContainsKey(TokenServiceCredentialType.Windows.ToString()))
// {
// authenticationCredentials.EndpointType = TokenServiceCredentialType.Windows;
// retry = ++retryCount < 2;
// }
// We don't care, we just want to return null. The reason why we are are catching this one is because in pure Kerberos mode, this
// will throw a very bad exception that will crash VS.
}
// // We don't care, we just want to return null. The reason why we are are catching this one is because in pure Kerberos mode, this
// // will throw a very bad exception that will crash VS.
//}
catch (SecurityNegotiationException)
{
// This is the exception with Integrated Windows Auth.

Просмотреть файл

@ -16,7 +16,6 @@ using System.ServiceModel.Security.Tokens;
using System.Text;
using System.Xml;
using Microsoft.PowerPlatform.Dataverse.Client.Utils;
//using Microsoft.Crm.Protocols.WSTrust.Bindings;
using Microsoft.Xrm.Sdk;
using Microsoft.Xrm.Sdk.Client;
using Microsoft.Xrm.Sdk.Common;
@ -262,13 +261,13 @@ namespace Microsoft.PowerPlatform.Dataverse.Client.Connector.OnPremises
}
return null;
}
}
#if NETFRAMEWORK
private static KerberosSecurityTokenParameters GetKerberosTokenParameters(SecurityBindingElement securityElement)
{
if (securityElement != null)
{
#if NETFRAMEWORK
if (securityElement.EndpointSupportingTokenParameters != null)
{
if (securityElement.EndpointSupportingTokenParameters.Endorsing != null)
@ -279,15 +278,12 @@ namespace Microsoft.PowerPlatform.Dataverse.Client.Connector.OnPremises
}
}
}
#else
throw new PlatformNotSupportedException("Xrm.Sdk WSTrust");
#endif
}
return null;
}
#endif
private static IssuedSecurityTokenParameters GetIssuedTokenParameters(SecurityBindingElement securityElement)
private static IssuedSecurityTokenParameters GetIssuedTokenParameters(SecurityBindingElement securityElement)
{
if (securityElement != null)
{
@ -351,15 +347,15 @@ namespace Microsoft.PowerPlatform.Dataverse.Client.Connector.OnPremises
}
return new CustomBinding(elements);
}
}
#if NETFRAMEWORK
private static void ParseEndpoints(ServiceEndpointDictionary serviceEndpoints, ServiceEndpointCollection serviceEndpointCollection)
{
serviceEndpoints.Clear();
if (serviceEndpointCollection != null)
{
#if NETFRAMEWORK
foreach (var endpoint in serviceEndpointCollection)
{
if (IsEndpointSupported(endpoint))
@ -367,13 +363,11 @@ namespace Microsoft.PowerPlatform.Dataverse.Client.Connector.OnPremises
serviceEndpoints.Add(endpoint.Name, endpoint);
}
}
#else
throw new PlatformNotSupportedException("Xrm.Sdk WSDL");
#endif
}
}
#endif
private static bool IsEndpointSupported(ServiceEndpoint endpoint)
private static bool IsEndpointSupported(ServiceEndpoint endpoint)
{
if (endpoint != null)
{
@ -389,6 +383,7 @@ namespace Microsoft.PowerPlatform.Dataverse.Client.Connector.OnPremises
internal static ServiceEndpointMetadata RetrieveServiceEndpointMetadata(Type contractType, Uri serviceUri, bool checkForSecondary)
{
#if NETFRAMEWORK // WebInfra; MetadataSet and CreateMetadataClient are NETFRAMEWORK-ONLY
ServiceEndpointMetadata serviceEndpointMetadata = new ServiceEndpointMetadata();
serviceEndpointMetadata.ServiceUrls = ServiceConfiguration<IOrganizationService>.CalculateEndpoints(serviceUri);
@ -398,25 +393,17 @@ namespace Microsoft.PowerPlatform.Dataverse.Client.Connector.OnPremises
serviceEndpointMetadata.ServiceUrls.AlternateEndpoint = null;
}
#if !NETFRAMEWORK
// TODO: Waiting on work for updated WCF endpoints collection to be completed. // hard throw here to prevent any futher progress.
throw new PlatformNotSupportedException("Xrm.Sdk WSDL");
#endif
// Get version of current assembly which is the version of the SDK
#pragma warning disable CS0162 // Unreachable code detected
Version sdkVersion = GetSDKVersionNumberFromAssembly();
#pragma warning restore CS0162 // Unreachable code detected
var wsdlUri = new Uri(string.Format(CultureInfo.InvariantCulture, "{0}{1}&sdkversion={2}", serviceUri.AbsoluteUri, "?wsdl", sdkVersion.ToString(2)));
var mcli = CreateMetadataClient(wsdlUri.Scheme);
if (mcli != null)
{
#if NETFRAMEWORK
try
{
serviceEndpointMetadata.ServiceMetadata = mcli.GetMetadata(wsdlUri, MetadataExchangeClientMode.HttpGet);
}
}
catch (InvalidOperationException ioexp)
{
bool rethrow = true;
@ -447,29 +434,14 @@ namespace Microsoft.PowerPlatform.Dataverse.Client.Connector.OnPremises
throw;
}
}
#else
throw new PlatformNotSupportedException("Xrm.Sdk WSDL");
#endif
}
else
{
#if !NETFRAMEWORK
if (serviceEndpointMetadata.ServiceMetadata == null)
serviceEndpointMetadata.ServiceMetadata = new MetadataSet();
var MetadataBody = GetMexDocument(wsdlUri);
#else
throw new PlatformNotSupportedException("Xrm.Sdk WSDL");
#endif
}
ClientExceptionHelper.ThrowIfNull(serviceEndpointMetadata.ServiceMetadata, "STS Metadata");
ClientExceptionHelper.ThrowIfNull(serviceEndpointMetadata.ServiceMetadata, "STS Metadata");
var contracts = CreateContractCollection(contractType);
if (contracts != null)
{
#if NETFRAMEWORK
// The following code inserts a custom WsdlImporter without removing the other
// importers already in the collection.
var importer = new WsdlImporter(serviceEndpointMetadata.ServiceMetadata);
@ -497,34 +469,15 @@ namespace Microsoft.PowerPlatform.Dataverse.Client.Connector.OnPremises
}
ParseEndpoints(serviceEndpointMetadata.ServiceEndpoints, endpoints);
#else
// Dataverse requires Message Transport security which is not supported in .net core for ActiveDirectory.
//AuthenticationPolicy authenticationPolicy = new AuthenticationPolicy();
//authenticationPolicy.PolicyElements.Add("AuthenticationType", "ActiveDirectory"); // Need to read these from metdata in the future if WCF does not provide support/.
//TextMessageEncodingBindingElement text01 = new TextMessageEncodingBindingElement();
//HttpsTransportBindingElement http1 = new HttpsTransportBindingElement();
//http1.ExtendedProtectionPolicy = new System.Security.Authentication.ExtendedProtection.ExtendedProtectionPolicy(System.Security.Authentication.ExtendedProtection.PolicyEnforcement.WhenSupported, System.Security.Authentication.ExtendedProtection.ProtectionScenario.TransportSelected, null);
//CustomBinding bind = new CustomBinding(authenticationPolicy, new TextMessageEncodingBindingElement(), http1);
//bind.Name = "CustomBinding_IOrganizationService";
//bind.Namespace = "http://schemas.microsoft.com/xrm/2011/Contracts/Services";
//serviceEndpointMetadata.ServiceEndpoints.Add(
// "CustomBinding_IOrganizationService",
// new ServiceEndpoint(contracts[0],
// bind,
// new EndpointAddress(serviceEndpointMetadata.ServiceUrls.PrimaryEndpoint)));
throw new PlatformNotSupportedException("Xrm.Sdk WSDL");
#endif
}
return serviceEndpointMetadata;
#else
throw new NotImplementedException("ServiceModel metadata support is limited for this target framework");
#endif
}
private static Version GetSDKVersionNumberFromAssembly()
private static Version GetSDKVersionNumberFromAssembly()
{
string fileVersion = OrganizationServiceProxy.GetXrmSdkAssemblyFileVersion();
@ -536,8 +489,9 @@ namespace Microsoft.PowerPlatform.Dataverse.Client.Connector.OnPremises
}
return parsedVersion;
}
}
#if NETFRAMEWORK
/// <summary>
/// Returns a list of policy import extensions in the importer parameter and adds a SecurityBindingElementImporter if not already present in the list.
/// </summary>
@ -546,7 +500,7 @@ namespace Microsoft.PowerPlatform.Dataverse.Client.Connector.OnPremises
private static List<IPolicyImportExtension> AddSecurityBindingToPolicyImporter(WsdlImporter importer)
{
List<IPolicyImportExtension> newExts = new List<IPolicyImportExtension>();
#if NETFRAMEWORK
KeyedByTypeCollection<IPolicyImportExtension> policyExtensions = importer.PolicyImportExtensions;
SecurityBindingElementImporter securityBindingElementImporter = policyExtensions.Find<SecurityBindingElementImporter>();
@ -564,18 +518,14 @@ namespace Microsoft.PowerPlatform.Dataverse.Client.Connector.OnPremises
newExts.AddRange(policyExtensions);
return newExts;
#else
newExts.Add(new AuthenticationPolicyImporter(new SecurityBindingElementImporter()));
return newExts;
//throw new PlatformNotSupportedException("Xrm.Sdk WSDL");
#endif
}
#endif
[SuppressMessage("Microsoft.Design", "CA1031:DoNotCatchGeneralExceptionTypes", Justification = "Need to catch any exception here and fail.")]
#if NETFRAMEWORK
[SuppressMessage("Microsoft.Design", "CA1031:DoNotCatchGeneralExceptionTypes", Justification = "Need to catch any exception here and fail.")]
private static bool TryRetrieveMetadata(MetadataExchangeClient mcli, Uri serviceEndpoint, ServiceEndpointMetadata serviceEndpointMetadata)
{
#if NETFRAMEWORK
bool rethrow = true;
try
{
@ -589,12 +539,10 @@ namespace Microsoft.PowerPlatform.Dataverse.Client.Connector.OnPremises
}
return rethrow;
#else
throw new PlatformNotSupportedException("Xrm.Sdk WSDL");
#endif
}
#endif
private static XmlQualifiedName GetPortTypeQName(ContractDescription contract)
private static XmlQualifiedName GetPortTypeQName(ContractDescription contract)
{
return new XmlQualifiedName(contract.Name, contract.Namespace);
}
@ -602,11 +550,11 @@ namespace Microsoft.PowerPlatform.Dataverse.Client.Connector.OnPremises
private static Collection<ContractDescription> CreateContractCollection(Type contract)
{
return new Collection<ContractDescription> { ContractDescription.GetContract(contract) };
}
}
#if NETFRAMEWORK
private static MetadataExchangeClient CreateMetadataClient(string scheme)
{
#if NETFRAMEWORK
WSHttpBinding mexBinding = null;
if (string.Compare(scheme, "https", StringComparison.OrdinalIgnoreCase) == 0)
@ -628,13 +576,10 @@ namespace Microsoft.PowerPlatform.Dataverse.Client.Connector.OnPremises
mcli.MaximumResolvedReferences = 100;
return mcli;
#else
return null;
//throw new PlatformNotSupportedException("Xrm.Sdk WSDL");
#endif
}
#endif
public static void ReplaceEndpointAddress(ServiceEndpoint endpoint, Uri adddress)
public static void ReplaceEndpointAddress(ServiceEndpoint endpoint, Uri adddress)
{
var addressBuilder = new EndpointAddressBuilder(endpoint.Address);
addressBuilder.Uri = adddress;

Просмотреть файл

@ -369,8 +369,8 @@ namespace Microsoft.PowerPlatform.Dataverse.Client
{
using (OperationContextScope scope = new OperationContextScope((IContextChannel)channel))
{
var ForceConsistencytHeader = new MessageHeader<string>("Strong").GetUntypedHeader(Utilities.RequestHeaders.FORCE_CONSISTENCY, "http://schemas.microsoft.com/xrm/2011/Contracts");
request.Headers.Add(ForceConsistencytHeader);
var ForceConsistencyHeader = new MessageHeader<string>("Strong").GetUntypedHeader(Utilities.RequestHeaders.FORCE_CONSISTENCY, "http://schemas.microsoft.com/xrm/2011/Contracts");
request.Headers.Add(ForceConsistencyHeader);
}
}
return null;

Просмотреть файл

@ -34,22 +34,31 @@
<PackageReference Include="Microsoft.Identity.Client" version="$(PackageVersion_MSAL)" />
<PackageReference Include="Microsoft.Rest.ClientRuntime" Version="$(PackageVersion_RestClientRuntime)" />
<PackageReference Include="Microsoft.VisualBasic" Version="10.3.0" />
<PackageReference Include="System.ServiceModel.Http" version="4.10.3" />
<PackageReference Include="System.ServiceModel.Primitives" version="4.10.3" />
<PackageReference Include="Newtonsoft.Json" Version="$(PackageVersion_Newtonsoft)" />
<PackageReference Include="System.Configuration.ConfigurationManager" Version="$(PackageVersion_SystemConfigurationConfigurationManager)" />
<!--<PackageReference Include="System.Security.Cryptography.Algorithms" Version="4.3.1" />
<PackageReference Include="System.Security.Cryptography.ProtectedData" Version="4.7.0" />
<PackageReference Include="System.Security.Permissions" Version="$(PackageVersion_SystemSecurityPermissions)" /> -->
<PackageReference Include="System.Text.Json" Version="$(PackageVersion_SystemTextJson)" />
<PackageReference Include="Microsoft.Identity.Client.Extensions.Msal" Version="$(PackageVersion_MSAL)" />
<PackageReference Include="Microsoft.Extensions.Caching.Memory" Version="$(PackageVersion_Microsoft_Extensions)" />
<!--<PackageReference Include="System.Drawing.Common" Version="5.0.3" />-->
<!-- explict add to deal with CVE-2021-24112 -->
</ItemGroup>
<Choose>
<When Condition="'$(TargetFramework)' == 'net6.0' or '$(TargetFramework)' == 'net8.0'">
<ItemGroup>
<PackageReference Include="System.ServiceModel.Http" version="$(PackageVersion_System_ServiceModel_PostNet6)" />
<PackageReference Include="System.ServiceModel.Primitives" version="$(PackageVersion_System_ServiceModel_PostNet6)"/>
</ItemGroup>
</When>
<Otherwise>
<ItemGroup>
<PackageReference Include="System.ServiceModel.Http" version="$(PackageVersion_System_ServiceModel_PreNet6)" />
<PackageReference Include="System.ServiceModel.Primitives" version="$(PackageVersion_System_ServiceModel_PreNet6)" />
</ItemGroup>
</Otherwise>
</Choose>
<ItemGroup Condition="'$(TargetFramework)' == 'net462' or '$(TargetFramework)' == 'net472' or '$(TargetFramework)' == 'net48'">
<Reference Include="System.Web" />
</ItemGroup>
</Project>

Просмотреть файл

@ -578,6 +578,12 @@ namespace Microsoft.PowerPlatform.Dataverse.Client
}
set
{
if (ConnectedOrgVersion == Version.Parse("9.0.0.0")) // Default setting found as this is a version number that is hard set during setup of connection. it is not possible to actually have an environment with this version number
{
//force update version
_logEntry.Log($"Requested current version from Dataverse, found: {OrganizationDetail.OrganizationVersion}");
}
if (_connectionSvc != null && Utilities.FeatureVersionMinimums.IsFeatureValidForEnviroment(_connectionSvc?.OrganizationVersion, Utilities.FeatureVersionMinimums.ForceConsistencySupported))
_connectionSvc.ForceServerCacheConsistency = value;
else
@ -1269,7 +1275,7 @@ namespace Microsoft.PowerPlatform.Dataverse.Client
_connectionSvc.RequestAdditionalHeadersAsync = GetCustomHeaders;
// Assign the log entry host to the ConnectionService engine
ConnectionService tempConnectService = null;
_connectionSvc.InternetProtocalToUse = useSsl ? "https" : "http";
_connectionSvc.InternetProtocolToUse = useSsl ? "https" : "http";
if (!_connectionSvc.DoLogin(out tempConnectService))
{
_logEntry.Log("Unable to Login to Dataverse", TraceEventType.Error);

Просмотреть файл

@ -1,7 +1,7 @@

Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio Version 16
VisualStudioVersion = 16.0.29609.76
# Visual Studio Version 17
VisualStudioVersion = 17.10.35027.167
MinimumVisualStudioVersion = 10.0.40219.1
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Microsoft.PowerPlatform.Dataverse.Client", "Client\Microsoft.PowerPlatform.Dataverse.Client.csproj", "{7303AAC5-BCEF-4BDB-B7D8-303490D506C6}"
EndProject
@ -11,12 +11,14 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "DataverseClient_Core_UnitTe
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Microsoft.PowerPlatform.Dataverse.Client.Dynamics", "Extensions\DynamicsExtension\Microsoft.PowerPlatform.Dataverse.Client.Dynamics.csproj", "{8CE32D7B-EA3D-4725-A270-9780D366EDB7}"
EndProject
#Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Microsoft.Dynamics.Sdk.Messages.Shell", "Extensions\Microsoft.Dynamics.Sdk.Messages\Microsoft.Dynamics.Sdk.Messages.Shell.csproj", "{503645DD-7711-40ED-8811-F06391F294AB}"
#EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "LiveTestsConsole", "UnitTests\LiveTestsConsole\LiveTestsConsole.csproj", "{5A1A4FFF-78F5-48A2-9AB0-3E507E938465}"
EndProject
#Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Microsoft.PowerPlatform.Dataverse.ServiceClientConverter", "Extensions\Microsoft.PowerPlatform.Dataverse.ServiceClientConverter\Microsoft.PowerPlatform.Dataverse.ServiceClientConverter.csproj", "{752E5268-3D99-485D-A31E-FC40AE9C0867}"
#EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "AzDevOps_ServiceConnection_Test", "UnitTests\AzDevOps_ServiceConnection_Test\AzDevOps_ServiceConnection_Test.csproj", "{581F17CF-C7DE-4147-8764-E6B4328C07E7}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Microsoft.PowerPlatform.Dataverse.Client.AzAuth", "Extensions\Microsoft.PowerPlatform.Dataverse.Client.AzAuth\Microsoft.PowerPlatform.Dataverse.Client.AzAuth.csproj", "{6A891168-EACF-4AC1-B081-ABA2FFF0DA7D}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Microsoft.PowerPlatform.Dataverse.Client.PowerShell", "PowerShell\Microsoft.PowerPlatform.Dataverse.Client.PowerShell\Microsoft.PowerPlatform.Dataverse.Client.PowerShell.csproj", "{849A9DED-F4C6-4CFE-BA25-696F6E100198}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
@ -35,18 +37,22 @@ Global
{8CE32D7B-EA3D-4725-A270-9780D366EDB7}.Debug|Any CPU.Build.0 = Debug|Any CPU
{8CE32D7B-EA3D-4725-A270-9780D366EDB7}.Release|Any CPU.ActiveCfg = Release|Any CPU
{8CE32D7B-EA3D-4725-A270-9780D366EDB7}.Release|Any CPU.Build.0 = Release|Any CPU
{503645DD-7711-40ED-8811-F06391F294AB}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{503645DD-7711-40ED-8811-F06391F294AB}.Debug|Any CPU.Build.0 = Debug|Any CPU
{503645DD-7711-40ED-8811-F06391F294AB}.Release|Any CPU.ActiveCfg = Release|Any CPU
{503645DD-7711-40ED-8811-F06391F294AB}.Release|Any CPU.Build.0 = Release|Any CPU
{5A1A4FFF-78F5-48A2-9AB0-3E507E938465}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{5A1A4FFF-78F5-48A2-9AB0-3E507E938465}.Debug|Any CPU.Build.0 = Debug|Any CPU
{5A1A4FFF-78F5-48A2-9AB0-3E507E938465}.Release|Any CPU.ActiveCfg = Release|Any CPU
{5A1A4FFF-78F5-48A2-9AB0-3E507E938465}.Release|Any CPU.Build.0 = Release|Any CPU
{752E5268-3D99-485D-A31E-FC40AE9C0867}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{752E5268-3D99-485D-A31E-FC40AE9C0867}.Debug|Any CPU.Build.0 = Debug|Any CPU
{752E5268-3D99-485D-A31E-FC40AE9C0867}.Release|Any CPU.ActiveCfg = Release|Any CPU
{752E5268-3D99-485D-A31E-FC40AE9C0867}.Release|Any CPU.Build.0 = Release|Any CPU
{581F17CF-C7DE-4147-8764-E6B4328C07E7}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{581F17CF-C7DE-4147-8764-E6B4328C07E7}.Debug|Any CPU.Build.0 = Debug|Any CPU
{581F17CF-C7DE-4147-8764-E6B4328C07E7}.Release|Any CPU.ActiveCfg = Release|Any CPU
{581F17CF-C7DE-4147-8764-E6B4328C07E7}.Release|Any CPU.Build.0 = Release|Any CPU
{6A891168-EACF-4AC1-B081-ABA2FFF0DA7D}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{6A891168-EACF-4AC1-B081-ABA2FFF0DA7D}.Debug|Any CPU.Build.0 = Debug|Any CPU
{6A891168-EACF-4AC1-B081-ABA2FFF0DA7D}.Release|Any CPU.ActiveCfg = Release|Any CPU
{6A891168-EACF-4AC1-B081-ABA2FFF0DA7D}.Release|Any CPU.Build.0 = Release|Any CPU
{849A9DED-F4C6-4CFE-BA25-696F6E100198}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{849A9DED-F4C6-4CFE-BA25-696F6E100198}.Debug|Any CPU.Build.0 = Debug|Any CPU
{849A9DED-F4C6-4CFE-BA25-696F6E100198}.Release|Any CPU.ActiveCfg = Release|Any CPU
{849A9DED-F4C6-4CFE-BA25-696F6E100198}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
@ -54,6 +60,7 @@ Global
GlobalSection(NestedProjects) = preSolution
{F85F6B93-D17D-4CAE-9B2F-D293BE73C700} = {CD32538C-E929-42F9-A936-5550427E2CD5}
{5A1A4FFF-78F5-48A2-9AB0-3E507E938465} = {CD32538C-E929-42F9-A936-5550427E2CD5}
{581F17CF-C7DE-4147-8764-E6B4328C07E7} = {CD32538C-E929-42F9-A936-5550427E2CD5}
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
SolutionGuid = {EA6D26FC-C065-4849-959E-1EF7FC013AF2}

Просмотреть файл

@ -23,7 +23,11 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Microsoft.PowerPlatform.Dat
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Microsoft.PowerPlatform.Dataverse.WebResourceUtility", "WebResourceUtility\Microsoft.PowerPlatform.Dataverse.WebResourceUtility.csproj", "{FDFD6B7F-A925-40EE-98DC-2E06C1D1E3B6}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Microsoft.PowerPlatform.Dataverse.Client.AzAuth", "Extensions\Microsoft.PowerPlatform.Dataverse.Client.AzAuth\Microsoft.PowerPlatform.Dataverse.Client.AzAuth.csproj", "{618D52B7-4CE7-402F-972B-E381C1C28299}"
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Microsoft.PowerPlatform.Dataverse.Client.AzAuth", "Extensions\Microsoft.PowerPlatform.Dataverse.Client.AzAuth\Microsoft.PowerPlatform.Dataverse.Client.AzAuth.csproj", "{618D52B7-4CE7-402F-972B-E381C1C28299}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "AzDevOps_ServiceConnection_Test", "UnitTests\AzDevOps_ServiceConnection_Test\AzDevOps_ServiceConnection_Test.csproj", "{581F17CF-C7DE-4147-8764-E6B4328C07E7}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Microsoft.PowerPlatform.Dataverse.Client.PowerShell", "PowerShell\Microsoft.PowerPlatform.Dataverse.Client.PowerShell\Microsoft.PowerPlatform.Dataverse.Client.PowerShell.csproj", "{8FD12028-BBEF-448B-BD43-E352386149DD}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
@ -143,6 +147,30 @@ Global
{618D52B7-4CE7-402F-972B-E381C1C28299}.Release|Any CPU.Build.0 = Release|Any CPU
{618D52B7-4CE7-402F-972B-E381C1C28299}.Release|x64.ActiveCfg = Release|Any CPU
{618D52B7-4CE7-402F-972B-E381C1C28299}.Release|x64.Build.0 = Release|Any CPU
{581F17CF-C7DE-4147-8764-E6B4328C07E7}.CRMINTERNAL|Any CPU.ActiveCfg = Debug|Any CPU
{581F17CF-C7DE-4147-8764-E6B4328C07E7}.CRMINTERNAL|Any CPU.Build.0 = Debug|Any CPU
{581F17CF-C7DE-4147-8764-E6B4328C07E7}.CRMINTERNAL|x64.ActiveCfg = Debug|Any CPU
{581F17CF-C7DE-4147-8764-E6B4328C07E7}.CRMINTERNAL|x64.Build.0 = Debug|Any CPU
{581F17CF-C7DE-4147-8764-E6B4328C07E7}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{581F17CF-C7DE-4147-8764-E6B4328C07E7}.Debug|Any CPU.Build.0 = Debug|Any CPU
{581F17CF-C7DE-4147-8764-E6B4328C07E7}.Debug|x64.ActiveCfg = Debug|Any CPU
{581F17CF-C7DE-4147-8764-E6B4328C07E7}.Debug|x64.Build.0 = Debug|Any CPU
{581F17CF-C7DE-4147-8764-E6B4328C07E7}.Release|Any CPU.ActiveCfg = Release|Any CPU
{581F17CF-C7DE-4147-8764-E6B4328C07E7}.Release|Any CPU.Build.0 = Release|Any CPU
{581F17CF-C7DE-4147-8764-E6B4328C07E7}.Release|x64.ActiveCfg = Release|Any CPU
{581F17CF-C7DE-4147-8764-E6B4328C07E7}.Release|x64.Build.0 = Release|Any CPU
{8FD12028-BBEF-448B-BD43-E352386149DD}.CRMINTERNAL|Any CPU.ActiveCfg = Debug|Any CPU
{8FD12028-BBEF-448B-BD43-E352386149DD}.CRMINTERNAL|Any CPU.Build.0 = Debug|Any CPU
{8FD12028-BBEF-448B-BD43-E352386149DD}.CRMINTERNAL|x64.ActiveCfg = Debug|Any CPU
{8FD12028-BBEF-448B-BD43-E352386149DD}.CRMINTERNAL|x64.Build.0 = Debug|Any CPU
{8FD12028-BBEF-448B-BD43-E352386149DD}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{8FD12028-BBEF-448B-BD43-E352386149DD}.Debug|Any CPU.Build.0 = Debug|Any CPU
{8FD12028-BBEF-448B-BD43-E352386149DD}.Debug|x64.ActiveCfg = Debug|Any CPU
{8FD12028-BBEF-448B-BD43-E352386149DD}.Debug|x64.Build.0 = Debug|Any CPU
{8FD12028-BBEF-448B-BD43-E352386149DD}.Release|Any CPU.ActiveCfg = Release|Any CPU
{8FD12028-BBEF-448B-BD43-E352386149DD}.Release|Any CPU.Build.0 = Release|Any CPU
{8FD12028-BBEF-448B-BD43-E352386149DD}.Release|x64.ActiveCfg = Release|Any CPU
{8FD12028-BBEF-448B-BD43-E352386149DD}.Release|x64.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
@ -151,6 +179,7 @@ Global
{F85F6B93-D17D-4CAE-9B2F-D293BE73C700} = {CD32538C-E929-42F9-A936-5550427E2CD5}
{5A1A4FFF-78F5-48A2-9AB0-3E507E938465} = {CD32538C-E929-42F9-A936-5550427E2CD5}
{E24CC0FA-4686-448E-A9AC-7A2B58D07FF6} = {01915F6D-79FF-4118-9EAD-2470351C8035}
{581F17CF-C7DE-4147-8764-E6B4328C07E7} = {CD32538C-E929-42F9-A936-5550427E2CD5}
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
SolutionGuid = {EA6D26FC-C065-4849-959E-1EF7FC013AF2}

Просмотреть файл

@ -108,8 +108,11 @@ namespace Microsoft.PowerPlatform.Dataverse.Client
if (_cacheList.ContainsKey(instanceUri))
{
accessToken = _cacheList[instanceUri];
if (accessToken.HasValue && accessToken.Value.ExpiresOn < DateTimeOffset.Now.Subtract(TimeSpan.FromSeconds(30)))
if (accessToken.HasValue && accessToken.Value.ExpiresOn < DateTimeOffset.UtcNow.Subtract(TimeSpan.FromSeconds(30)))
{
accessToken = null; // flush the access token if it is about to expire.
_cacheList.Remove(instanceUri);
}
}
if ( accessToken == null)
@ -137,22 +140,25 @@ namespace Microsoft.PowerPlatform.Dataverse.Client
return accessToken.Value.Token;
}
private string[] ResolveScopesList(Uri instanceUrl , Uri resource = null)
/// <summary>
/// gets or creates the scope list for the current instance.
/// </summary>
/// <param name="instanceUrl"></param>
/// <param name="resource"></param>
/// <returns></returns>
/// <exception cref="ArgumentNullException"></exception>
private string[] ResolveScopesList(Uri instanceUrl, Uri resource = null)
{
_scopesList ??= new Dictionary<Uri, List<string>>();
if ( _scopesList.ContainsKey(instanceUrl))
{
return _scopesList[instanceUrl].ToArray();
}
if (_scopesList.TryGetValue(instanceUrl, out List<string> foundList))
return foundList.ToArray();
if (resource == null)
{
throw new ArgumentNullException("Resource URI is required");
}
else
{
_scopesList.Add(instanceUrl, new List<string> { $"{resource}.default" });
return _scopesList[instanceUrl].ToArray();
}
_scopesList.Add(instanceUrl, new List<string> { $"{resource}.default" });
return _scopesList[instanceUrl].ToArray();
}
/// <summary>

Просмотреть файл

@ -0,0 +1,189 @@
using Azure.Core;
using Azure.Identity;
using Microsoft.Extensions.Logging;
using System;
using System.Collections.Generic;
using Microsoft.PowerPlatform.Dataverse.Client.Model;
using System.Diagnostics;
using System.Threading.Tasks;
namespace Microsoft.PowerPlatform.Dataverse.Client
{
/// <summary>
/// Auth class that will create a Workload Identity based authentication for Dataverse Service Client using the specified Azure DevOps Service Connection.
/// </summary>
public class AzPipelineFederatedIdentityAuth
{
private AzurePipelinesCredential _pipelineCredential;
private AzurePipelinesCredentialOptions _credentialOptions;
private readonly bool _autoResolveAuthorityAndTenant;
private Dictionary<Uri, List<string>> _scopesList;
private Dictionary<Uri, AccessToken?> _cacheList;
private ILogger _logger;
private string _tenantId;
private string _clientId;
private string _serviceConnectionId;
private string _systemAccessTokenEnvVarName;
/// <summary>
/// Creates a new instance of the ServiceClient class using the AzDevOps Service Connection
/// </summary>
/// <param name="tenantId">TenantId for the service connection</param>
/// <param name="clientId">ClientId for the service connection</param>
/// <param name="serviceConnectionId">Service Connection Id of AzDevOps ServiceConnection configured for workload identity</param>
/// <param name="connectionOptions">Dataverse ServiceClient Connection Options</param>
/// <param name="configurationOptions">Dataverse ServiceClient Configuration Options. Default = null</param>
/// <param name="systemAccessTokenEnvVarName">Environment Variable that has the current AzDevOps System Access Token. Default=SYSTEM_ACCESSTOKEN</param>
/// <returns></returns>
/// <exception cref="ArgumentException"></exception>
public static ServiceClient CreateServiceClient(
string tenantId,
string clientId,
string serviceConnectionId,
ConnectionOptions connectionOptions,
ConfigurationOptions configurationOptions = null,
string systemAccessTokenEnvVarName = "SYSTEM_ACCESSTOKEN")
{
if (connectionOptions == null)
{
throw new ArgumentException("ConnectionOptions are required");
}
if (connectionOptions.ServiceUri == null)
{
throw new ArgumentException("ConnectionOptions.ServiceUri is required");
}
connectionOptions.AuthenticationType = AuthenticationType.ExternalTokenManagement; // force the authentication type to be external token management.
AzPipelineFederatedIdentityAuth azAuth = new AzPipelineFederatedIdentityAuth( tenantId, clientId, serviceConnectionId, systemAccessTokenEnvVarName, true, connectionOptions.Logger);
connectionOptions.AccessTokenProviderFunctionAsync = azAuth.GetAccessToken;
return new ServiceClient(connectionOptions, false, configurationOptions);
}
/// <summary>
/// Creates an instance of the AzPipelineFederatedIdentityAuth class
/// </summary>
/// <param name="autoResolveAuthorityAndTenant">Should resolve Dataverse authority and resource from url.</param>
/// <param name="serviceConnectionId">Service Connection Id of AzDevOps ServiceConnection configured for workload identity</param>
/// <param name="clientId">ClientId for the service connection</param>
/// <param name="tenantId">TenantId for the service connection</param>
/// <param name="SystemAccessTokenEnvVarName">Environment Variable that has the current AzDevOps System Access Token. Default=SYSTEM_ACCESSTOKEN</param>
/// <param name="logger">ILogger instance</param>
public AzPipelineFederatedIdentityAuth(string tenantId, string clientId, string serviceConnectionId, string SystemAccessTokenEnvVarName, bool autoResolveAuthorityAndTenant, ILogger logger = null)
{
_tenantId = tenantId;
_clientId = clientId;
_serviceConnectionId = serviceConnectionId;
_systemAccessTokenEnvVarName = SystemAccessTokenEnvVarName;
_autoResolveAuthorityAndTenant = autoResolveAuthorityAndTenant;
_logger = logger;
}
/// <summary>
/// Returns the current access token for the connected ServiceClient instance
/// </summary>
/// <param name="instanceUrl"></param>
/// <returns></returns>
public async Task<string> GetAccessToken(string instanceUrl)
{
if (!Uri.IsWellFormedUriString(instanceUrl, UriKind.RelativeOrAbsolute))
{
throw new ArgumentException("Invalid instance URL");
}
AccessToken? accessToken = null;
Uri instanceUri = new Uri(instanceUrl);
if (_pipelineCredential == null)
{
Uri resourceUri = await InitializeCredentials(instanceUri).ConfigureAwait(false);
ResolveScopesList(instanceUri, resourceUri);
}
// Get or create existing token.
_cacheList ??= new Dictionary<Uri, AccessToken?>();
if (_cacheList.ContainsKey(instanceUri))
{
accessToken = _cacheList[instanceUri];
if (accessToken.HasValue && accessToken.Value.ExpiresOn < DateTimeOffset.UtcNow.Subtract(TimeSpan.FromSeconds(30)))
{
accessToken = null; // flush the access token if it is about to expire.
_cacheList.Remove(instanceUri);
}
}
if (accessToken == null)
{
Stopwatch sw = Stopwatch.StartNew();
_logger.LogDebug("Getting new access token for {0}", instanceUri);
accessToken = await _pipelineCredential.GetTokenAsync(new TokenRequestContext(ResolveScopesList(instanceUri)), System.Threading.CancellationToken.None).ConfigureAwait(false);
_logger.LogDebug("Access token retrieved in {0}ms", sw.ElapsedMilliseconds);
sw.Stop();
if (_cacheList.ContainsKey(instanceUri))
{
_cacheList[instanceUri] = accessToken;
}
else
{
_cacheList.Add(instanceUri, accessToken);
}
}
if (accessToken == null)
{
throw new Exception("Failed to retrieve access token");
}
return accessToken.Value.Token;
}
private string[] ResolveScopesList(Uri instanceUrl, Uri resource = null)
{
_scopesList ??= new Dictionary<Uri, List<string>>();
if (_scopesList.TryGetValue(instanceUrl, out List<string> foundList))
return foundList.ToArray();
if (resource == null)
throw new ArgumentNullException("Resource URI is required");
_scopesList.Add(instanceUrl, new List<string> { $"{resource}.default" });
return _scopesList[instanceUrl].ToArray();
}
/// <summary>
/// Initialize the credentials for the current instance
/// </summary>
/// <param name="instanceUrl"></param>
/// <returns></returns>
private async Task<Uri> InitializeCredentials(Uri instanceUrl)
{
_logger.LogDebug("Initializing credentials for {0}", instanceUrl);
Stopwatch sw = Stopwatch.StartNew();
Uri resourceUri = null;
_credentialOptions ??= new AzurePipelinesCredentialOptions();
if (_autoResolveAuthorityAndTenant)
{
_logger.LogDebug("Resolving authority and tenant for {0}", instanceUrl);
using var httpClient = new System.Net.Http.HttpClient();
Auth.AuthorityResolver authorityResolver = new Auth.AuthorityResolver(httpClient);
var authDetails = await authorityResolver.ProbeForExpectedAuthentication(instanceUrl).ConfigureAwait(false);
resourceUri = authDetails.Resource;
_credentialOptions.AuthorityHost = authDetails.Authority;
//_credentialOptions.TenantId = authDetails.Authority.Segments[1].Replace("/", "");
_logger.LogDebug("Authority and tenant resolved in {0}ms", sw.ElapsedMilliseconds);
_logger.LogDebug("Initialize Creds - found authority with name " + (string.IsNullOrEmpty(authDetails.Authority.ToString()) ? "<Not Provided>" : authDetails.Authority.ToString()));
_logger.LogDebug("Initialize Creds - found resource with name " + (string.IsNullOrEmpty(authDetails.Resource.ToString()) ? "<Not Provided>" : authDetails.Resource.ToString()));
//_logger.LogDebug("Initialize Creds - found tenantId " + (string.IsNullOrEmpty(_credentialOptions.TenantId) ? "<Not Provided>" : _credentialOptions.TenantId));
}
_pipelineCredential = new AzurePipelinesCredential(_tenantId, _clientId, _serviceConnectionId, Environment.GetEnvironmentVariable(_systemAccessTokenEnvVarName), _credentialOptions);
_logger.LogDebug("Credentials initialized in {0}ms", sw.ElapsedMilliseconds);
sw.Start();
return resourceUri;
}
}
}

Просмотреть файл

@ -0,0 +1,120 @@
#Build Drop Script
#Drops the files in the drop folder for the build.
[CmdletBinding(PositionalBinding=$true)]
param(
[string] $BuildSourcesDirectory ,
[string] $BuildConfiguration,
[string] $StagingDirectory,
[string] $ProjectRootDirectory,
[string] $SolutionName,
[bool] $RunFromVSBuild = $false,
[bool] $EnableDebug = $false
)
#BuildDrop for Microsoft.Xrm.OnlineManagementAPI solution
Write-Host ">>> ========================= Invoking BuildDrop.ps1 for $SolutionName ======================="
Write-Host ">>> BuildSourcesDirectory = $BuildSourcesDirectory"
Write-Host ">>> ProjectRootDirectory = $ProjectRootDirectory"
Write-Host ">>> SolutionName = $SolutionName"
Write-Host ">>> BuildConfiguration = $BuildConfiguration"
Write-Host ">>> StagingDirectory = $StagingDirectory"
Write-Host ">>> RunFromVSBuild = $RunFromVSBuild"
Write-Host ">>> Write Debug Info = $EnableDebug"
if ( [System.String]::IsNullOrEmpty($StagingDirectory) -eq $true)
{
#Running local build
$StagingDirectory = $BuildSourcesDirectory
}
if ( $RunFromVSBuild -eq $false )
{
$dropFolderName = "Drop"
}
else
{
$dropFolderName = "Drop"
}
$SolutionName = "Microsoft.PowerPlatform.Dataverse.Client.PowerShell";
#Create path for drop directory
#format for Local Build: Root/Drop/Buildconfig/SolutionName/Bins.
#format for Server Build: Root/Buildconfig/SolutionName/Bins.
if($RunFromVSBuild -eq $false)
{
#$dropPath = [System.IO.Path]::Combine($dropFolderName , $SolutionName )
$dropPath = [System.IO.Path]::Combine($dropFolderName )
}
else
{
$dropPath = [System.IO.Path]::Combine($StagingDirectory , $dropFolderName , $BuildConfiguration)
}
Write-Host ">>> Output path is $dropPath"
## Assembly Out directory
if($RunFromVSBuild -eq $false)
{
$BinsDirectory = $StagingDirectory #[System.IO.Path]::Combine($ProjectRootDirectory , $SolutionName , "bin" , $BuildConfiguration )
}
else
{
$BinsDirectory = [System.IO.Path]::Combine($BuildSourcesDirectory , "bin" , $BuildConfiguration, "DataverseClient" , "net6.0" )
}
## Copying PowerShell Module out only.
Write-Host ">>> BINS path is $BinsDirectory"
# Setup Module Drop Directory Key
if($RunFromVSBuild -eq $false)
{
$PowerShellModuleFilesDirectory = [System.IO.Path]::Combine($dropPath , $SolutionName)
}
else {
$PowerShellModuleFilesDirectory = [System.IO.Path]::Combine($dropPath , $SolutionName)
}
Write-Host ">>> Module Drop path is $PowerShellModuleFilesDirectory"
## ############## Project or Solution COPY code here. ############ ##
#create the Root Drop directory
New-Item -ItemType directory -Force $dropPath
##create subfolder for Management Powershell
New-Item -ItemType Directory -Force $PowerShellModuleFilesDirectory
if ( [System.IO.Directory]::Exists($PowerShellModuleFilesDirectory) -eq $true )
{
#copy launcher.
#Copy-Item -Path "$BinsDirectory\*" -Destination $dropFolderName -Include 'RegisterXrmTooling.ps1' -Force
Robocopy $BinsDirectory $dropPath 'RegisterServiceClient.ps1' /XX
if ($lastexitcode -le 7) {
Write-Host ">>> ExitCode = " $lastexitcode
$lastexitcode = 0
}
# remove anything from Target so as to not upset robocopy
#copy modules.
Robocopy ([System.IO.Path]::Combine($BinsDirectory , 'Microsoft.PowerPlatform.Dataverse.Client.PowerShell')) $PowerShellModuleFilesDirectory *.* /XX
if ($lastexitcode -le 7) {
Write-Host ">>> ExitCode = " $lastexitcode
$lastexitcode = 0
}
#copy DLL's
Robocopy $BinsDirectory $PowerShellModuleFilesDirectory *.dll
if ($lastexitcode -le 7)
{
Write-Host ">>> ExitCode1 = " $lastexitcode
$lastexitcode = 0
}
#copy Help
Robocopy $BinsDirectory $PowerShellModuleFilesDirectory *.dll-help.xml
if ($lastexitcode -le 7)
{
Write-Host ">>> ExitCode1 = " $lastexitcode
$lastexitcode = 0
Exit 0
}
}

Просмотреть файл

@ -0,0 +1,159 @@
// Ignore Spelling: Dataverse
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.Logging;
using System.Management.Automation;
using System.Reflection;
namespace Microsoft.PowerPlatform.Dataverse.Client.PowerShell.Commands
{
public class BaseCmdLet : PSCmdlet
{
#region Vars
///// <summary>
///// file Writer Link
///// </summary>
//private Microsoft.Xrm.Tooling.Connector.DynamicsFileLogTraceListener commonFileWriter = null;
/// <summary>
/// when present and populated, this will write the logs to the directory specified. loges are written only when -verbose is chosen.
/// </summary>
[Parameter(Mandatory = false, ValueFromPipelineByPropertyName = true)]
public string LogWriteDirectory { get; set; } = string.Empty;
//#if DEBUG
// private System.Diagnostics.DefaultTraceListener commonConsoleListener = null;
//#endif
#endregion
internal ILogger CreateILogger()
{
var ConfigFileLocation = Path.Combine(Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location) ?? "", "appsettings.json");
IConfiguration config = new ConfigurationBuilder()
.AddJsonFile(ConfigFileLocation, optional: true, reloadOnChange: true)
.Build();
ILoggerFactory loggerFactory = LoggerFactory.Create(builder =>
builder.AddConsole(options =>
{
#pragma warning disable CS0618 // Type or member is obsolete
options.IncludeScopes = true;
options.TimestampFormat = "hh:mm:ss ";
#pragma warning restore CS0618 // Type or member is obsolete
})
.AddConfiguration(config.GetSection("Logging")));
return loggerFactory.CreateLogger<Microsoft.PowerPlatform.Dataverse.Client.ServiceClient>();
}
/// <summary>
/// Determines if its necessary to enable tracing.
/// </summary>
internal void SetDiagnosticsMode()
{
if (this.MyInvocation.BoundParameters.ContainsKey("verbose") && (SwitchParameter)this.MyInvocation.BoundParameters["verbose"])
{
// CrmConnectControl.Utility.TraceControlSettings.TraceLevel = System.Diagnostics.SourceLevels.Verbose;
// Connector.TraceControlSettings.TraceLevel = System.Diagnostics.SourceLevels.Verbose;
// if (CrmConnectControl.Utility.TraceControlSettings.TraceLevel != System.Diagnostics.SourceLevels.Off)
// {
// // Create a common TraceFile Writer.
// if (commonFileWriter == null)
// {
// if (!string.IsNullOrEmpty(LogWriteDirectory) && System.IO.Directory.Exists(LogWriteDirectory))
// {
// commonFileWriter = new Connector.DynamicsFileLogTraceListener()
// {
// BaseFileName = "Microsoft.PowerPlatform.Dataverse.Client.PowerShell",
// Location = VisualBasic.Logging.LogFileLocation.Custom,
// CustomLocation = LogWriteDirectory
// };
// }
// else
// {
// commonFileWriter = new Connector.DynamicsFileLogTraceListener()
// {
// BaseFileName = "Microsoft.PowerPlatform.Dataverse.Client.PowerShell",
// Location = VisualBasic.Logging.LogFileLocation.LocalUserApplicationDirectory
// };
// }
// this.WriteVerbose(string.Format("Verbose output log file: '{0}'", commonFileWriter.FullLogFileName));
// CrmConnectControl.Utility.TraceControlSettings.AddTraceListener(commonFileWriter);
// Connector.TraceControlSettings.AddTraceListener(commonFileWriter);
// }
//#if DEBUG
// if ( commonConsoleListener == null )
// {
// commonConsoleListener = new System.Diagnostics.DefaultTraceListener();
// CrmConnectControl.Utility.TraceControlSettings.AddTraceListener(commonFileWriter);
// Connector.TraceControlSettings.AddTraceListener(commonFileWriter);
// }
//#endif
// }
}
else
if (this.MyInvocation.BoundParameters.ContainsKey("verbose") && !(SwitchParameter)this.MyInvocation.BoundParameters["verbose"])
{
//// forces it off.
//CrmConnectControl.Utility.TraceControlSettings.TraceLevel = System.Diagnostics.SourceLevels.Off;
//Connector.TraceControlSettings.TraceLevel = System.Diagnostics.SourceLevels.Off;
}
}
/// <summary>
/// Cleans up open TraceWriters
/// </summary>
internal void CleanUpDiagnosticsMode()
{
//CrmConnectControl.Utility.TraceControlSettings.CloseListeners();
//Connector.TraceControlSettings.CloseListeners();
}
}
#region Threading Support Class
/// <summary>
/// Type of write to use.
/// </summary>
internal enum WriteInfoType
{
Warning = 0,
Verbose,
Debug
}
/// <summary>
/// holder class to signal handling to the cmdlet adapter writer.
/// </summary>
internal class GeneralWriteInfo
{
/// <summary>
/// Warning message to write.
/// </summary>
public string Message { get; set; }
/// <summary>
/// Type of Message in this class.
/// </summary>
public WriteInfoType MessageType { get; set; }
/// <summary>
/// Warning Message to write.
/// </summary>
/// <param name="warningMessage"></param>
public GeneralWriteInfo(string warningMessage, WriteInfoType messageType)
{
Message = warningMessage;
MessageType = messageType;
}
}
#endregion
}

Просмотреть файл

@ -0,0 +1,224 @@
// Ignore Spelling: Dataverse Auth queryfor Orgs
using System.Management.Automation;
using System.Globalization;
using Microsoft.Extensions.Logging;
using Microsoft.PowerPlatform.Dataverse.Client.Model;
namespace Microsoft.PowerPlatform.Dataverse.Client.PowerShell.Commands
{
public class CommonAuth : BaseCmdLet
{
#region Vars
/// <summary>
/// Connection timeout setting for CRM connection.
/// </summary>
private int maxcrmconnectiontimeoutminutes = -1;
/// <summary>
/// Connection string to use when connecting to CRM
/// </summary>
internal string connectionString = string.Empty;
/// <summary>
/// Url of organization to connect too.
/// </summary>
internal Uri? orgUrlToUse;
/// <summary>
/// Tenant ID for FIC
/// </summary>
internal Guid tenantId;
/// <summary>
/// FIC Client Id
/// </summary>
internal Guid clientId;
/// <summary>
/// Service Connection Id
/// </summary>
internal Guid serviceConnectionId;
/// <summary>
/// Environment AccessToken KeyName.
/// </summary>
internal string accessTokenEnvKeyName = string.Empty;
/// <summary>
/// CrmSvcConnection
/// </summary>
protected ServiceClient? serviceClient = null;
///// <summary>
///// Progress Record.
///// </summary>
//private ProgressRecord? connProgress = null;
/// <summary>
/// Error Record if any.
/// </summary>
private ErrorRecord? errorRecord = null;
/// <summary>
/// set when querying for orgs.
/// </summary>
public bool queryforOrgs = false;
/// <summary>
/// PowerShell MultiThreaded Adapter.
/// </summary>
//private PowerShellAdapter? adapter = null;
/// <summary>
/// Percentage completed.
/// </summary>
//private int percentCmp = 0;
#endregion
#region Properties.
/// <summary>
/// The following is the definition of the input parameter "MaxConnectionTimeOutMinutes".
/// User credential used to login to CRM
/// </summary>
[Parameter(Position = 20, ValueFromPipeline = true, ValueFromPipelineByPropertyName = true)]
public int MaxConnectionTimeOutMinutes
{
get { return this.maxcrmconnectiontimeoutminutes; }
set { this.maxcrmconnectiontimeoutminutes = value; }
}
#endregion
public CommonAuth()
{
// Auto Add TLS 1.2 support which is required.
System.Net.ServicePointManager.SecurityProtocol = System.Net.SecurityProtocolType.Tls12;
}
/// <summary>
/// Get Orgs.
/// </summary>
public void ExecuteGetOrgs()
{
ExecuteAuth();
if (errorRecord != null)
WriteError(errorRecord);
}
/// <summary>
/// Run Auth.
/// </summary>
public void ExecuteAuth()
{
RunAuth();
if (!queryforOrgs && errorRecord != null)
WriteError(errorRecord);
}
/// <summary>
/// Authenticate with Dataverse.
/// </summary>
private void RunAuth()
{
if (serviceConnectionId != null && serviceConnectionId != Guid.Empty)
{
serviceClient = AzPipelineFederatedIdentityAuth.CreateServiceClient(
tenantId.ToString(),
clientId.ToString(),
serviceConnectionId.ToString(),
new ConnectionOptions()
{
ServiceUri = orgUrlToUse,
Logger = CreateILogger()
}
);
}
else if (!string.IsNullOrEmpty(connectionString))
{
// Connection string is present.
ServiceClient localServiceClient = new ServiceClient(connectionString, CreateILogger());
if (localServiceClient != null && localServiceClient.IsReady)
serviceClient = localServiceClient;
else
{
if (!string.IsNullOrEmpty(localServiceClient?.LastError) || localServiceClient?.LastException != null)
{
errorRecord = new ErrorRecord(new Exception(string.Format(CultureInfo.InvariantCulture, "Failed to connect to Dataverse: {0}", localServiceClient.LastError), localServiceClient.LastException), "-10", ErrorCategory.PermissionDenied, null);
WriteError(errorRecord);
serviceClient = null;
}
}
}
else
{
// No connection string.
errorRecord = new ErrorRecord(new Exception("Connection string is required to connect to Dataverse"), "-1", ErrorCategory.InvalidArgument, null);
WriteError(errorRecord);
serviceClient = null;
}
// Set connection timeout if required.
if (serviceClient != null && MaxConnectionTimeOutMinutes != -1)
{
WriteVerbose(string.Format(CultureInfo.InstalledUICulture, "Dataverse Connection Timeout set to {0} Minutes", MaxConnectionTimeOutMinutes));
SetConnectionTimeoutValues(new TimeSpan(0, MaxConnectionTimeOutMinutes, 0));
}
else
if (serviceClient != null)
WriteVerbose(string.Format(CultureInfo.InstalledUICulture, "Dataverse Connection Timeout is set to {0} Minutes", GetConnectionTimeoutValues().Minutes));
}
#region Private classes.
/// <summary>
/// Updates the timeout value to extend the amount of item that a request will wait.
/// </summary>
public void SetConnectionTimeoutValues(TimeSpan TimeOutToSet)
{
ServiceClient.MaxConnectionTimeout = TimeOutToSet;
}
/// <summary>
/// Gets the current connection time out value.
/// </summary>
/// <returns></returns>
private TimeSpan GetConnectionTimeoutValues()
{
return ServiceClient.MaxConnectionTimeout;
}
#endregion
}
#region Extension Methods for SecureString
///// <summary>
///// Adds a extension to Secure string
///// </summary>
//internal static class SecureStringExtensions
//{
// /// <summary>
// /// DeCrypt a Secure password
// /// </summary>
// /// <param name="value"></param>
// /// <returns></returns>
// public static string ToUnsecureString(this SecureString value)
// {
// if (null == value)
// throw new ArgumentNullException("value");
// // Get a pointer to the secure string memory data.
// IntPtr ptr = Marshal.SecureStringToGlobalAllocUnicode(value);
// try
// {
// // DeCrypt
// return Marshal.PtrToStringUni(ptr);
// }
// finally
// {
// // release the pointer.
// Marshal.ZeroFreeGlobalAllocUnicode(ptr);
// }
// }
//}
#endregion
}

Просмотреть файл

@ -0,0 +1,134 @@
// Ignore Spelling: Dataverse
using System.Management.Automation;
using System.Reflection;
namespace Microsoft.PowerPlatform.Dataverse.Client.PowerShell.Commands
{
/// <summary>
/// this will establish a CRM connection
/// </summary>
[Cmdlet(VerbsCommon.Get, "PowerPlatformConnection")]
public class GetPowerPlatformConnection : CommonAuth
{
/// <summary>
/// Tenant Id of the FIC
/// </summary>
[Parameter(Mandatory = true, Position = 1, ValueFromPipeline = true, ValueFromPipelineByPropertyName = true, ParameterSetName = "FIC")]
public Guid TenantId
{
get { return base.tenantId; }
set { base.tenantId = value; }
}
/// <summary>
/// Client Id of the FIC
/// </summary>
[Parameter(Mandatory = true, Position = 2, ValueFromPipeline = true, ValueFromPipelineByPropertyName = true, ParameterSetName = "FIC")]
public Guid ClientId
{
get { return base.clientId; }
set { base.clientId = value; }
}
/// <summary>
/// Service Connection Id of the FIC
/// </summary>
[Parameter(Mandatory = true, Position = 3, ValueFromPipeline = true, ValueFromPipelineByPropertyName = true, ParameterSetName = "FIC")]
public Guid ServiceConnectionId
{
get { return base.serviceConnectionId; }
set { base.serviceConnectionId = value; }
}
/// <summary>
/// OrganizationUrl of the FIC
/// </summary>
[Parameter(Mandatory = true, Position = 4, ValueFromPipeline = true, ValueFromPipelineByPropertyName = true, ParameterSetName = "FIC")]
public Uri? OrganizationUrl
{
get { return base.orgUrlToUse; }
set { base.orgUrlToUse = value; }
}
/// <summary>
/// Environment AccessToken KeyName.
/// </summary>
[Parameter(Mandatory = false , Position = 4, ValueFromPipeline = true, ValueFromPipelineByPropertyName = true, ParameterSetName = "FIC")]
public string AccessTokenEnvKeyName
{
get { return base.accessTokenEnvKeyName; }
set { base.accessTokenEnvKeyName = value; }
}
/// <summary>
/// Used to set the connection string to connect to crm. all other connection elements are ignored when this string appears.
/// </summary>
[Parameter(Mandatory = true, Position = 1, ValueFromPipeline = true, ValueFromPipelineByPropertyName = true, ParameterSetName = "ConnectionStringOnly")]
public string ConnectionString
{
get { return base.connectionString; }
set { base.connectionString = value; }
}
/// <summary>
/// PreInitializion
/// </summary>
protected override void BeginProcessing()
{
base.queryforOrgs = false;
//string thisAssemblyPath = string.Empty;
//var AsmList = AppDomain.CurrentDomain.GetAssemblies();
//bool found = false;
//// Look in the assemblies for the resources file.
//foreach (Assembly asm in AsmList)
//{
// if (asm.FullName.ToLower().Contains(XamlResourceName))
// {
// found = true;
// break;
// }
//}
//if (System.IO.File.Exists(Assembly.GetExecutingAssembly().Location))
// thisAssemblyPath = Assembly.GetExecutingAssembly().Location;
//if (!found)
//{
// // Get the Direction Info object
// System.IO.DirectoryInfo d = new System.IO.DirectoryInfo(thisAssemblyPath);
// // Remove file name
// thisAssemblyPath = System.IO.Path.GetDirectoryName(thisAssemblyPath);
// // Load the assembly.
// if (System.IO.File.Exists(System.IO.Path.Combine(thisAssemblyPath, string.Format("{0}.dll", XamlResourceName))))
// Assembly.LoadFile(System.IO.Path.Combine(thisAssemblyPath, string.Format("{0}.dll", XamlResourceName)));
//}
base.BeginProcessing();
}
/// <summary>
/// ProcessRecord method.
/// </summary>
protected override void ProcessRecord()
{
try
{
base.SetDiagnosticsMode();
base.ExecuteAuth();
if (serviceClient != null)
WriteObject(serviceClient);
base.CleanUpDiagnosticsMode();
}
catch (Exception generalEx)
{
// General error write for something we don't understand going wrong.
WriteError(new ErrorRecord(generalEx, "-9", ErrorCategory.SyntaxError, null));
}
}
}//End Class
}//End namespace

Просмотреть файл

@ -0,0 +1,110 @@
// Ignore Spelling: Dataverse cmdlet
using System.Management.Automation;
namespace Microsoft.PowerPlatform.Dataverse.Client.PowerShell.Commands
{
/// <summary>
/// Adapter Class
/// </summary>
internal class PowerShellAdapter
{
private ManualResetEvent queueEvent = new ManualResetEvent(false);
#region Parameters
private Cmdlet cmdlet { get; set; }
private Queue<object> queue { get; set; }
private object LockToken { get; set; }
public State state;
public ErrorRecord? fatalErrorRecord;
#endregion
/// <summary>
/// Ctor
/// </summary>
/// <param name="cmdlet">cmdlet</param>
public PowerShellAdapter(Cmdlet cmdlet)
{
this.cmdlet = cmdlet;
this.LockToken = new object();
this.queue = new Queue<object>();
this.state = State.Running;
fatalErrorRecord = null;
}
#region Methods
/// <summary>
/// Listener Method
/// </summary>
/// <param name="timeout">Time after which Operation will declared as Timed Out</param>
public void Listen(TimeSpan timeout)
{
DateTime dateTime = DateTime.UtcNow;
dateTime = dateTime.Add(timeout);
while (state == State.Running || queue.Count > 0)
{
queueEvent.WaitOne(timeout);
while (queue.Count > 0)
{
var obj = queue.Dequeue();
if (obj is ErrorRecord)
{
cmdlet.WriteError((ErrorRecord)obj);
}
else if (obj is ProgressRecord)
{
cmdlet.WriteProgress((ProgressRecord)obj);
}
else if (obj is GeneralWriteInfo)
{
// General write info to the UX.
switch (((GeneralWriteInfo)obj).MessageType)
{
case WriteInfoType.Warning:
cmdlet.WriteWarning(((GeneralWriteInfo)obj).Message);
break;
case WriteInfoType.Verbose:
cmdlet.WriteVerbose(((GeneralWriteInfo)obj).Message);
break;
default:
cmdlet.WriteDebug(((GeneralWriteInfo)obj).Message);
break;
}
}
}
if (DateTime.UtcNow > dateTime)
{
cmdlet.ThrowTerminatingError(new ErrorRecord(new Exception("TIMED_OUT"), "1", ErrorCategory.OperationTimeout, this));
}
Thread.Sleep(100);
}
if (state == State.FinishedWithError)
{
cmdlet.ThrowTerminatingError(fatalErrorRecord);
}
}
public void Write(object obj)
{
lock (LockToken)
{
queue.Enqueue(obj);
queueEvent.Set();
}
}
#endregion
}
/// <summary>
/// Determines the State of the Running Import
/// </summary>
internal enum State
{
Running,
FinishedWithError,
FinishedWithSuccess,
TimedOut
};
}

Просмотреть файл

@ -0,0 +1,50 @@
<#
This script will create the catalog file from the signed assembly in a PowerShell command shell and drops the files in the drop folder for the signing. .
#>
[CmdletBinding(PositionalBinding=$true)]
param(
[string] $BuildSourcesDirectory ,
[string] $BuildConfiguration,
[string] $StagingDirectory,
[bool] $RunFromVSBuild = $false,
[bool] $EnableDebug = $false
)
$SolutionName = "Microsoft.PowerPlatform.Dataverse.Client.PowerShell"
Write-Host ">>> ========================= Invoking GenerateCatalogFile.ps1 for $SolutionName ======================="
Write-Host ">>> BuildSourcesDirectory = $BuildSourcesDirectory"
Write-Host ">>> SolutionName = $SolutionName"
Write-Host ">>> BuildConfiguration = $BuildConfiguration"
Write-Host ">>> StagingDirectory = $StagingDirectory"
Write-Host ">>> RunFromVSBuild = $RunFromVSBuild"
Write-Host ">>> Write Debug Info = $EnableDebug"
Write-Host ">>> VERSION INFO:"
$PSVersionTable
Write-Host ">>> LOADING Microsoft.Powershell.Security"
Import-Module Microsoft.Powershell.Security -Verbose
if ( [System.String]::IsNullOrEmpty($StagingDirectory) -eq $true)
{
#Running local build
$StagingDirectory = $BuildSourcesDirectory
}
#Create path for drop directory
$dropFolderName = "Drop"
$dropPath = [System.IO.Path]::Combine($StagingDirectory , $dropFolderName, $SolutionName)
Write-Host ">>> Output path is $dropPath"
$catalogFilePath = "$dropPath\Microsoft.PowerPlatform.Dataverse.Client.PowerShell.cat"
Write-Host ">>> CatalogFile path is $catalogFilePath"
$isExists = Get-Item -LiteralPath "$catalogFilePath" -ErrorAction SilentlyContinue
if ($null -ne $isExists)
{
Remove-Item $catalogFilePath -Force
}
New-FileCatalog -Path "$dropPath" -CatalogFilePath $catalogFilePath -CatalogVersion 1.0

Просмотреть файл

@ -0,0 +1,62 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<LangVersion>latest</LangVersion>
<ComponentAreaName>DataverseClient</ComponentAreaName>
<SignAssembly>true</SignAssembly>
</PropertyGroup>
<Import Project="..\..\..\..\Build.Common.core.props" />
<PropertyGroup>
<ProjectDir Condition="'$(ProjectDir)' == '' ">$(MSBuildProjectDirectory)\</ProjectDir>
<CopyLocalLockFileAssemblies>true</CopyLocalLockFileAssemblies>
<TargetFrameworks>net6.0</TargetFrameworks>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="PowerShellStandard.Library" Version="5.1.1" />
<PackageReference Include="Microsoft.Extensions.Configuration.Json" Version="$(PackageVersion_Microsoft_Extensions)" />
<PackageReference Include="Microsoft.Extensions.Logging" Version="$(PackageVersion_Microsoft_Extensions)" />
<PackageReference Include="Microsoft.Extensions.Logging.Console" Version="$(PackageVersion_Microsoft_Extensions)" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\..\Client\Microsoft.PowerPlatform.Dataverse.Client.csproj" />
<ProjectReference Include="..\..\Extensions\Microsoft.PowerPlatform.Dataverse.Client.AzAuth\Microsoft.PowerPlatform.Dataverse.Client.AzAuth.csproj" />
</ItemGroup>
<ItemGroup>
<None Update="appsettings.json">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None>
<None Update="Microsoft.PowerPlatform.Dataverse.Client.PowerShell\Microsoft.PowerPlatform.Dataverse.Client.Connect.psm1">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None>
<None Update="Microsoft.PowerPlatform.Dataverse.Client.PowerShell\Microsoft.PowerPlatform.Dataverse.Client.Operations.psm1">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None>
<None Update="Microsoft.PowerPlatform.Dataverse.Client.PowerShell\Microsoft.PowerPlatform.Dataverse.Client.PowerShell.psd1">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None>
<None Update="Microsoft.PowerPlatform.Dataverse.Client.PowerShell\Microsoft.PowerPlatform.Dataverse.Client.PowerShell.psm1">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None>
<None Update="Microsoft.PowerPlatform.Dataverse.Client.PowerShell\UtilityFunctions.psm1">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None>
<None Update="RegisterServiceClient.ps1">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None>
<None Update="Start-Debug.ps1">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</None>
</ItemGroup>
<PropertyGroup>
<PostBuildEvent>pwsh -ExecutionPolicy RemoteSigned -Command "&amp; '$(ProjectDir)BuildDrop.ps1' -EnableDebug 0 -BuildSourcesDirectory '$(ProjectDir)' -BuildConfiguration '$(Configuration)' -StagingDirectory '$(OutDir)' -ProjectRootDirectory '$(SolutionDir)' -SolutionName '$(SolutionName)' "
pwsh -ExecutionPolicy RemoteSigned -Command "&amp; '$(ProjectDir)GenerateCatlogFile.ps1' -EnableDebug 0 -BuildSourcesDirectory '$(ProjectDir)' -BuildConfiguration '$(Configuration)' -StagingDirectory '$(OutDir)' "</PostBuildEvent>
</PropertyGroup>
</Project>

Просмотреть файл

@ -0,0 +1,144 @@
function Connect-PowerPlatformDataverse {
# .ExternalHelp Microsoft.Xrm.Data.PowerShell.Help.xml
[CmdletBinding()]
PARAM(
[parameter(Position = 1, Mandatory = $true, ParameterSetName = "connectionstring")]
[string]$ConnectionString,
[parameter(Position = 1, Mandatory = $true, ParameterSetName = "FIC")]
[ValidatePattern('([\w-]+).crm([0-9]*).(microsoftdynamics|dynamics|crm[\w-]*).(com|de|us|cn)')]
[string]$ServerUrl,
[parameter(Position = 2, Mandatory = $true, ParameterSetName = "FIC")]
[ValidateScript({
            try {
                [System.Guid]::Parse($_) | Out-Null
                $true
            }
catch {
                $false
            }
        })]
[string]$TenantId,
[parameter(Position = 3, Mandatory = $true, ParameterSetName = "FIC")]
[ValidateScript({
            try {
                [System.Guid]::Parse($_) | Out-Null
                $true
            }
catch {
                $false
            }
        })]
[string]$ClientId,
[parameter(Position = 4, Mandatory = $true, ParameterSetName = "FIC")]
[ValidateScript({
            try {
                [System.Guid]::Parse($_) | Out-Null
                $true
            }
catch {
                $false
            }
        })]
[string]$ServiceConnectionId,
[parameter(Position = 4, Mandatory = $false, ParameterSetName = "FIC")]
[string]$AccessTokenEnvironmentKeyName,
[int]$ConnectionTimeoutInSeconds,
# [string]$LogWriteDirectory,
[switch]$BypassTokenCache
)
AddTls12Support #make sure tls12 is enabled
if ($PSCmdlet.MyInvocation.BoundParameters["Verbose"].IsPresent -eq $true) {
# Enable-CrmConnectorVerboseLogging
}
if (-not [string]::IsNullOrEmpty($ServerUrl) -and $ServerUrl.StartsWith("https://", "CurrentCultureIgnoreCase") -ne $true) {
Write-Verbose "ServerUrl is missing https, fixing URL: https://$ServerUrl"
$ServerUrl = "https://" + $ServerUrl
}
#starting default connection string with require new instance and server url
$cs = ";Url=$ServerUrl"
if ($BypassTokenCache) {
$cs += ";TokenCacheStorePath="
}
if ($ConnectionTimeoutInSeconds -and $ConnectionTimeoutInSeconds -gt 0) {
$newTimeout = New-Object System.TimeSpan -ArgumentList 0, 0, $ConnectionTimeoutInSeconds
Write-Verbose "Setting new connection timeout of $newTimeout"
#set the timeout on the MaxConnectionTimeout static
[Microsoft.PowerPlatform.Dataverse.Client.ServiceClient]::MaxConnectionTimeout = $newTimeout
}
if ($ConnectionString) {
if (!$ConnectionString -or $ConnectionString.Length -eq 0) {
throw "Cannot create the ServiceClient, the connection string is null"
}
Write-Verbose "ConnectionString provided - skipping all helpers/known parameters"
$global:conn = Get-PowerPlatformConnection -ConnectionString $ConnectionString
if ($global:conn) {
ApplyServiceClientObjectTemplate($global:conn) #applyObjectTemplateFormat
}
return $global:conn
}
elseif ($ServiceConnectionId) {
try {
$global:conn = Get-PowerPlatformConnection -ServiceConnectionId $ServiceConnectionId -TenantId $TenantId -ClientId $ClientId -AccessTokenEnvKeyName $AccessTokenEnvironmentKeyName -OrganizationUrl $ServerUrl
ApplyServiceClientObjectTemplate($global:conn) #applyObjectTemplateFormat
$global:conn
return
}
catch {
throw $_
}
}
}
function AddTls12Support {
#by default PowerShell will show Ssl3, Tls - since SSL3 is not desirable we will drop it and use Tls + Tls12
[System.Net.ServicePointManager]::SecurityProtocol = [System.Net.SecurityProtocolType]::Tls -bor [System.Net.SecurityProtocolType]::Tls12
}
function ApplyServiceClientObjectTemplate {
[CmdletBinding()]
PARAM(
[parameter(Mandatory = $true)]
[Microsoft.PowerPlatform.Dataverse.Client.ServiceClient]$conn
)
try {
$defaultPropsServiceClient = @(
'IsReady',
'IsBatchOperationsAvailable',
'MaxRetryCount',
'RetryPauseTime',
'Authority',
'ActiveAuthenticationType',
'OAuthUserId',
'TenantId',
'EnvironmentId',
'ConnectedOrgId',
'ConnectedOrgUriActual',
'ConnectedOrgFriendlyName',
'ConnectedOrgUniqueName',
'ConnectedOrgVersion',
'SdkVersionProperty',
'CallerId',
'CallerAADObjectId',
'DisableCrossThreadSafeties',
'SessionTrackingId',
'ForceServerMetadataCacheConsistency',
'RecommendedDegreesOfParallelism',
'LastError'
)
$defaultPropsSetServiceClient = New-Object System.Management.Automation.PSPropertySet('DefaultDisplayPropertySet', [string[]]$defaultPropsServiceClient)
$PSStandardMembers = [System.Management.Automation.PSMemberInfo[]]@($defaultPropsSetServiceClient)
$conn | Add-Member MemberSet PSStandardMembers $PSStandardMembers -Force
}
Catch {
Write-Verbose "Failed to set a new PSStandardMember on connection object"
}
}

Просмотреть файл

@ -0,0 +1,136 @@
#
# Module manifest for module 'Microsoft.PowerPlatform.Dataverse.Client.PowerShell'
#
# Generated by: Microsoft Power Platform Team
#
@{
# Script module or binary module file associated with this manifest.
RootModule = 'Microsoft.PowerPlatform.Dataverse.Client.PowerShell.psm1'
# Version number of this module.
ModuleVersion = '1.1.0.0'
# ID used to uniquely identify this module
GUID = '996701E3-B7C8-4A91-AC14-BB27918350DA'
# Author of this module
Author = 'Microsoft Power Platform Team'
# Company or vendor of this module
CompanyName = 'Microsoft'
# Copyright statement for this module
Copyright = 'Copyright 2023. All rights reserved.'
# Description of the functionality provided by this module
Description = 'PowerShell Module for Connecting to Power Platform Dataverse'
# Minimum version of the Windows PowerShell engine required by this module
PowerShellVersion = '7.0'
# Supported PSEditions: 'Desktop', 'Core'
CompatiblePSEditions = @('Core')
# Modules that must be imported into the global environment prior to importing this module
#RequiredModules =
# Assemblies that must be loaded prior to importing this module
RequiredAssemblies = @(
'Microsoft.PowerPlatform.Dataverse.Client.dll',
'Microsoft.PowerPlatform.Dataverse.Client.PowerShell.dll',
'Microsoft.Xrm.Sdk.dll',
'Microsoft.Crm.Sdk.Proxy.dll',
'Newtonsoft.Json.dll'
)
# Modules to import as nested modules of the module specified in RootModule/ModuleToProcess
NestedModules = if ($PSEdition -eq 'Core') {
@(
'Microsoft.PowerPlatform.Dataverse.Client.PowerShell.dll',
'UtilityFunctions.psm1',
'Microsoft.PowerPlatform.Dataverse.Client.Operations',
'Microsoft.PowerPlatform.Dataverse.Client.Connect'
)
}
else { # Desktop
@(
#null
)
}
# Functions to export from this module
FunctionsToExport = @(
'New-DataverseRecord',
'Get-DataverseRecord',
'Get-DataverseEntityMetadata',
'Get-MyUserId',
'Get-DataverseRecordsByFetch',
'Get-DataverseOrgDbOrgSettings',
'Get-DataverseEntityOptionSet',
'Get-DataverseEntityAttributes',
'Get-DataverseSystemSettings',
'Set-DataverseRecord',
'Set-DataverseSystemSettings',
'Invoke-DataverseAction',
'Remove-DataverseRecord',
'Connect-PowerPlatformDataverse'
)
# Cmdlets to export from this module
CmdletsToExport = @(
'Get-PowerPlatformConnection'
)
# Variables to export from this module
VariablesToExport = @(
)
# Aliases to export from this module
AliasesToExport = @(
)
# List of all modules packaged with this module.
ModuleList = @(
'Microsoft.PowerPlatform.Dataverse.Client.PowerShell'
)
# List of all files packaged with this module
#FileList = @()
# Private data to pass to the module specified in RootModule/ModuleToProcess. This may also contain a PSData hashtable with additional module metadata used by PowerShell.
PrivateData = @{
PSData = @{
# Tags applied to this module. These help with module discovery in online galleries.
# Tags = @()
# A URL to the license for this module.
LicenseUri = 'http://download.microsoft.com/download/E/1/8/E18C0FAD-FEC8-44CD-9A16-98EDC4DAC7A2/LicenseTerms.docx'
# A URL to the main website for this project.
ProjectUri = 'https://github.com/microsoft/PowerPlatform-DataverseServiceClient'
# A URL to an icon representing this module.
IconUri = 'https://connectoricons-prod.azureedge.net/powerappsforappmakers/icon_1.0.1056.1255.png'
# ReleaseNotes of this module
ReleaseNotes = '
Current Release:
>>CURRENTRELEASEID<<
'
} # End of PSData hashtable
} # End of PrivateData hashtable
# HelpInfo URI of this module
#HelpInfoURI = ''
# Default prefix for commands exported from this module. Override the default prefix using Import-Module -Prefix.
#DefaultCommandPrefix = ''
}

Просмотреть файл

@ -0,0 +1,11 @@
Push-Location $PSScriptRoot
$PackageRoot = $PSScriptRoot
$LoadingModule = $true
dir *.ps1 | % Name | Resolve-Path | Import-Module
$LoadingModule = $false
Pop-Location

Просмотреть файл

@ -0,0 +1,43 @@
function Coalesce {
foreach ($i in $args) {
if ($i -ne $null) {
return $i
}
}
}
function LastConnectorException {
[CmdletBinding()]
PARAM(
[parameter(Mandatory = $true)]
[Microsoft.PowerPlatform.Dataverse.Client.ServiceClient]$conn
)
return (Coalesce $conn.LastError $conn.LastException)
}
function VerifyConnectionParam {
[CmdletBinding()]
PARAM(
[parameter(Mandatory=$false)]
[Microsoft.PowerPlatform.Dataverse.Client.ServiceClient]$conn,
[parameter(Mandatory=$false)]
[bool]$pipelineValue
)
#we have a $conn value and we were not given a $conn value so we should try to find one
if($conn -eq $null -and $pipelineValue -eq $false)
{
$connobj = Get-Variable conn -Scope global -ErrorAction SilentlyContinue
if($connobj.Value -eq $null)
{
throw 'A connection to Dataverse is required, use Get-PowerPlatformConnection or one of the other connection functions to connect.'
}
else
{
$conn = $connobj.Value
}
}elseif($conn -eq $null -and $pipelineValue -eq $true){
throw "Connection object provided is null"
}
return $conn
}

Просмотреть файл

@ -0,0 +1,8 @@
<#
This script will load in a PowerShell command shell and import the module developed in the project. To clean up, exit this shell.
#>
# Load the module.
$env:PSModulePath = (Resolve-Path .).Path + ";" + $env:PSModulePath
Import-Module 'Microsoft.PowerPlatform.Dataverse.Client.PowerShell' -Verbose

Просмотреть файл

@ -0,0 +1,9 @@
<#
This script will load in a PowerShell command shell and import the module developed in the project. To clean up, exit this shell.
#>
# Load the module.
$env:PSModulePath = (Resolve-Path .).Path + ";" + $env:PSModulePath
Import-Module 'Microsoft.PowerPlatform.Dataverse.Client.PowerShell' -Verbose

Просмотреть файл

@ -0,0 +1,21 @@
<#
This script will run on debug.
It will load in a PowerShell command shell and import the module developed in the project. To end debug, exit this shell.
#>
cd Drop
# Write a reminder on how to end debugging.
$message = "| Exit this shell to end the debug session! |"
$line = "-" * $message.Length
$color = "Cyan"
Write-Host -ForegroundColor $color $line
Write-Host -ForegroundColor $color $message
Write-Host -ForegroundColor $color $line
Write-Host
invoke-expression -command ".\RegisterServiceClient.ps1"
# Happy debugging :-)

Просмотреть файл

@ -0,0 +1,9 @@
{
"Logging": {
"LogLevel": {
"Default": "Information",
"Microsoft.PowerPlatform.Dataverse.Client.ServiceClient": "Trace",
"dvscClient.Program": "Trace"
}
}
}

Просмотреть файл

@ -0,0 +1,25 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<ProjectSpecificFx>true</ProjectSpecificFx>
<OutputType>Exe</OutputType>
<TargetFrameworks>net462;net6.0</TargetFrameworks>
<SignAssembly>false</SignAssembly>
<ComponentAreaName>DataverseClient-Tests</ComponentAreaName>
<IsPackable>false</IsPackable>
</PropertyGroup>
<Import Project="..\..\..\..\Build.Common.core.props" />
<ItemGroup>
<ProjectReference Include="..\..\Extensions\Microsoft.PowerPlatform.Dataverse.Client.AzAuth\Microsoft.PowerPlatform.Dataverse.Client.AzAuth.csproj" />
<PackageReference Include="Microsoft.Extensions.DependencyInjection" Version="$(PackageVersion_Microsoft_Extensions)" />
<PackageReference Include="Microsoft.Extensions.Http" Version="$(PackageVersion_Microsoft_Extensions)" />
<PackageReference Include="Microsoft.Extensions.Logging" Version="$(PackageVersion_Microsoft_Extensions)" />
<PackageReference Include="Microsoft.Extensions.Logging.Console" Version="$(PackageVersion_Microsoft_Extensions)" />
<PackageReference Include="Microsoft.Extensions.Configuration.Json" Version="$(PackageVersion_Microsoft_Extensions)" />
<PackageReference Include="Microsoft.Identity.Client" version="$(PackageVersion_MSAL)" />
<PackageReference Include="Microsoft.Rest.ClientRuntime" Version="$(PackageVersion_RestClientRuntime)" />
<PackageReference Include="System.CommandLine" Version="2.0.0-beta4.22272.1" Nowarn="NU1701" />
</ItemGroup>
</Project>

Просмотреть файл

@ -0,0 +1,49 @@
using Microsoft.PowerPlatform.Dataverse.Client;
using Microsoft.PowerPlatform.Dataverse.Client.Model;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.Logging;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Microsoft.Crm.Sdk.Messages;
namespace AzDevOps_ServiceConnection_Test.Operations
{
internal class ConnectionTest
{
internal static async Task Run(Uri dvUrlToUse, Guid tenantId, Guid clientId, Guid serviceConnectionId, string systemAccessTokenEnvironmentId)
{
IConfiguration config = new ConfigurationBuilder()
.AddJsonFile("appsettings.json", optional: false, reloadOnChange: true)
.Build();
ILoggerFactory loggerFactory = LoggerFactory.Create(builder =>
builder.AddConsole(options =>
{
options.IncludeScopes = true;
options.TimestampFormat = "hh:mm:ss ";
})
.AddConfiguration(config.GetSection("Logging")));
var logger = loggerFactory.CreateLogger<ServiceClient>();
ServiceClient client = AzPipelineFederatedIdentityAuth.CreateServiceClient(
tenantId.ToString(),
clientId.ToString(),
serviceConnectionId.ToString(),
new ConnectionOptions()
{
ServiceUri = dvUrlToUse,
Logger = logger
}
);
var response = (WhoAmIResponse)await client.ExecuteAsync(new WhoAmIRequest()).ConfigureAwait(false);
logger.LogInformation($"Response: {response.UserId} - {response.BusinessUnitId} - {response.OrganizationId}");
}
}
}

Просмотреть файл

@ -0,0 +1,78 @@
using System;
using System.CommandLine;
using System.Threading.Tasks;
using AzDevOps_ServiceConnection_Test.Operations;
namespace AzDevOps_ServiceConnection_Test
{
internal class Program
{
static async Task<int> Main(string[] args)
{
Console.WriteLine("TEST Creating Service Connection to Dataverse");
var rootCommand = new RootCommand("Test harness for connecting to Dataverse from DevOps");
var DvUrlToUse = GenerateOptionItem<Uri>(
"--DataverseUrl",
"URL of the Dataverse Server that you want to connect too.\nMake sure to remove any trailing / from the URL! You will see an auth error if present",
"-url",
true);
var TenantId = GenerateOptionItem<Guid>(
"--tenantid",
"tenantID (Guid)",
"-t",
true);
var ClientId = GenerateOptionItem<Guid>(
"--ClientId",
"ClientId (Guid)",
"-c",
true);
var ServiceConnectionId = GenerateOptionItem<Guid>(
"--ServiceConnectionId",
"ServiceConnectionId (Guid)",
"-s",
true);
var SystemAccessTokenEnvironmentId = GenerateOptionItem<string>(
"--SystemAccessTokenName",
"Environment Variable name for the System Access Token",
"-en",
false);
var testCommand = new Command("test", "Get Connection to Dataverse and Test it")
{
DvUrlToUse,
TenantId,
ClientId,
ServiceConnectionId,
SystemAccessTokenEnvironmentId
};
testCommand.SetHandler(async (dvUrlToUse, tenantId, clientId, serviceConnectionId, systemAccessTokenEnvironmentId) =>
{
await ConnectionTest.Run(dvUrlToUse, tenantId, clientId, serviceConnectionId, systemAccessTokenEnvironmentId).ConfigureAwait(false);
}, DvUrlToUse, TenantId, ClientId, ServiceConnectionId, SystemAccessTokenEnvironmentId);
rootCommand.Add(testCommand);
return await rootCommand.InvokeAsync(args).ConfigureAwait(false);
}
private static Option<T> GenerateOptionItem<T>(string name, string description, string alias, bool isRequired = false)
{
var option = new Option<T>(name: $"--{name}", description: description);
option.AddAlias($"-{alias}");
option.IsRequired = isRequired;
return option;
}
}
}

Просмотреть файл

@ -0,0 +1,9 @@
{
"Logging": {
"LogLevel": {
"Default": "None",
"AzDevOps_ServiceConnection_Test.Program": "None",
"Microsoft.PowerPlatform.Dataverse.Client.ServiceClient": "Trace"
}
}
}

Просмотреть файл

@ -3,8 +3,8 @@
<PropertyGroup Label="Package versions">
<PackageVersion_Adal>3.19.8</PackageVersion_Adal>
<PackageVersion_MSAL>4.61.3</PackageVersion_MSAL>
<PackageVersion_CdsSdk>9.2.24044.9795-master</PackageVersion_CdsSdk>
<PackageVersion_CrmProxy>9.2.24044.9795-master</PackageVersion_CrmProxy>
<PackageVersion_CdsSdk>9.2.24073.11611-master</PackageVersion_CdsSdk>
<PackageVersion_CrmProxy>9.2.24073.11611-master</PackageVersion_CrmProxy>
<PackageVersion_Newtonsoft>13.0.1</PackageVersion_Newtonsoft>
<PackageVersion_RestClientRuntime>2.3.24</PackageVersion_RestClientRuntime>
<PackageVersion_XrmSdk>9.0.2.55</PackageVersion_XrmSdk>
@ -17,10 +17,11 @@
<PackageVersion_SystemTextJson>7.0.3</PackageVersion_SystemTextJson>
<PackageVersion_SystemTextEncodingsWeb>7.0.0</PackageVersion_SystemTextEncodingsWeb>
<PackageVersion_SystemMemory>4.5.5</PackageVersion_SystemMemory>
<PackageVersion_SystemServiceModelHttp>4.10.3</PackageVersion_SystemServiceModelHttp>
<PackageVersion_SystemConfigurationConfigurationManager>6.0.0</PackageVersion_SystemConfigurationConfigurationManager>
<PackageVersion_SystemSecurityPermissions>6.0.0</PackageVersion_SystemSecurityPermissions>
<PackageVersion_Azure_Identity>1.12.0</PackageVersion_Azure_Identity>
<PackageVersion_System_ServiceModel_PreNet6>4.10.3</PackageVersion_System_ServiceModel_PreNet6>
<PackageVersion_System_ServiceModel_PostNet6>6.2.0</PackageVersion_System_ServiceModel_PostNet6>
<!-- Test: -->
<PackageVersion_MicrosoftNETTestSdk>17.5.0</PackageVersion_MicrosoftNETTestSdk>

Просмотреть файл

@ -148,6 +148,140 @@
<member name="T:Microsoft.PowerPlatform.Dataverse.Client.BooleanAttributeData" />
<member name="M:Microsoft.PowerPlatform.Dataverse.Client.BooleanAttributeData.#ctor" />
<member name="P:Microsoft.PowerPlatform.Dataverse.Client.BooleanAttributeData.BooleanOptions" />
<member name="T:Microsoft.PowerPlatform.Dataverse.Client.Builder.AbstractClientRequestBuilder`1">
<typeparam name="T" />
</member>
<member name="M:Microsoft.PowerPlatform.Dataverse.Client.Builder.AbstractClientRequestBuilder`1.Associate(System.String,System.Guid,Microsoft.Xrm.Sdk.Relationship,Microsoft.Xrm.Sdk.EntityReferenceCollection)">
<param name="entityName" />
<param name="entityId" />
<param name="relationship" />
<param name="relatedEntities" />
</member>
<member name="M:Microsoft.PowerPlatform.Dataverse.Client.Builder.AbstractClientRequestBuilder`1.AssociateAsync(System.String,System.Guid,Microsoft.Xrm.Sdk.Relationship,Microsoft.Xrm.Sdk.EntityReferenceCollection,System.Threading.CancellationToken)">
<param name="entityName" />
<param name="entityId" />
<param name="relationship" />
<param name="relatedEntities" />
<param name="cancellationToken" />
</member>
<member name="M:Microsoft.PowerPlatform.Dataverse.Client.Builder.AbstractClientRequestBuilder`1.AssociateAsync(System.String,System.Guid,Microsoft.Xrm.Sdk.Relationship,Microsoft.Xrm.Sdk.EntityReferenceCollection)">
<param name="entityName" />
<param name="entityId" />
<param name="relationship" />
<param name="relatedEntities" />
</member>
<member name="M:Microsoft.PowerPlatform.Dataverse.Client.Builder.AbstractClientRequestBuilder`1.Create(Microsoft.Xrm.Sdk.Entity)">
<param name="entity" />
</member>
<member name="M:Microsoft.PowerPlatform.Dataverse.Client.Builder.AbstractClientRequestBuilder`1.CreateAndReturnAsync(Microsoft.Xrm.Sdk.Entity,System.Threading.CancellationToken)">
<param name="entity" />
<param name="cancellationToken" />
</member>
<member name="M:Microsoft.PowerPlatform.Dataverse.Client.Builder.AbstractClientRequestBuilder`1.CreateAsync(Microsoft.Xrm.Sdk.Entity,System.Threading.CancellationToken)">
<param name="entity" />
<param name="cancellationToken" />
</member>
<member name="M:Microsoft.PowerPlatform.Dataverse.Client.Builder.AbstractClientRequestBuilder`1.CreateAsync(Microsoft.Xrm.Sdk.Entity)">
<param name="entity" />
</member>
<member name="M:Microsoft.PowerPlatform.Dataverse.Client.Builder.AbstractClientRequestBuilder`1.Delete(System.String,System.Guid)">
<param name="entityName" />
<param name="id" />
</member>
<member name="M:Microsoft.PowerPlatform.Dataverse.Client.Builder.AbstractClientRequestBuilder`1.DeleteAsync(System.String,System.Guid,System.Threading.CancellationToken)">
<param name="entityName" />
<param name="id" />
<param name="cancellationToken" />
</member>
<member name="M:Microsoft.PowerPlatform.Dataverse.Client.Builder.AbstractClientRequestBuilder`1.DeleteAsync(System.String,System.Guid)">
<param name="entityName" />
<param name="id" />
</member>
<member name="M:Microsoft.PowerPlatform.Dataverse.Client.Builder.AbstractClientRequestBuilder`1.Disassociate(System.String,System.Guid,Microsoft.Xrm.Sdk.Relationship,Microsoft.Xrm.Sdk.EntityReferenceCollection)">
<param name="entityName" />
<param name="entityId" />
<param name="relationship" />
<param name="relatedEntities" />
</member>
<member name="M:Microsoft.PowerPlatform.Dataverse.Client.Builder.AbstractClientRequestBuilder`1.DisassociateAsync(System.String,System.Guid,Microsoft.Xrm.Sdk.Relationship,Microsoft.Xrm.Sdk.EntityReferenceCollection,System.Threading.CancellationToken)">
<param name="entityName" />
<param name="entityId" />
<param name="relationship" />
<param name="relatedEntities" />
<param name="cancellationToken" />
</member>
<member name="M:Microsoft.PowerPlatform.Dataverse.Client.Builder.AbstractClientRequestBuilder`1.DisassociateAsync(System.String,System.Guid,Microsoft.Xrm.Sdk.Relationship,Microsoft.Xrm.Sdk.EntityReferenceCollection)">
<param name="entityName" />
<param name="entityId" />
<param name="relationship" />
<param name="relatedEntities" />
</member>
<member name="M:Microsoft.PowerPlatform.Dataverse.Client.Builder.AbstractClientRequestBuilder`1.Execute(Microsoft.Xrm.Sdk.OrganizationRequest)">
<param name="request" />
</member>
<member name="M:Microsoft.PowerPlatform.Dataverse.Client.Builder.AbstractClientRequestBuilder`1.ExecuteAsync(Microsoft.Xrm.Sdk.OrganizationRequest,System.Threading.CancellationToken)">
<param name="request" />
<param name="cancellationToken" />
</member>
<member name="M:Microsoft.PowerPlatform.Dataverse.Client.Builder.AbstractClientRequestBuilder`1.ExecuteAsync(Microsoft.Xrm.Sdk.OrganizationRequest)">
<param name="request" />
</member>
<member name="M:Microsoft.PowerPlatform.Dataverse.Client.Builder.AbstractClientRequestBuilder`1.Retrieve(System.String,System.Guid,Microsoft.Xrm.Sdk.Query.ColumnSet)">
<param name="entityName" />
<param name="id" />
<param name="columnSet" />
</member>
<member name="M:Microsoft.PowerPlatform.Dataverse.Client.Builder.AbstractClientRequestBuilder`1.RetrieveAsync(System.String,System.Guid,Microsoft.Xrm.Sdk.Query.ColumnSet,System.Threading.CancellationToken)">
<param name="entityName" />
<param name="id" />
<param name="columnSet" />
<param name="cancellationToken" />
</member>
<member name="M:Microsoft.PowerPlatform.Dataverse.Client.Builder.AbstractClientRequestBuilder`1.RetrieveAsync(System.String,System.Guid,Microsoft.Xrm.Sdk.Query.ColumnSet)">
<param name="entityName" />
<param name="id" />
<param name="columnSet" />
</member>
<member name="M:Microsoft.PowerPlatform.Dataverse.Client.Builder.AbstractClientRequestBuilder`1.RetrieveMultiple(Microsoft.Xrm.Sdk.Query.QueryBase)">
<param name="query" />
</member>
<member name="M:Microsoft.PowerPlatform.Dataverse.Client.Builder.AbstractClientRequestBuilder`1.RetrieveMultipleAsync(Microsoft.Xrm.Sdk.Query.QueryBase,System.Threading.CancellationToken)">
<param name="query" />
<param name="cancellationToken" />
</member>
<member name="M:Microsoft.PowerPlatform.Dataverse.Client.Builder.AbstractClientRequestBuilder`1.RetrieveMultipleAsync(Microsoft.Xrm.Sdk.Query.QueryBase)">
<param name="query" />
</member>
<member name="M:Microsoft.PowerPlatform.Dataverse.Client.Builder.AbstractClientRequestBuilder`1.Update(Microsoft.Xrm.Sdk.Entity)">
<param name="entity" />
</member>
<member name="M:Microsoft.PowerPlatform.Dataverse.Client.Builder.AbstractClientRequestBuilder`1.UpdateAsync(Microsoft.Xrm.Sdk.Entity,System.Threading.CancellationToken)">
<param name="entity" />
<param name="cancellationToken" />
</member>
<member name="M:Microsoft.PowerPlatform.Dataverse.Client.Builder.AbstractClientRequestBuilder`1.UpdateAsync(Microsoft.Xrm.Sdk.Entity)">
<param name="entity" />
</member>
<member name="M:Microsoft.PowerPlatform.Dataverse.Client.Builder.AbstractClientRequestBuilder`1.WithCorrelationId(System.Guid)">
<param name="correlationId" />
</member>
<member name="M:Microsoft.PowerPlatform.Dataverse.Client.Builder.AbstractClientRequestBuilder`1.WithCrmUserId(System.Guid)">
<param name="crmUserId" />
</member>
<member name="M:Microsoft.PowerPlatform.Dataverse.Client.Builder.AbstractClientRequestBuilder`1.WithHeader(System.String,System.String)">
<param name="key" />
<param name="value" />
</member>
<member name="M:Microsoft.PowerPlatform.Dataverse.Client.Builder.AbstractClientRequestBuilder`1.WithHeaders(System.Collections.Generic.IDictionary{System.String,System.String})">
<param name="headers" />
</member>
<member name="M:Microsoft.PowerPlatform.Dataverse.Client.Builder.AbstractClientRequestBuilder`1.WithRequestId(System.Guid)">
<param name="requestId" />
</member>
<member name="M:Microsoft.PowerPlatform.Dataverse.Client.Builder.AbstractClientRequestBuilder`1.WithUserObjectId(System.Guid)">
<param name="userObjectId" />
</member>
<member name="T:Microsoft.PowerPlatform.Dataverse.Client.Builder.ServiceClientRequestBuilder" />
<member name="T:Microsoft.PowerPlatform.Dataverse.Client.DataverseDataTypeWrapper">
<summary>
Contains a variable definition.</summary>
@ -157,12 +291,6 @@
Create a new Data Type
Default Constructor</summary>
</member>
<member name="M:Microsoft.PowerPlatform.Dataverse.Client.DataverseDataTypeWrapper.#ctor(System.Object,Microsoft.PowerPlatform.Dataverse.Client.DataverseFieldType)">
<summary>
Create a new Data Type</summary>
<param name="data">Data to Set</param>
<param name="CdsFieldType">Type of Data to Set</param>
</member>
<member name="M:Microsoft.PowerPlatform.Dataverse.Client.DataverseDataTypeWrapper.#ctor(System.Object,Microsoft.PowerPlatform.Dataverse.Client.DataverseFieldType,System.String)">
<summary>
Create a new Data Type</summary>
@ -170,6 +298,12 @@
<param name="CdsFieldType">Type of Data to Set</param>
<param name="relatedEntityName">Name of the related entity, applies to the Field Types: Customer and Lookup</param>
</member>
<member name="M:Microsoft.PowerPlatform.Dataverse.Client.DataverseDataTypeWrapper.#ctor(System.Object,Microsoft.PowerPlatform.Dataverse.Client.DataverseFieldType)">
<summary>
Create a new Data Type</summary>
<param name="data">Data to Set</param>
<param name="CdsFieldType">Type of Data to Set</param>
</member>
<member name="P:Microsoft.PowerPlatform.Dataverse.Client.DataverseDataTypeWrapper.ReferencedEntity">
<summary>
Name of the entity that a Lookup or Related Customer Entity</summary>
@ -1961,14 +2095,6 @@
<param name="relationship">Relationship Name</param>
<param name="relatedEntities">Entities to associate</param>
</member>
<member name="M:Microsoft.PowerPlatform.Dataverse.Client.ServiceClient.AssociateAsync(System.String,System.Guid,Microsoft.Xrm.Sdk.Relationship,Microsoft.Xrm.Sdk.EntityReferenceCollection)">
<summary>
Associate an entity with a set of entities</summary>
<param name="entityName" />
<param name="entityId" />
<param name="relationship" />
<param name="relatedEntities" />
</member>
<member name="M:Microsoft.PowerPlatform.Dataverse.Client.ServiceClient.AssociateAsync(System.String,System.Guid,Microsoft.Xrm.Sdk.Relationship,Microsoft.Xrm.Sdk.EntityReferenceCollection,System.Threading.CancellationToken)">
<summary>
Associate an entity with a set of entities</summary>
@ -1978,6 +2104,14 @@
<param name="relatedEntities" />
<param name="cancellationToken">Propagates notification that operations should be canceled.</param>
</member>
<member name="M:Microsoft.PowerPlatform.Dataverse.Client.ServiceClient.AssociateAsync(System.String,System.Guid,Microsoft.Xrm.Sdk.Relationship,Microsoft.Xrm.Sdk.EntityReferenceCollection)">
<summary>
Associate an entity with a set of entities</summary>
<param name="entityName" />
<param name="entityId" />
<param name="relationship" />
<param name="relatedEntities" />
</member>
<member name="M:Microsoft.PowerPlatform.Dataverse.Client.ServiceClient.Clone(Microsoft.Extensions.Logging.ILogger)">
<summary>
Clone, 'Clones" the current Dataverse ServiceClient with a new connection to Dataverse.
@ -2004,12 +2138,6 @@
<param name="entity">Entity to create</param>
<returns>ID of newly created entity</returns>
</member>
<member name="M:Microsoft.PowerPlatform.Dataverse.Client.ServiceClient.CreateAndReturnAsync(Microsoft.Xrm.Sdk.Entity)">
<summary>
Create an entity and process any related entities</summary>
<param name="entity">entity to create</param>
<returns>Returns the newly created record</returns>
</member>
<member name="M:Microsoft.PowerPlatform.Dataverse.Client.ServiceClient.CreateAndReturnAsync(Microsoft.Xrm.Sdk.Entity,System.Threading.CancellationToken)">
<summary>
Create an entity and process any related entities</summary>
@ -2017,11 +2145,11 @@
<param name="cancellationToken">Propagates notification that operations should be canceled.</param>
<returns>Returns the newly created record</returns>
</member>
<member name="M:Microsoft.PowerPlatform.Dataverse.Client.ServiceClient.CreateAsync(Microsoft.Xrm.Sdk.Entity)">
<member name="M:Microsoft.PowerPlatform.Dataverse.Client.ServiceClient.CreateAndReturnAsync(Microsoft.Xrm.Sdk.Entity)">
<summary>
Create an entity and process any related entities</summary>
<param name="entity">entity to create</param>
<returns>The ID of the created record</returns>
<returns>Returns the newly created record</returns>
</member>
<member name="M:Microsoft.PowerPlatform.Dataverse.Client.ServiceClient.CreateAsync(Microsoft.Xrm.Sdk.Entity,System.Threading.CancellationToken)">
<summary>
@ -2030,18 +2158,19 @@
<param name="cancellationToken">Propagates notification that operations should be canceled.</param>
<returns>The ID of the created record</returns>
</member>
<member name="M:Microsoft.PowerPlatform.Dataverse.Client.ServiceClient.CreateAsync(Microsoft.Xrm.Sdk.Entity)">
<summary>
Create an entity and process any related entities</summary>
<param name="entity">entity to create</param>
<returns>The ID of the created record</returns>
</member>
<member name="M:Microsoft.PowerPlatform.Dataverse.Client.ServiceClient.CreateRequestBuilder" />
<member name="M:Microsoft.PowerPlatform.Dataverse.Client.ServiceClient.Delete(System.String,System.Guid)">
<summary>
Issues a Delete request to Dataverse</summary>
<param name="entityName">Entity name to delete</param>
<param name="id">ID if entity to delete</param>
</member>
<member name="M:Microsoft.PowerPlatform.Dataverse.Client.ServiceClient.DeleteAsync(System.String,System.Guid)">
<summary>
Delete instance of an entity</summary>
<param name="entityName">Logical name of entity</param>
<param name="id">Id of entity</param>
</member>
<member name="M:Microsoft.PowerPlatform.Dataverse.Client.ServiceClient.DeleteAsync(System.String,System.Guid,System.Threading.CancellationToken)">
<summary>
Delete instance of an entity</summary>
@ -2049,6 +2178,12 @@
<param name="id">Id of entity</param>
<param name="cancellationToken">Propagates notification that operations should be canceled.</param>
</member>
<member name="M:Microsoft.PowerPlatform.Dataverse.Client.ServiceClient.DeleteAsync(System.String,System.Guid)">
<summary>
Delete instance of an entity</summary>
<param name="entityName">Logical name of entity</param>
<param name="id">Id of entity</param>
</member>
<member name="M:Microsoft.PowerPlatform.Dataverse.Client.ServiceClient.Disassociate(System.String,System.Guid,Microsoft.Xrm.Sdk.Relationship,Microsoft.Xrm.Sdk.EntityReferenceCollection)">
<summary>
Issues a Disassociate Request to Dataverse.</summary>
@ -2057,14 +2192,6 @@
<param name="relationship">Relationship Name</param>
<param name="relatedEntities">Entities to disassociate</param>
</member>
<member name="M:Microsoft.PowerPlatform.Dataverse.Client.ServiceClient.DisassociateAsync(System.String,System.Guid,Microsoft.Xrm.Sdk.Relationship,Microsoft.Xrm.Sdk.EntityReferenceCollection)">
<summary>
Disassociate an entity with a set of entities</summary>
<param name="entityName" />
<param name="entityId" />
<param name="relationship" />
<param name="relatedEntities" />
</member>
<member name="M:Microsoft.PowerPlatform.Dataverse.Client.ServiceClient.DisassociateAsync(System.String,System.Guid,Microsoft.Xrm.Sdk.Relationship,Microsoft.Xrm.Sdk.EntityReferenceCollection,System.Threading.CancellationToken)">
<summary>
Disassociate an entity with a set of entities</summary>
@ -2074,6 +2201,21 @@
<param name="relatedEntities" />
<param name="cancellationToken">Propagates notification that operations should be canceled.</param>
</member>
<member name="M:Microsoft.PowerPlatform.Dataverse.Client.ServiceClient.DisassociateAsync(System.String,System.Guid,Microsoft.Xrm.Sdk.Relationship,Microsoft.Xrm.Sdk.EntityReferenceCollection)">
<summary>
Disassociate an entity with a set of entities</summary>
<param name="entityName" />
<param name="entityId" />
<param name="relationship" />
<param name="relatedEntities" />
</member>
<member name="M:Microsoft.PowerPlatform.Dataverse.Client.ServiceClient.DiscoverOnlineOrganizationsAsync(System.Func{System.String,System.Threading.Tasks.Task{System.String}},System.Uri,System.String,Microsoft.Extensions.Logging.ILogger,System.Threading.CancellationToken)">
<param name="tokenProviderFunction" />
<param name="discoveryServiceUri" />
<param name="tokenCacheStorePath" />
<param name="logger" />
<param name="cancellationToken" />
</member>
<member name="M:Microsoft.PowerPlatform.Dataverse.Client.ServiceClient.DiscoverOnlineOrganizationsAsync(System.Func{System.String,System.Threading.Tasks.Task{System.String}},System.Uri,System.String,Microsoft.Extensions.Logging.ILogger)">
<summary>
Discovers Organizations Using the global discovery service and an external source for access tokens</summary>
@ -2083,13 +2225,6 @@
<param name="logger">Logging provider <see cref="T:Microsoft.Extensions.Logging.ILogger" /></param>
<returns />
</member>
<member name="M:Microsoft.PowerPlatform.Dataverse.Client.ServiceClient.DiscoverOnlineOrganizationsAsync(System.Func{System.String,System.Threading.Tasks.Task{System.String}},System.Uri,System.String,Microsoft.Extensions.Logging.ILogger,System.Threading.CancellationToken)">
<param name="tokenProviderFunction" />
<param name="discoveryServiceUri" />
<param name="tokenCacheStorePath" />
<param name="logger" />
<param name="cancellationToken" />
</member>
<member name="M:Microsoft.PowerPlatform.Dataverse.Client.ServiceClient.DiscoverOnlineOrganizationsAsync(System.String,System.String,System.String,System.Uri,System.Boolean,System.String,Microsoft.PowerPlatform.Dataverse.Client.Auth.PromptBehavior,System.Boolean,Microsoft.PowerPlatform.Dataverse.Client.Model.DiscoveryServer,System.String,Microsoft.Extensions.Logging.ILogger)">
<summary>
Discovers Organizations Using the global discovery service.
@ -2147,12 +2282,6 @@
<param name="request">Request object</param>
<returns>Response object</returns>
</member>
<member name="M:Microsoft.PowerPlatform.Dataverse.Client.ServiceClient.ExecuteAsync(Microsoft.Xrm.Sdk.OrganizationRequest)">
<summary>
Perform an action in an organization specified by the request.</summary>
<param name="request">Refer to SDK documentation for list of messages that can be used.</param>
<returns>Results from processing the request</returns>
</member>
<member name="M:Microsoft.PowerPlatform.Dataverse.Client.ServiceClient.ExecuteAsync(Microsoft.Xrm.Sdk.OrganizationRequest,System.Threading.CancellationToken)">
<summary>
Perform an action in an organization specified by the request.</summary>
@ -2160,6 +2289,12 @@
<param name="cancellationToken">Propagates notification that operations should be canceled.</param>
<returns>Results from processing the request</returns>
</member>
<member name="M:Microsoft.PowerPlatform.Dataverse.Client.ServiceClient.ExecuteAsync(Microsoft.Xrm.Sdk.OrganizationRequest)">
<summary>
Perform an action in an organization specified by the request.</summary>
<param name="request">Refer to SDK documentation for list of messages that can be used.</param>
<returns>Results from processing the request</returns>
</member>
<member name="M:Microsoft.PowerPlatform.Dataverse.Client.ServiceClient.ExecuteOrganizationRequest(Microsoft.Xrm.Sdk.OrganizationRequest,System.String,System.Boolean)">
<summary>
Executes a Dataverse Organization Request (thread safe) and returns the organization response object. Also adds metrics for logging support.</summary>
@ -2228,14 +2363,6 @@
<param name="columnSet">ColumnSet to request</param>
<returns>Entity object</returns>
</member>
<member name="M:Microsoft.PowerPlatform.Dataverse.Client.ServiceClient.RetrieveAsync(System.String,System.Guid,Microsoft.Xrm.Sdk.Query.ColumnSet)">
<summary>
Retrieves instance of an entity</summary>
<param name="entityName">Logical name of entity</param>
<param name="id">Id of entity</param>
<param name="columnSet">Column Set collection to return with the request</param>
<returns>Selected Entity</returns>
</member>
<member name="M:Microsoft.PowerPlatform.Dataverse.Client.ServiceClient.RetrieveAsync(System.String,System.Guid,Microsoft.Xrm.Sdk.Query.ColumnSet,System.Threading.CancellationToken)">
<summary>
Retrieves instance of an entity</summary>
@ -2245,18 +2372,20 @@
<param name="cancellationToken">Propagates notification that operations should be canceled.</param>
<returns>Selected Entity</returns>
</member>
<member name="M:Microsoft.PowerPlatform.Dataverse.Client.ServiceClient.RetrieveAsync(System.String,System.Guid,Microsoft.Xrm.Sdk.Query.ColumnSet)">
<summary>
Retrieves instance of an entity</summary>
<param name="entityName">Logical name of entity</param>
<param name="id">Id of entity</param>
<param name="columnSet">Column Set collection to return with the request</param>
<returns>Selected Entity</returns>
</member>
<member name="M:Microsoft.PowerPlatform.Dataverse.Client.ServiceClient.RetrieveMultiple(Microsoft.Xrm.Sdk.Query.QueryBase)">
<summary>
Issues a RetrieveMultiple Request to Dataverse</summary>
<param name="query">Query to Request</param>
<returns>EntityCollection Result</returns>
</member>
<member name="M:Microsoft.PowerPlatform.Dataverse.Client.ServiceClient.RetrieveMultipleAsync(Microsoft.Xrm.Sdk.Query.QueryBase)">
<summary>
Retrieves a collection of entities</summary>
<param name="query" />
<returns>Returns an EntityCollection Object containing the results of the query</returns>
</member>
<member name="M:Microsoft.PowerPlatform.Dataverse.Client.ServiceClient.RetrieveMultipleAsync(Microsoft.Xrm.Sdk.Query.QueryBase,System.Threading.CancellationToken)">
<summary>
Retrieves a collection of entities</summary>
@ -2264,22 +2393,28 @@
<param name="cancellationToken">Propagates notification that operations should be canceled.</param>
<returns>Returns an EntityCollection Object containing the results of the query</returns>
</member>
<member name="M:Microsoft.PowerPlatform.Dataverse.Client.ServiceClient.RetrieveMultipleAsync(Microsoft.Xrm.Sdk.Query.QueryBase)">
<summary>
Retrieves a collection of entities</summary>
<param name="query" />
<returns>Returns an EntityCollection Object containing the results of the query</returns>
</member>
<member name="M:Microsoft.PowerPlatform.Dataverse.Client.ServiceClient.Update(Microsoft.Xrm.Sdk.Entity)">
<summary>
Issues an update to Dataverse.</summary>
<param name="entity">Entity to update into Dataverse</param>
</member>
<member name="M:Microsoft.PowerPlatform.Dataverse.Client.ServiceClient.UpdateAsync(Microsoft.Xrm.Sdk.Entity)">
<summary>
Updates an entity and process any related entities</summary>
<param name="entity">entity to update</param>
</member>
<member name="M:Microsoft.PowerPlatform.Dataverse.Client.ServiceClient.UpdateAsync(Microsoft.Xrm.Sdk.Entity,System.Threading.CancellationToken)">
<summary>
Updates an entity and process any related entities</summary>
<param name="entity">entity to update</param>
<param name="cancellationToken">Propagates notification that operations should be canceled.</param>
</member>
<member name="M:Microsoft.PowerPlatform.Dataverse.Client.ServiceClient.UpdateAsync(Microsoft.Xrm.Sdk.Entity)">
<summary>
Updates an entity and process any related entities</summary>
<param name="entity">entity to update</param>
</member>
<member name="P:Microsoft.PowerPlatform.Dataverse.Client.ServiceClient.ActiveAuthenticationType">
<summary>
Authentication Type to use</summary>
@ -2512,10 +2647,12 @@
Logg an error with an Exception</summary>
<param name="exception" />
</member>
<member name="M:Microsoft.PowerPlatform.Dataverse.Client.TraceLoggerBase.Log(System.String)">
<member name="M:Microsoft.PowerPlatform.Dataverse.Client.TraceLoggerBase.Log(System.String,System.Diagnostics.TraceEventType,System.Exception)">
<summary>
Log a Message as an Information event.</summary>
Log a Trace event</summary>
<param name="message" />
<param name="eventType" />
<param name="exception" />
</member>
<member name="M:Microsoft.PowerPlatform.Dataverse.Client.TraceLoggerBase.Log(System.String,System.Diagnostics.TraceEventType)">
<summary>
@ -2523,12 +2660,10 @@
<param name="message" />
<param name="eventType" />
</member>
<member name="M:Microsoft.PowerPlatform.Dataverse.Client.TraceLoggerBase.Log(System.String,System.Diagnostics.TraceEventType,System.Exception)">
<member name="M:Microsoft.PowerPlatform.Dataverse.Client.TraceLoggerBase.Log(System.String)">
<summary>
Log a Trace event</summary>
Log a Message as an Information event.</summary>
<param name="message" />
<param name="eventType" />
<param name="exception" />
</member>
<member name="M:Microsoft.PowerPlatform.Dataverse.Client.TraceLoggerBase.RefreshListeners(System.Collections.Generic.List{Microsoft.PowerPlatform.Dataverse.Client.TraceSourceSetting})">
<summary>
@ -2607,11 +2742,6 @@
<param name="serializationInfo" />
<param name="streamingContext" />
</member>
<member name="M:Microsoft.PowerPlatform.Dataverse.Client.Utils.DataverseConnectionException.#ctor(System.String)">
<summary>
Creates a CdsService Client Exception</summary>
<param name="message">Error Message</param>
</member>
<member name="M:Microsoft.PowerPlatform.Dataverse.Client.Utils.DataverseConnectionException.#ctor(System.String,System.Exception)">
<summary>
Creates a CdsService Client Exception</summary>
@ -2625,6 +2755,11 @@
<param name="data" />
<param name="httpOperationException" />
</member>
<member name="M:Microsoft.PowerPlatform.Dataverse.Client.Utils.DataverseConnectionException.#ctor(System.String)">
<summary>
Creates a CdsService Client Exception</summary>
<param name="message">Error Message</param>
</member>
<member name="M:Microsoft.PowerPlatform.Dataverse.Client.Utils.DataverseConnectionException.GenerateClientConnectionException(Microsoft.Rest.HttpOperationException)">
<param name="httpOperationException" />
</member>
@ -2638,11 +2773,6 @@
<param name="serializationInfo" />
<param name="streamingContext" />
</member>
<member name="M:Microsoft.PowerPlatform.Dataverse.Client.Utils.DataverseOperationException.#ctor(System.String)">
<summary>
Creates a CdsService Client Exception</summary>
<param name="message">Error Message</param>
</member>
<member name="M:Microsoft.PowerPlatform.Dataverse.Client.Utils.DataverseOperationException.#ctor(System.String,System.Exception)">
<summary>
Creates a CdsService Client Exception</summary>
@ -2658,6 +2788,11 @@
<param name="data">Data Properties</param>
<param name="httpOperationException" />
</member>
<member name="M:Microsoft.PowerPlatform.Dataverse.Client.Utils.DataverseOperationException.#ctor(System.String)">
<summary>
Creates a CdsService Client Exception</summary>
<param name="message">Error Message</param>
</member>
<member name="M:Microsoft.PowerPlatform.Dataverse.Client.Utils.DataverseOperationException.GenerateClientOperationException(Microsoft.Rest.HttpOperationException)">
<summary>
Creates a CdsService Client Exception from a httpOperationResult.</summary>
@ -2683,13 +2818,6 @@
<param name="input">The XML stream to load.</param>
<returns>the new XmlDocument object</returns>
</member>
<member name="M:Microsoft.PowerPlatform.Dataverse.Client.XmlUtil.CreateXmlDocument(System.String)">
<summary>
Creates an XmlDocument object with secure default property values.
Loads the given XML into the XmlDocument.</summary>
<param name="xml">The XML to load.</param>
<returns>the new XmlDocument object</returns>
</member>
<member name="M:Microsoft.PowerPlatform.Dataverse.Client.XmlUtil.CreateXmlDocument(System.String,System.Boolean)">
<summary>
Creates an XmlDocument object with secure default property values.
@ -2699,6 +2827,13 @@
<param name="preserveWhiteSpace">Whether the whitespaces are to be preserved or not.</param>
<returns>the new XmlDocument object</returns>
</member>
<member name="M:Microsoft.PowerPlatform.Dataverse.Client.XmlUtil.CreateXmlDocument(System.String)">
<summary>
Creates an XmlDocument object with secure default property values.
Loads the given XML into the XmlDocument.</summary>
<param name="xml">The XML to load.</param>
<returns>the new XmlDocument object</returns>
</member>
<member name="M:Microsoft.PowerPlatform.Dataverse.Client.XmlUtil.CreateXmlDocument(System.Xml.XmlReader)">
<summary>
Creates an XmlDocument object with secure default property values.</summary>
@ -2711,12 +2846,6 @@
<param name="xmlStream">Xml stream.</param>
<returns>The new XmlReader object.</returns>
</member>
<member name="M:Microsoft.PowerPlatform.Dataverse.Client.XmlUtil.CreateXmlReader(System.String)">
<summary>
Creates an XmlReader object with secure default property values.</summary>
<param name="xml">The string to get the data from.</param>
<returns>the new XmlReader object</returns>
</member>
<member name="M:Microsoft.PowerPlatform.Dataverse.Client.XmlUtil.CreateXmlReader(System.String,System.Boolean)">
<summary>
Creates an XmlReader object with secure default property values and given whitespace setting.</summary>
@ -2724,6 +2853,12 @@
<param name="preserveWhiteSpace">Whether the whitespaces are to be preserved or not.</param>
<returns>the new XmlReader object</returns>
</member>
<member name="M:Microsoft.PowerPlatform.Dataverse.Client.XmlUtil.CreateXmlReader(System.String)">
<summary>
Creates an XmlReader object with secure default property values.</summary>
<param name="xml">The string to get the data from.</param>
<returns>the new XmlReader object</returns>
</member>
<member name="M:Microsoft.PowerPlatform.Dataverse.Client.XmlUtil.CreateXmlWriter(System.IO.TextWriter,System.Boolean)">
<summary>
Creates an XmlWriter on top of the provided TextWriter as per

Просмотреть файл

@ -15,32 +15,32 @@
<tags>Dynamics CommonDataService CDS PowerApps PowerPlatform ServiceClient Dataverse</tags>
<dependencies>
<group targetFramework=".NETFramework4.6.2">
<dependency id="Microsoft.PowerPlatform.Dataverse.Client" version="1.1.0" exclude="Build,Analyzers" />
<dependency id="Azure.Identity" version="1.11.3" exclude="Build,Analyzers" />
<dependency id="Microsoft.PowerPlatform.Dataverse.Client" version="1.1.27" exclude="Build,Analyzers" />
<dependency id="Azure.Identity" version="1.12.0" exclude="Build,Analyzers" />
</group>
<group targetFramework=".NETFramework4.7.2">
<dependency id="Microsoft.PowerPlatform.Dataverse.Client" version="1.1.0" exclude="Build,Analyzers" />
<dependency id="Azure.Identity" version="1.11.3" exclude="Build,Analyzers" />
<dependency id="Microsoft.PowerPlatform.Dataverse.Client" version="1.1.27" exclude="Build,Analyzers" />
<dependency id="Azure.Identity" version="1.12.0" exclude="Build,Analyzers" />
</group>
<group targetFramework=".NETFramework4.8">
<dependency id="Microsoft.PowerPlatform.Dataverse.Client" version="1.1.0" exclude="Build,Analyzers" />
<dependency id="Azure.Identity" version="1.11.3" exclude="Build,Analyzers" />
<dependency id="Microsoft.PowerPlatform.Dataverse.Client" version="1.1.27" exclude="Build,Analyzers" />
<dependency id="Azure.Identity" version="1.12.0" exclude="Build,Analyzers" />
</group>
<group targetFramework="NET6.0">
<dependency id="Microsoft.PowerPlatform.Dataverse.Client" version="1.1.0" exclude="Build,Analyzers" />
<dependency id="Azure.Identity" version="1.11.3" exclude="Build,Analyzers" />
<dependency id="Microsoft.PowerPlatform.Dataverse.Client" version="1.1.27" exclude="Build,Analyzers" />
<dependency id="Azure.Identity" version="1.12.0" exclude="Build,Analyzers" />
</group>
</dependencies>
</metadata>
<files>
<file src="{signedBinDir}\{configuration}\DataverseClient-AzAuth\net6.0\Microsoft.PowerPlatform.Dataverse.Client.AzAuth.dll" target="lib\net6.0\Microsoft.PowerPlatform.Dataverse.Client.AzAuth.dll" />
<file src="{signedBinDir}\{configuration}\DataverseClient-AzAuth\net6.0\Microsoft.PowerPlatform.Dataverse.Client.AzAuth.xml" target="lib\net6.0\Microsoft.PowerPlatform.Dataverse.Client.AzAuth.xml" />
<file src="{signedBinDir}\{configuration}\DataverseClient-AzAuth\net472\Microsoft.PowerPlatform.Dataverse.Client.AzAuth.dll" target="lib\net472\Microsoft.PowerPlatform.Dataverse.Client.AzAuth.dll" />
<file src="{signedBinDir}\{configuration}\DataverseClient-AzAuth\net472\Microsoft.PowerPlatform.Dataverse.Client.AzAuth.xml" target="lib\net472\Microsoft.PowerPlatform.Dataverse.Client.AzAuth.xml" />
<file src="{signedBinDir}\{configuration}\DataverseClient-AzAuth\net462\Microsoft.PowerPlatform.Dataverse.Client.AzAuth.dll" target="lib\net462\Microsoft.PowerPlatform.Dataverse.Client.AzAuth.dll" />
<file src="{signedBinDir}\{configuration}\DataverseClient-AzAuth\net462\Microsoft.PowerPlatform.Dataverse.Client.AzAuth.xml" target="lib\net462\Microsoft.PowerPlatform.Dataverse.Client.AzAuth.xml" />
<file src="{signedBinDir}\{configuration}\DataverseClient-AzAuth\net48\Microsoft.PowerPlatform.Dataverse.Client.AzAuth.dll" target="lib\net48\Microsoft.PowerPlatform.Dataverse.Client.AzAuth.dll" />
<file src="{signedBinDir}\{configuration}\DataverseClient-AzAuth\net48\Microsoft.PowerPlatform.Dataverse.Client.AzAuth.xml" target="lib\net48\Microsoft.PowerPlatform.Dataverse.Client.AzAuth.xml" />
<file src="{signedBinDir}\{configuration}\DataverseClient\net6.0\Microsoft.PowerPlatform.Dataverse.Client.AzAuth.dll" target="lib\net6.0\Microsoft.PowerPlatform.Dataverse.Client.AzAuth.dll" />
<file src="{signedBinDir}\{configuration}\DataverseClient\net6.0\Microsoft.PowerPlatform.Dataverse.Client.AzAuth.xml" target="lib\net6.0\Microsoft.PowerPlatform.Dataverse.Client.AzAuth.xml" />
<file src="{signedBinDir}\{configuration}\DataverseClient\net472\Microsoft.PowerPlatform.Dataverse.Client.AzAuth.dll" target="lib\net472\Microsoft.PowerPlatform.Dataverse.Client.AzAuth.dll" />
<file src="{signedBinDir}\{configuration}\DataverseClient\net472\Microsoft.PowerPlatform.Dataverse.Client.AzAuth.xml" target="lib\net472\Microsoft.PowerPlatform.Dataverse.Client.AzAuth.xml" />
<file src="{signedBinDir}\{configuration}\DataverseClient\net462\Microsoft.PowerPlatform.Dataverse.Client.AzAuth.dll" target="lib\net462\Microsoft.PowerPlatform.Dataverse.Client.AzAuth.dll" />
<file src="{signedBinDir}\{configuration}\DataverseClient\net462\Microsoft.PowerPlatform.Dataverse.Client.AzAuth.xml" target="lib\net462\Microsoft.PowerPlatform.Dataverse.Client.AzAuth.xml" />
<file src="{signedBinDir}\{configuration}\DataverseClient\net48\Microsoft.PowerPlatform.Dataverse.Client.AzAuth.dll" target="lib\net48\Microsoft.PowerPlatform.Dataverse.Client.AzAuth.dll" />
<file src="{signedBinDir}\{configuration}\DataverseClient\net48\Microsoft.PowerPlatform.Dataverse.Client.AzAuth.xml" target="lib\net48\Microsoft.PowerPlatform.Dataverse.Client.AzAuth.xml" />
<file src="{sharedImagesDir}\Desktop\Dataverse.128x128.png" target="images\Dataverse.128x128.png" />
</files>
</package>

Просмотреть файл

@ -7,9 +7,12 @@ Notice:
Note: Only AD on FullFramework, OAuth, Certificate, ClientSecret Authentication types are supported at this time.
++CURRENTRELEASEID++
Fix for endless retry loop issue in WebAPI calls when specific error states are encountered.
Fix for Logging MSAL telemetry when using ILogger
Previously, Logs for MSAL were not written to the configured ILogger, they would only go to Trace Source and InMemory Logs.
Fix for RequestBuilder to properly honor CrmUserId and AADOid in request builder requests.
Fix for ForceServerMetadataCacheConsistency not being effective until an operation to retrieve current organization version has been executed.
If this us set to a value before any organization detail related information is retrieved, it will now cause the organization info to be retrieved from Dataverse. This is done only once.
Updated ServiceClient retry logic to use the server specified RetryAfter for Time and Concurrency throttling fault codes, in addition to Burst.
Updated ConnectionService retry logic to parse RetryAfter header as seconds instead of hours.
Dependency Changes:

Просмотреть файл

@ -24,6 +24,9 @@
<dependency id="Microsoft.Rest.ClientRuntime" version="[$PackageVersion_RestClientRuntime$,)" exclude="Build,Analyzers" />
<dependency id="Newtonsoft.Json" version="[$PackageVersion_Newtonsoft$,)" exclude="Build,Analyzers" />
<dependency id="System.Text.Json" version="[$PackageVersion_SystemTextJson$,)" exclude="Build,Analyzers" />
<dependency id="System.ServiceModel.Http" version="[$PackageVersion_System_ServiceModel_PreNet6$,)" />
<dependency id="System.ServiceModel.Primitives" version="[$PackageVersion_System_ServiceModel_PreNet6$,)" />
</group>
<group targetFramework=".NETFramework4.7.2">
<dependency id="Microsoft.Extensions.DependencyInjection" version="[$PackageVersion_Microsoft_Extensions$,)" exclude="Build,Analyzers" />
@ -35,6 +38,8 @@
<dependency id="Microsoft.Rest.ClientRuntime" version="[$PackageVersion_RestClientRuntime$,)" exclude="Build,Analyzers" />
<dependency id="Newtonsoft.Json" version="[$PackageVersion_Newtonsoft$,)" exclude="Build,Analyzers" />
<dependency id="System.Text.Json" version="[$PackageVersion_SystemTextJson$,)" exclude="Build,Analyzers" />
<dependency id="System.ServiceModel.Http" version="[$PackageVersion_System_ServiceModel_PreNet6$,)" />
<dependency id="System.ServiceModel.Primitives" version="[$PackageVersion_System_ServiceModel_PreNet6$,)" />
</group>
<group targetFramework=".NETFramework4.8">
<dependency id="Microsoft.Extensions.DependencyInjection" version="[$PackageVersion_Microsoft_Extensions$,)" exclude="Build,Analyzers" />
@ -46,6 +51,8 @@
<dependency id="Microsoft.Rest.ClientRuntime" version="[$PackageVersion_RestClientRuntime$,)" exclude="Build,Analyzers" />
<dependency id="Newtonsoft.Json" version="[$PackageVersion_Newtonsoft$,)" exclude="Build,Analyzers" />
<dependency id="System.Text.Json" version="[$PackageVersion_SystemTextJson$,)" exclude="Build,Analyzers" />
<dependency id="System.ServiceModel.Http" version="[$PackageVersion_System_ServiceModel_PreNet6$,)" />
<dependency id="System.ServiceModel.Primitives" version="[$PackageVersion_System_ServiceModel_PreNet6$,)" />
</group>
<group targetFramework="NET6.0">
<dependency id="System.Collections" version="4.3.0" exclude="Build,Analyzers" />
@ -59,8 +66,8 @@
<dependency id="System.Runtime.Serialization.Primitives" version="4.3.0" exclude="Build,Analyzers" />
<dependency id="System.Runtime.Serialization.Xml" version="4.3.0" exclude="Build,Analyzers" />
<dependency id="System.Security.Permissions" version="[$PackageVersion_SystemSecurityPermissions$,)" exclude="Build,Analyzers" />
<dependency id="System.ServiceModel.Http" version="4.10.3" exclude="Build,Analyzers" />
<dependency id="System.ServiceModel.Primitives" version="4.10.3" exclude="Build,Analyzers" />
<dependency id="System.ServiceModel.Http" version="[$PackageVersion_System_ServiceModel_PostNet6$,)" exclude="Build,Analyzers" />
<dependency id="System.ServiceModel.Primitives" version="[$PackageVersion_System_ServiceModel_PostNet6$,)" exclude="Build,Analyzers" />
<dependency id="System.Text.Json" version="[$PackageVersion_SystemTextJson$,)" exclude="Build,Analyzers" />
<dependency id="Microsoft.Extensions.DependencyInjection" version="[$PackageVersion_Microsoft_Extensions$,)" exclude="Build,Analyzers" />
<dependency id="Microsoft.Extensions.Http" version="[$PackageVersion_Microsoft_Extensions$,)" exclude="Build,Analyzers" />