Windows Server 2016, expected to release in (appropriately enough) 2016, includes an installation option called Nano Server. In this article, I’ll teach you how to build a Nano Server–based VM, step by step and by using Windows PowerShell almost entirely. We’ll use Windows Server 2016 Technical Preview 3, which is the latest version as of this writing in October 2015.
Latest posts by Timothy Warner (see all)

Nano Server represents the next generation of Server Core. At Ignite 2015, Windows Server lead architect Jeffrey Snover said that Nano Server supports application containers and “born in the cloud” application deployment.

Look at these incredible stats. Compared to a Windows Server full installation, Nano Server has:

  • 93 percent smaller virtual hard disk (VHD) size
  • 80 percent fewer reboots
  • Absolutely no GUI or 32-bit subsystem
  • Absolutely no local logon

Essentially we’re looking at a small-footprint, completely headless OS platform. Cool, we get it—reduced attack surface and “bare metal” system performance. But what are Nano’s primary use cases? Here they are:

  • Compute host for Hyper-V clustered and/or non-clustered VMs
  • Storage host for clustered or non-clustered Scale-Out File Server
  • Containerized application host for “born in the cloud” applications and guest operating systems

Meeting your prerequisites

Of course, we’ll need a copy of Windows Server 2016 Technical Preview 3. It’s a free download, but make sure you reserve the time necessary for a 4.7 GB download.

In this tutorial, we’re deploying a Nano VHD to a virtual machine, so you’ll need a hypervisor. Windows 8.1 includes Hyper-V out of the box; alternatively, there’s Oracle VM VirtualBox for free. Myself, I shelled out the do-re-mi for a VMware Workstation license.

Anyway, we’re going to use a lot of Windows PowerShell here, so open the Windows PowerShell Integrated Scripting Environment (ISE) as an administrator and temporarily relax script execution settings:

Set-ExecutionPolicy –ExecutionPolicy Bypass –Scope Process

On my Windows 8.1–based administrative workstation, I will use D:\nano as my local working directory. Let’s create that folder:

New-Item –ItemType Directory –Path 'D:\nano'

Let’s mount the Windows Server 2016 TP3 ISO disk image:

Mount-DiskImage –ImagePath 'D:\isos\en_windows_server_2016_technical_preview_3_x64_dvd_6942082.iso'

My computer mounted the Server 2016 ISO image as drive G:; you can use Get-Volume to verify this. To finish up our prereqs, we’ll copy two key Nano-oriented PowerShell script files from the \NanoServer folder of our newly mounted disk image to my D:\nano working directory:

Copy-Item –Path 'G:\NanoServer\Convert-WindowsImage.ps1', 'F:\NanoServer\New-NanoServerImage.ps1' –Destination 'D:\nano'

Building the Nano VHD

We’ll now make use of those two pre-built PowerShell scripts to build ourselves a ready-to-boot Nano VHD!

First, we’ll set our PowerShell session to our D:\nano working directory and “dot source” the .ps1 files to load their enclosed functions into our runspace:

Set-Location –Path 'D:\nano'
. .\Convert-WindowsImage.ps1
. .\New-NanoServerImage.ps1

NOTE: When you type a period (“dot”), a space, and then the name of a PowerShell module, you basically dump all the module’s contents into your current runspace. In the preceding example, the dot-backslash (.\) syntax tells PowerShell that the module is located in the current working directory.

We'll use the New-NanoServerImage function to build a base Nano Server OS image. One of the coolest things about Nano Server is that you need to inject workloads into the image because there’s no side-by-side Windows component store like there is in “full” Windows.

New-NanoServerImage –MediaPath G:\ -BasePath .\Base –TargetPath .\Nano1 –ComputerName Nano1 –GuestDrivers

In the previous code, we’re installing the Hyper-V server bits (-Compute workload) and the Hyper-V guest drivers (-GuestDrivers workload). The Compute workload enables our Nano Server to act as a Hyper-V host. We’ll also be prompted for a local administrator password.

Are you wondering about stuff like domain join, what other workload packages are available, how to inject additional packages into Nano, and so on? Remember that Windows Server 2016 is still in an early stage, and much of the functionality hasn’t even been “lit up” yet. The official Nano Server blog is a place you should visit often for updates.

Starting Nano for the first time

