TPM (The Practical Side) : Installing MSSQL Server and .Net 3.5 in a container on Windows Server 2016 TP3 Hyper-V

5 Flares Twitter 1 Facebook 0 LinkedIn 0 Buffer 4 Email -- 5 Flares ×

Ā, upane! ka upane! A step upward, another step upward!

beside write my rants on identities and everything else from time to time I like to play in the old way, that means… “all black style”.

So let’s start from the facts:

  • I’m in love with docker
  • I am an avid reader of @frazelledazzell blog
  • I remember the first time I saw a session of @markrussinovich in 2001 at the teched (yes I’m that old…)

what does that means? I love challenges that seems apparently not possible, but let’s start from the beginning.

Microsoft is doing a real great job porting @docker on windows and released the TP3 of Windows Server 2016 who provide Docker version 1.9.0-dev, build 4376380.

You may read everything on here

The actual version has some strict requirements:

  • System running Windows Server Technical Preview 3 Server Core.
  • 10GB available storage for OS Base Image and setup scripts.
  • Administrator permissions on the machine or VM.

but most of all got a quite long list of “things” who works or not works at all on containers. The list is  here

Now if you look at the list the first row in the table is quite interesting:

    • Name : .NET
    • Version: 3,5
    • Does it Work?: NO
    • Comment :Fails to install properly

And even more interesting there’s no mention of MSSQL server in the list!

So here’s the challenge is it possible to install .net 3.5 and MSSQL Server 2014 Standard Edition (that require .net 3.5) on a docker image?

in a word? YES

Okay let say I gave myself the answer before actually trying….but I’m an old nerd who love spend the long nights in the hotel trying new stuff and I do not easily give up on things.

now before go through the steps just a little disclaimer:


Create your own docker container

Once your windows server 2016 TP3 got containers up and running and the windows core images ready create a base container.

Since we will need to run a graphical interface at some point enable the container to be used through RDP, you may get the steps here (look for the paragraph “Accessing windows server container with Remote Desktop”)

docker run –it –name mycontainer –hostname mycontainer  windowsservercore “cmd”

At this point you got you’re container ready to be reached through RDP (i.e.: mstsc yourhostip:3390)

now the funny part:

Install .net 3.5

When you install .net 3.5 you have to take care of two main points (at least to make it usable):

  • the path where the files are installed
  • The registry keys who inform other applications that a certain version of .net is installed

Do not try to install .net 3.5 through powershell since it will fail but use DISM instead.

Wait slow down kids, slow down do not run dism command yet.

Create a temporary folder on your image, it will be needed to copy the .net folders generated by the command before the command itself fail and delete everything.

Open another CMD window and after that you’re ready.

so type:

mkdir c:\yourtmpfolder

than switch to c:\Windows\Microsoft.NET\Framework64\

at this point run the command:

Dism /online /enable-feature /featurename:NetFx3 /All /LimitAccess /Source:d:\sources\sxs

monitor the Framework64 folder and when you see the .net 3.5 folders created issue the following command

xcopy * c:\youtpmfolder /E

re-run the command until the dism command fail

At this point copy back the folders in their supposed original position.

I had to run DISM 3 times to be sure I have everything copied correctly, I’m not sure if everything is really needed for MSSQL server so could be that only the .net 3.5 folder is really needed.

So we got now the files ready but we still miss the regedit part.

Open regedit (type regedit in the cmd window and hit enter…)

look for the branch:


Create the following keys:

  • v2.0.50727
  • v3.0
  • v3.5

click on v.3.5 and create the following:

  • CBS (REG_DWORD) = 1
  • Install (REG_DWORD) = 1
  • SP (REG_DWORD)=1
  • InstallPath(REG_SZ)=C:\Windows\Microsoft.NET\Framework64\v3.5\
  • Version(REG_SZ)=3.5.30729.4926

Now exit the container to stop it.

WARNING: you’re in RDP do before stop the container do a clean logoff otherwise the container may ended up to not stop in a clean way.

now commit your new image and remove you’re original container and re-create it or simply create a new one based on the new committed image.

Install MSSQL Server 2014 Standard Edition

Connect back to the container through RDP, insert/mount the MSSQL CD and run the following:

setup.exe /UIMODE=EnableUIOnServerCore /Action=Install

The lovely MSSQL wizard will appear. Remember you’re in a windows core edition so some feature will not work. In my case I’ve installed just the engine it’s all I needed.

Run the wizard, will nicely pass the .net test as per image below


Simply and nice…looking at the container task list we notice the sqlservr.exe task,in my case with pid 4156


Now looking at the host (I do not use hyper-v mode but default as container mode)


but most of all …


now before actually get out from there you have to run a couple of commands more:

First let’s change the service account for the MSSQL services.

Thanks for this great blog post:

Second we have to enable MSSQL remotely:

HINT: MSSQL Poershell will fail due the ExecutionPolicy restiction so run the script this way:

Get-Content .runme.ps1 | PowerShell.exe -noprofile

Logoff from the container, Stop it.Commit the new image

now last part connect to the MSSQL server from outside.

New-NetFirewallRule -Name “MSSQL” -DisplayName “MSSQL Protocol” -Protocol TCP -LocalPort @(1433) -Action Allow

New-NetFirewallRule -Name “ContainerMSSQL” -DisplayName “MSSQL Port for connecting to Container” -Protocol TCP -LocalPort @(1434) -Action Allow

and finally:

docker run -it –name yournewcontainer –hostname yournewcointaner  -p 1433:1433 containerimage “cmd”

(if new container is d1im-db and the image is d1im-basev5 will be something like

docker run –it  –name d1im-db –hostname d1im-db  di1m-basev5 –p 1433:1433  “cmd”

and bum you’re done. (notice the hostname that is the one docker dynamically created)


oh last thing you wondering from where it comes the first line of this blog don’t you?

here it is: