Dynamics 365 CE TLS Connectivity Issue from .NET and PowerShell

If you have been running recently into some strange unexplained connectivity issues to Dynamics 365 CE Online, then the chances are this might be due to TLS incompatibility between Dynamics and your client code.

What is the issue?

Microsoft has started to disable TLS 1.0 and TLS 1.1 support for Dynamics 365 online instances. That means only TLS 1.2 will be supported. Obviously this is for good reasons to improve security.

What is impacted?

Any of your clients or PowerShell Modules/Scripts that relies on the CRM SDK. This includes CRM development tools, CRM Package Deployment PowerShell Tools, Custom clients/portal/services and others.

Suggested Fixes?

You can find out more information about this change and potential fixes in this article. To cut a long story short, you either have to update your .NET client to 4.6.2 or provide implement a machine wide registry key to enforce highest security protocol (TLS 1.2).

How to see your current settings from code?

From .NET

Console.WriteLine(ServicePointManager.SecurityProtocol);

From PowerShell

$currentProtocol = [System.Net.ServicePointManager]::SecurityProtocol
Write-Verbose "Current Security Protocol: $currentProtocol"

This gets more complicated…

I noticed that even if you have PowerShell Cmdlets compiled in .NET 4.6.2, PowerShell will still sometimes run in its own run-time depending on the machine configuration.

So for example on my Windows 10 Machine with PS 5.1 by default I could only see SSL3 and TLS available. You will probably see the same on a .NET Client compiled using .NET 4.5.2 or earlier.

Alternative Solution…

So if you want to keep your .NET version or if you are facing the issues when running PowerShell you can try the solutions below.

If you are connecting to a known CRM instance/version. Then you force the connection to use TLS 1.2 using the code below.

From .NET

ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls12;

From PowerShell

[System.Net.ServicePointManager]::SecurityProtocol = [System.Net.SecurityProtocolType]::Tls12;

However if you are building something that may need to connect using previous security protocol, for example a generic PowerShell Module that can be used for Online and On-premises. You probably want to keep your options open. The below code will check your current settings and add TLS 1.1 and TLS 1.2 support if not already configured.

From .NET

            WriteVerbose(string.Format("Current Security Protocol: {0}", ServicePointManager.SecurityProtocol));

            if (!ServicePointManager.SecurityProtocol.HasFlag(SecurityProtocolType.Tls11))
            {
                ServicePointManager.SecurityProtocol = ServicePointManager.SecurityProtocol ^ SecurityProtocolType.Tls11;
            }
            if (!ServicePointManager.SecurityProtocol.HasFlag(SecurityProtocolType.Tls12))
            {
                ServicePointManager.SecurityProtocol = ServicePointManager.SecurityProtocol ^ SecurityProtocolType.Tls12;
            }

            WriteVerbose(string.Format("Modified Security Protocol: {0}", ServicePointManager.SecurityProtocol));<span 				data-mce-type="bookmark" 				id="mce_SELREST_start" 				data-mce-style="overflow:hidden;line-height:0" 				style="overflow:hidden;line-height:0" 			></span>

From PowerShell

#Set Security Protocol
$currentProtocol = [System.Net.ServicePointManager]::SecurityProtocol
Write-Verbose "Current Security Protocol: $currentProtocol"
if (-not $currentProtocol.HasFlag([System.Net.SecurityProtocolType]::Tls11))
{
    [System.Net.ServicePointManager]::SecurityProtocol = [System.Net.ServicePointManager]::SecurityProtocol  -bor [System.Net.SecurityProtocolType]::Tls11;
}
if (-not $currentProtocol.HasFlag([System.Net.SecurityProtocolType]::Tls12))
{
    [System.Net.ServicePointManager]::SecurityProtocol = [System.Net.ServicePointManager]::SecurityProtocol  -bor [System.Net.SecurityProtocolType]::Tls12;
}
$currentProtocol = [System.Net.ServicePointManager]::SecurityProtocol
Write-Verbose "Modified Security Protocol: $currentProtocol"

Hope this was helpful. Let me know if you have others solutions and if the above solutions work for you.

Advertisements

One thought on “Dynamics 365 CE TLS Connectivity Issue from .NET and PowerShell

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s