- Use Azure Bastion as a jump host for RDP and SSH - Tue, Apr 18 2023
- Azure Virtual Desktop: Getting started - Fri, Apr 14 2023
- Understanding Azure service accounts - Fri, Mar 31 2023
Nano Server in a nutshell
Microsoft has played with the user interface quite a bit over the years. Windows Server 2008 gave us the Server Core option. Windows Server 2012/R2 introduced Minimal Server Configuration, as well as the ability to switch GUI layers without reinstalling the operating system.
Nano Server is a Windows Server 2016 installation option that provides a tiny disk footprint (less than 1 GB), a minimal attack surface, a stripped-down .NET Framework, and absolutely no GUI. According to Windows Server Lead Architect Jeffrey Snover, Nano Server offers:
- 93 percent smaller VHD size
- 92 percent fewer security bulletins
- 80 percent fewer reboots
The reason for all three of those points is the fact that all supported Windows Server roles and features live off-box. In other words, you have to manually install the available workloads:
- Storage
- Clustering
- Hyper-V
- Docker containers
As of January 2016, Windows Server 2016 TP4 includes a radically different Nano Server to what we had in previous builds. Let’s install an on-premises Nano Server virtual machine and see what’s new and what’s changed.
Building our Nano Server
I downloaded the Windows Server 2016 TP4 ISO from the Microsoft Evaluation Center. From an elevated Windows PowerShell session, I’ll next mount the DVD image to my Windows 8.1 workstation’s file system:
Mount-DiskImage 'C:\Users\Tim\Downloads\en_windows_server_2016_technical_preview_4_x64_dvd_7258292.iso'
Next, I’ll (a) create a folder for the Nano VM on my C: drive; (b) switch my PowerShell session’s focus to that location; and (c) copy the two PowerShell scripts (technically one module and one script) from the mounted ISO to our C:\nanoserver working directory:
New-Item -ItemType Directory -Path 'C:\nanoserver' Set-Location 'C:\nanoserver' Copy-Item -Path E:\NanoServer\Convert-WindowsImage.ps1 -Destination 'C:\nanoserver' Copy-Item -Path E:\NanoServer\NanoServerImageGenerator.psm1 -Destination 'C:\nanoserver'
I’ll manually import the NanoServerImageGenerator module into my current runspace; we’ll use the module’s enclosed New-NanoServerImage advanced function momentarily:
Import-Module -Name .\NanoServerImageGenerator.psm1
Let’s build ourselves a Nano Server Generation 1 virtual hard disk (VHD) file!
New-NanoServerImage –MediaPath E:\ -BasePath .\Base –TargetPath .\NanoServer.vhd –ComputerName NanoServer -Compute -OEMDrivers -EnableRemoteManagementPort
Let me explain what I did with that previous one-liner:
- MediaPath points to the mounted Windows Server 2016 DVD. Remember that Nano Server gets all installation materials off-box.
- The Base directory contains a local copy of any feature packages and drivers that you’ve injected into the Nano VHD.
- The Compute package enables Nano to act as a Hyper-V host.
- The OEMDrivers package includes common original equipment manufacturer (OEM) drivers.
- EnableRemoteManagementPort creates a WinRM endpoint, which is crucial for remote PowerShell-based administration.
I use Oracle VM VirtualBox on my workstation, so I created a virtual machine and attached my new C:\nanoserver\nanoserver.vhd virtual hard disk to that VM.
Creating our Nano Server VM using VirtualBox
Nano Server – local administration
At the 2015 Ignite conference, Jeffrey Snover told me he wanted the Nano Server local display to display You can’t do that! and do nothing else. That statement underscored Jeffrey’s strong belief that servers should not support either GUIs or local logon unless absolutely necessary.
Microsoft must have received a good deal of customer feedback on this issue, because Nano in Windows Server 2016 TP4 includes (limited) local administration support. For instance, this is what you see when you boot a Nano Server:
The Nano Server logon screen
I specified a local administrator password earlier when I ran New-NanoServerImage, so I’ll supply that here. The VM is not part of a domain, so I’ll use the server’s nanoserver hostname in the Domain: field. Drum roll please… Here’s the Nano Server Recovery Console:
Nano Server Recovery Console
Follow the keyboard navigation instructions at the bottom of the screen. For instance, press TAB and ENTER to switch to the Networking page, and then press ENTER a second time to see your NIC details:
Network adapter settings in Nano Server
Next, I’ll press F11 and then F4 and give my Nano Server a static IPv4 configuration:
Giving the Nano Server a static IPv4 address
Press ENTER to save and ESC to move backward through the navigation screens. I might be missing something, but I was unable to discover how to change the hostname, system time zone, and so forth from the Nano Recovery Console. It’s a safe bet to say that those features simply aren’t implemented yet.
Nano Server – remote administration
The bottom line is that Nano Server was developed to be administered remotely. Period. End of sentence. So, to that end, I brought up a second virtual machine, this one running Windows Server 2016 TP4 with the full GUI, and placed it on the same network subnet as our Nano Server box.
Windows Server 2016: it looks like Windows 10!
I fired up an elevated Windows PowerShell ISE session on my GUI server. I’ll start by creating a credential object to store the Nano Server VM’s local administrator username and password. Admittedly, this is a hacky approach, but I’m not concerned with security in my development environment.
$username = 'nanoserver\administrator' $password = 'P@$$w0rd' | ConvertTo-SecureString -AsPlainText -Force $cred = New-Object -TypeName System.Management.Automation.PSCredential -ArgumentList $username, $password
Because I’d like to disconnect and reconnect to my Nano Server session at will, I’ll create a persistent PSSession object:
New-PSSession -Name 'nanosession' -Credential $cred -ComputerName 'nanoserver'
Finally, I’ll enter the session:
Enter-PSSession -Name 'nanosession'
Let’s get a run of the services included in a “vanilla” Nano Server build:
PS C:\> Get-ChildItem -Path 'C:\NanoServer\Base\Packages\' | Select-Object -Property Name Name ---- Microsoft-NanoServer-Compute-Package.cab Microsoft-NanoServer-Containers-Package.cab Microsoft-NanoServer-DCB-Package.cab Microsoft-NanoServer-Defender-Package.cab Microsoft-NanoServer-DNS-Package.cab Microsoft-NanoServer-DSC-Package.cab Microsoft-NanoServer-FailoverCluster-Package.cab Microsoft-NanoServer-Guest-Package.cab Microsoft-NanoServer-IIS-Package.cab Microsoft-NanoServer-NPDS-Package.cab Microsoft-NanoServer-OEM-Drivers-Package.cab Microsoft-NanoServer-Storage-Package.cab Microsoft-OneCore-ReverseForwarders-Package.cab Microsoft-Windows-Server-SCVMM-Compute-Package.cab Microsoft-Windows-Server-SCVMM-Package.cab
Managing Nano Server packages
We’ll cover domain join in another article. In the meantime, I want to finish up today by teaching you how to inject feature packages into a Nano Server VHD. I stopped my nanoserver VM and moved the NanoServer working directory to my Windows Server 2016 TP4 box. Sadly, you need the “latest and greatest” DISM version (from the Windows ADK) to inject features into Nano, or even to use native PowerShell commands such as Add-WindowsPackage.
Let’s start by firing up an elevated PowerShell session and mounting NanoServer.vhd to the file system:
Mount-DiskImage -ImagePath 'C:\nanoserver\NanoServer.vhd'
Next, we’ll list the available packages from our Nano Server working directory (these were copied from the Windows Server 2016 TP4 installation media earlier when we built our Nano Server VHD):
PS C:\> Get-ChildItem -Path 'C:\NanoServer\Base\Packages\' | Select-Object -Property Name Name ---- Microsoft-NanoServer-Compute-Package.cab Microsoft-NanoServer-Containers-Package.cab Microsoft-NanoServer-DCB-Package.cab Microsoft-NanoServer-Defender-Package.cab Microsoft-NanoServer-DNS-Package.cab Microsoft-NanoServer-DSC-Package.cab Microsoft-NanoServer-FailoverCluster-Package.cab Microsoft-NanoServer-Guest-Package.cab Microsoft-NanoServer-IIS-Package.cab Microsoft-NanoServer-NPDS-Package.cab Microsoft-NanoServer-OEM-Drivers-Package.cab Microsoft-NanoServer-Storage-Package.cab Microsoft-OneCore-ReverseForwarders-Package.cab Microsoft-Windows-Server-SCVMM-Compute-Package.cab Microsoft-Windows-Server-SCVMM-Package.cab
Why don’t we inject the IIS package so Nano can host web content? We use Add-WindowsPackage to make that happen:
PS C:\nanoserver\base\Packages> Add-WindowsPackage -Path . -PackagePath .\Microsoft-NanoServer-IIS-Package.cab
After we dismount our VHD image, we can restart our Nano VM and we’ll be in business!
Dismount-DiskImage -ImagePath 'C:\nanoserver\NanoServer.vhd'
Took me ages to work out what was going wrong…
I built my nano vhd with no modules, then came to add the modules & kept getting an error. Even updated my dism.exe even though i’m running this on a 2016 server box (call it desperation). However the issue was with the line:
PS C:\nanoserver\base\Packages> Add–WindowsPackage –Path . –PackagePath .\Microsoft–NanoServer–IIS–Package.cab
If “.” is the current directory (as shown) then of course this won’t work as you’ve not pointed it at the mounted drive. You need
PS C:\nanoserver\base\Packages> Add–WindowsPackage –Path x: –PackagePath .\Microsoft–NanoServer–IIS–Package.cab
where X: is the drive that mount-diskimage mounted the VHD at.
😐