Azure, PowerShell and DLL hell

It’s great that Azure is supported so extensively within Windows PowerShell – it really helps with automating builds and adopting a continual delivery / DevOps approach however eventually, in my experience, you’ll find yourself wanting to supplement what’s available from Microsoft with some Cmdlets of your own. Sure you can access .Net from PowerShell but sometimes C# is just more expressive and maintainable.

Of course this is simple enough to do and an example of implementing Cmdlets that use the Storage and Service Bus SDKs to create and configure resources can be found in the Application Support framework (here’s a direct link to the relevant project).

However I guarantee you that given the pace of change in the Azure space then at some point you’ll hit a DLL binding issue. Your Cmdlet will reference a different version of the Storage DLL or you’ll be using NewtonSoft.Json v7 while the Storage SDK is using v6 or vice versa and you’ll get one of those delightful can’t find DLL issues. And here I was thinking that at one point .Net was supposed to solve DLL hell!

Fortunately there’s a fairly simple solution to this: the PowerShell executable is a .Net application like any other and you can add binding redirects to a powershell.exe.config file. On a clean Windows machine this file doesn’t exist but you can create it easily enough using notepad or your text editor of choice. If you’re using a 32-bit operating system then PowerShell can be found in the folder:

C:\Windows\System32\WindowsPowerShell\v1.0

Or on a 64-bit operating system in:

C:\Windows\SysWOW64\WindowsPowerShell\v1.0

In that folder either create a new file or edit the existing one – you’ll probably need to run your text editor with Administrator privileges. As an example my current powershell.exe.config file looks like this:

<?xml version="1.0" encoding="utf-8"?>
<configuration>
  <runtime>
    <assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
      <dependentAssembly>
        <assemblyIdentity name="Microsoft.Data.OData" publicKeyToken="31bf3856ad364e35" />
        <bindingRedirect oldVersion="0.0.0.0-5.6.4.0" newVersion="5.6.4.0" />
      </dependentAssembly>
      <dependentAssembly>
        <assemblyIdentity name="Microsoft.Data.Edm" publicKeyToken="31bf3856ad364e35" />
        <bindingRedirect oldVersion="0.0.0.0-5.6.4.0" newVersion="5.6.4.0" />
      </dependentAssembly>
      <dependentAssembly>
        <assemblyIdentity name="Microsoft.Data.Services.Client" publicKeyToken="31bf3856ad364e35" />
        <bindingRedirect oldVersion="0.0.0.0-5.6.4.0" newVersion="5.6.4.0" />
      </dependentAssembly>
      <dependentAssembly>
        <assemblyIdentity name="System.Spatial" publicKeyToken="31bf3856ad364e35" />
        <bindingRedirect oldVersion="0.0.0.0-5.6.4.0" newVersion="5.6.4.0" />
      </dependentAssembly>
      <dependentAssembly>
        <assemblyIdentity name="Newtonsoft.Json" publicKeyToken="30ad4fe6b2a6aeed" />
        <bindingRedirect oldVersion="0.0.0.0-7.0.0.0" newVersion="7.0.0.0" />
      </dependentAssembly>
    </assemblyBinding>
  </runtime>
</configuration>

Hope that helps with any PowerShell binding issues.

One thought on “Azure, PowerShell and DLL hell

  1. Yuri Bondarchuk

    It is known issue with Newtonsoft.Json

    I described it where
    http://stackoverflow.com/questions/31608983/newtonsoft-json-net-version-incompatibility-dll-hell

    The problem is that Newtonsoft release incompatible versions of Newtonsoft.Json.dll with same strong name. And if any other application install different version Newtonsoft.Json.dll into the GAC then all products that use Newtonsoft.Json.dll can potentially break, with really strange exceptions

    I reported this issue to creator of Newtonsoft.Json
    https://github.com/JamesNK/Newtonsoft.Json/issues/615

    But he close it, and resolution shows that he does not understand how .NET assembly versioning works

    Reply

Leave a Reply

Your email address will not be published. Required fields are marked *