In my environment, I’ll use one of my Windows Server 2012 R2 member servers as a Hyper-V host that, in turn, owns our new Nano VM.

On my member server, we’ll install Hyper-V from an elevated PowerShell console:

Install-WindowsFeature -Name Hyper-V -Restart

Now, we’ll create the new VM by using our newly created Nano Server VHD. Note that I moved my D:\nano build directory from my Windows 8.1 workstation to data drive E: on my server. Also, I created a Hyper-V switch named Internal that’s linked to the host-guest internal VM network.

New-VM -Name 'Nano1' -MemoryStartupBytes 512MB -SwitchName 'Internal' -VHDPath 'E:\nano\Nano1\Nano1.vhd' -Path 'E:\vms\Nano1' -Generation 1

Let’s start it up!

Start-VM -Name 'Nano1'

My lab network includes a DHCP server, so to begin we’ll let the Nano VM boot with a dynamic IPv4 address. When we connect to Nano from our Hyper-V server, we’re prompted to authenticate:

Authenticating to Nano Server

Authenticating to Nano Server

Use Administrator along with the password you defined when you built the VHD image.

On the next screen, we’ll verify our initial settings—namely, our hostname, workgroup/domain configuration, and IPv4 address.

Verifying the Nano Server configuration

Verifying the Nano Server configuration

Tab to Networking and press ENTER to inspect (but not modify, sadly) our TCP/IP configuration.

In Windows Server 2016 Technical Preview 3, Nano networking settings

In Windows Server 2016 Technical Preview 3, Nano networking settings are not modifiable locally.

Managing Nano Server day to day

In one word, we manage Nano Server by using remoting. If the GUI is your “thing,” then you can use Server Manager to load your Nano Server and manage its services graphically.

Windows Server 2016 supports an awesome technology called PowerShell Direct that enables you to send PowerShell from a Hyper-V host directly to its compatible guests, even if the guests don’t have an active networking stack! Isn’t that awesome?

In the meantime, we can use traditional WS-Man PowerShell remoting to configure our new Nano box. For instance, let’s create a remoting session from our GUI server and give the Nano Server a static IP configuration.

First, I need to modify my server’s TrustedHosts cache because Nano runs in a workgroup at this point in my environment:

Set-Item -Path WSMan:\localhost\client\TrustedHosts -Value 'Nano1' -Force

Then, I’ll enter an interactive remote session with Nano1 and relax the script execution policy temporarily:

Enter-PSSession -ComputerName 'Nano1' -Credential 'Administrator'
Set-ExecutionPolicy -ExecutionPolicy Bypass -Scope Session

Finally, we’ll set our new static IPv4 configuration using the following wonderful code snippet that I adapted from the Admin Arsenal blog. I would definitely suggest that you script this out in the Windows PowerShell ISE rather than in a console session:

# Set up our TCP/IP configuration as variables
$IP = ''
$MaskBits = '24'
$Gateway = ''
$Dns = ''
$IPType = 'IPv4'

# Retrieve the network adapter that you want to configure
$adapter = Get-NetAdapter | Where-Object { $_.Status -eq 'Up' }

# Remove any existing IP address and/or default gateway from our IPv4 network adapter
If (($adapter | Get-NetIPConfiguration).IPv4Address.IPAddress) {
        $adapter | Remove-NetIPAddress -AddressFamily $IPType -Confirm:$false
If (($adapter | Get-NetIPConfiguration).Ipv4DefaultGateway) {
        $adapter | Remove-NetRoute -AddressFamily $IPType -Confirm:$false
# Configure the IP address and default gateway
$adapter | New-NetIPAddress -AddressFamily $IPType -IPAddress $IP -PrefixLength $MaskBits -DefaultGateway $Gateway

# Configure the DNS client server IP address
$adapter | Set-DnsClientServerAddress -ServerAddresses $DNS

Thanks for reading! I hope you found this article informative.

1 Comment
  1. Avatar
    Justin 7 years ago

    Running this script causes the Nano Server to blow up.  It removes IP address info then poof, no more connection.  Nano Server can no longer log into domain.  Once you login into it locally, DHCP is disabled and IP address is 169.x.x.x

    This is pretty much how NOT to do it.

Leave a reply

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


© 4sysops 2006 - 2023


Please ask IT administration questions in the forums. Any other messages are welcome.


Log in with your credentials


Forgot your details?

Create Account