Nano Server notes, Part 1

By | May 2, 2016

Microsoft released Windows Server 2016, Technical Preview 5 (TP5) somewhere around the middle of last week and all I found time to do at the time was go download the ISO image from TechNet Evaluation Center.

My main curiosity is Nano Server; I missed TP4 (more or less) and last spent time with the TP3 release last year shortly after the Windows 10 RTM build. Nano Server has a smaller footprint than even a Windows Preinstallation Environment (WinPE) build and given that it’s “headless” and 64-bit only, I was interested to see what types of my utilities would run. That’s where I ran into the “Reverse Forwarders” issue. (Reverse Forwarders aren’t the issue, they help solve it.)

The good news is that, as noted in the “Getting Started” notes, Reverse Forwarders no longer need to be added to Nano Server — they are now part of the baseline. (“Now included by default,” it says in the roles and features table there.)

What I found in the TP3 release was that after standing up a VM running Nano Server, a lot of the console-based apps would immediately “abend” inside the remote PowerShell session. It was already a given that the UI executables weren’t going to be useful on Nano Server, but after a little research it became clear that a big issue was going to be ERROR_PROC_NOT_FOUND errors from GetProcAddress. Manually adding the Reverse Forwarders package “fixed” almost everything, but what was interesting to me was that I was still seeing a few problems.

Most of the problems were already behind me because there’s a lot of code with origins that go back 10-15 years. Most “old-school” Windows applications that needed to support a wide-range of versions use a lot of run-time dynamic linking; when DOS still roamed the land (Windows 95/Windows 98/Windows ME), it was necessary to support ANSI and Unicode code at run-time. Supporting run-time dynamic linking and Unicode probably eliminated a lot of the compatibility issues; throw on top of that x64/i386 builds and supporting the aforementioned WinPE and Nano Server isn’t too bad.

For Windows, though, it’s still a very small footprint and apparently Microsoft released the NanoServerApiScan tool last year in the post-TP4 release timeframe. So after getting the prerequisites staged in a Windows 10 VM, I ran the tool combined with the TP5 Reverse Forwarders and the Windows 10 SDK against several utilities. An example of one of the remaining issues was this:
-----------------------------------------------------------------------------
=== AdminStuff.x64.exe ===
=== D:\Testing\AdminStuff.x64.exe ===

ERRORS:

ADVAPI32.dll
AuditLookupCategoryIdFromCategoryGuid(Proc not found)

I was using AuditLookupCategoryIdFromCategoryGuid for “translating” the old and new styles of system auditing…without having looked yet, I’m guessing that Nano Server no longer works with LsaQueryInformationPolicy/LsaSetInformationPolicy and POLICY_AUDIT_EVENT_TYPE and now just uses Advanced Security Audit Policy Settings. (Or maybe it’s now heavily biased to the latter.)

So before:
if (AuditLookupCategoryIdFromCategoryGuid(pGUID, &CategoryId))

Becomes:
BOOLEAN (NTAPI* pfnAuditLookupCategoryIdFromCategoryGuid)(
_In_ const GUID* pAuditCategoryGuid,
_Out_ PPOLICY_AUDIT_EVENT_TYPE pAuditCategoryId
) = 0;

HMODULE hModAdvApi = GetModuleHandleA("ADVAPI32.DLL");
(FARPROC&)pfnAuditLookupCategoryIdFromCategoryGuid =
GetProcAddress(hModAdvApi, "AuditLookupCategoryIdFromCategoryGuid");

if (pfnAuditLookupCategoryIdFromCategoryGuid != NULL &&
(*pfnAuditLookupCategoryIdFromCategoryGuid)(pGUID, &CategoryId))

I can get away with GetModuleHandle rather than LoadLibrary/FreeLibrary here because the code is still implicitly linking to several other ADVAPI32 functions and the DLL (either the standard ones on most Windows versions or the forwarder on NanoServer) will be loaded before this can be called.