NIC teaming, Windows Server Essentials and Anywhere Access

Sometimes I do IT work for my customers other than software development. A case in point was recently when I migrated a customer of mine from a peer-to-peer workgroup to a domain using Windows Server 2016 Essentials. For those of you wondering the Server Essentials SKU is a really useful one for small businesses as it doesn't require CALs for up to 25 users (more information here, albeit for the 2012 version but it still holds true)

Onto the issue at hand, PPTP, L2TP and its ilk are now gone away (by default) replaced by a newer variant, SSTP, which tunnels over HTTPS. This means having a certificate installed on the server which proves its identity. So far, so good but the Anywhere Access wizard was failing at the end for some reason.

Ports 443 and 80 were open but the wizard didn't see that they were. I could access the server using HTTP(S) but any attempt to VPN in from a client gave me the error message that The network connection was aborted by the local system

Another error that was received was shown below

Before I proceed I should note that Essentials is very much wizard-driven from a configuration standpoint. This is probably owing to its SBS heritage and the market segment that it's aimed at. I've learned where possible that you're better off using the wizards where possible as these SKUs expect things to be done in a specific way and tend to throw toys out of the pram if they're not. However, no amount of running and re-running of the wizard would work for me so I was left with no other option but to go mucking about.

In researching the issue some places offered the opinion that it was NIC teaming that was causing the issue. Personally, I didn't see why this could be the case as Windows is presenting a virtual NIC for use but there may be something in this as when I broke out the command line to see if the certs were correctly bound to the NIC they were not.

  1. You need to have the thumbprint of the certificate so, assuming that you've got it successfully installed on the server, use the Certificates MMC to view this. Note it as you'll need for later.

     

  2. What I wanted to do was to ensure that this certificate is associated with 0.0.0.0:443 and [::]:443 network bindings on the server. To get this information, from an elevated command prompt type:

     

    netsh http show ssl

     

  3. You'll get a lot of information but the part that you're interested in is the bit that shows you your IPv4 and IPv6 settings so the entries beginning 0.0.0.0:443 and [::]:443 are those respectively. For the purposes of this post you can disregard the other pieces of information, we're only interested in these two

     

  4. Next ensure that the cert is correctly bound to each of the two ports by comparing the SHA-1 Certificate Hash value below each port to that of the value you obtained earlier.

     

  5. In my case I had a mismatch and so when fixing it I deleted both bindings using the commands:

     

    [IPv4]

    netsh http delete sslcert ipport=0.0.0.0:443

     

    [IPv6]

    netsh http delete sslcert ipport=[::]:443

     

  6. Next, I installed the correct certificate to both again, using the cert hash as noted earlier (shown here by foo)

     

    [IPv4]

    netsh http add sslcert ipport=0.0.0.0:443 certhash=foo appid={ba195980-cd49-458b-9e23-c84ee0adcd75} certstorename=MY

     

    [IPv6]

    netsh http add sslcert ipport=[::]:443 certhash=foo appid={ba195980-cd49-458b-9e23-c84ee0adcd75} certstorename=MY

     

  7. Although it may not be strictly necessary, to be on the safe side here I restarted the server.

     

  8. To verify that it worked I went into the Routing and Remote Access management tool and started the service from there and success! It started and I was then able to VPN in from a client.

The moral of the story here with Essentials is to stick to the wizards where possible but not to be afraid to do things manually if the wizard isn't working out for you.

Targeting multiple versions of the .NET Framework with the same source files

I had a contract recently where I had developed a site in v4.0 of the .NET Framework and when it came time to deliver it I discovered that the target server only ran v3.5. Upgrading it was not possible unfortunately so I had to recompile the solution for v3.5.

Now, I had moved all of my shared libraries to v4 of the Framework the minute that Microsoft had issued a go-live licence in the beta stages as there were some key things I wanted to take advantage of in the new version. I had happily used them since then with no issue until this project.

I knew that a lower version of the Framework could not consume assemblies created by a higher version (the other way around works flawlessly in my experience) so how was I to get my newly downgraded website to talk to my shared libraries? The options I saw here were as follows:

  • I could create a once-off build for this customer but if there were support issues afterwards there would be a lag while I recreated these as well.
  • I could branch in TFS but my experiences of branching are, to be honest, not terribly positive.
  • I could somehow create a side-by-side project where I'd be able to produce v3.5 assemblies in tandem with v4.0 assemblies. This seemed like the best option for me and this is how I did it.

(You may have an automated way of doing this, but I only automate if I have to do something more than once and in this case I didn't envisage that)

  • Begin by copying all of the C# project files in the solution to new files. Explorer will give those new files names like My.Csharp.Project – Copy.csproj.
  • Rename them so they are identifiable as what they are going to be. I used the following convention: My.Csharp.Project.v3.5.csproj
  • Open your solution and rename the files that are in there using the same naming convention so they become My.Csharp.Project.v4.0.csproj
  • Now add the v3.5 projects into your solution, if you've named them correctly they will alternate with their v4.0 counterparts
  • One by one do the following with the v3.5 projects
  • Change the compilation version to v3.5 of the Framework
  • Change the output folders for the build versions (Debug and Release). The convention I used was:
    • bin\v3.5\release
    • bin\v3.5\debug
  • Optionally add a compiler directive (I used NET35) to the project which will allow you create version-specific code
  • Following on from c. above I added a line to my AssemblyInfo.cs file to output a different version numbers for v3.5 vs. v4.0 assemblies

    #if NET40

    [assembly: AssemblyVersion("4.0.*")]

    #elif NET35

    [assembly: AssemblyVersion("3.5.*")]

    #endif

     

  • Now revisit your v4.0 projects and change their output folders as well. The convention I used was:
    • bin\v4.0\release
    • bin\v4.0\debug
  • If you're using source control you'll need to change your project GUID as well. Open the v3.5 project file in your favourite text editor and locate the line that looks like: <ProjectGuid>{GUID here}</ProjectGuid> to a new GUID

Modelling gender in a SQL Server database

For a project that I'm currently involved in I needed to model gender in a database column. In times past I'd probably just have used a CHAR(1) and constrained it to 'M' or 'F' but that's no longer appropriate given that now the column could be required to store (off the top of my head) male, female, neuter, partially transgendered, gender reassigned male to female, gender reassigned female to male or unknown to name but a few.

As is often the case the work already exists as a standard – in this case courtesy of the NHS and their PERSON GENDER CODE classification. As a useful aside note that there are two types of gender: gender at registration (I would surmise shortly after birth?) and current gender.

This seems to closely echo the ISO 5218 standard. In one place on the site the paper is located behind a paywall and in another place it's freely downloadable.

Lastly, here's a discussion on comp.databases.theory on the same thing.