[Updated: December 6th, 2015 – Nano Server 2016 Technical Preview 4 support]
Nano Server is a new installation option in Windows Server 2016 built for the cloud. It has been announced by Microsoft in April 2015 and is going to be shipped with Windows Server 2016 next year.
What makes Nano Server very special?
- A very small disk footprint compared to traditional Windows Server deployments (500 MB instead of multiple GB).
- A very limited attack surface.
- A very limited number of components, which means fewer updates and fewer reboots.
- Much faster deployment on virtual and bare-metal due to the reduced footprint.
How is this possible?
In short, the OS has been stripped from everything that is not needed in a cloud environment, in particular the UI stack, the x86 subsystem (WOW64), MSI installer support and unnecessary API.
Windows Server and System Center 2016 TP4 is publicly available now, and one of the key scenarios that’s available in Technical Preview 4 is the following:
- Nano Server (Enhanced in TP4 – Covered in this post).
- Windows Server Containers (Covered here), and Hyper-V Containers.
- Storage Spaces Direct (Enhanced in TP4 – Covered in the next post).
- Switch Embedded Teaming (Covered here).
There are a number of changes and enhancement in TP4 builds. The first one is renaming the Emergency Management Console (EMC) to Nano Server Recovery Console, the second one is the inclusion of Windows PowerShell script module that streamline the process of creating a NanoServer Virtual Machine, and last but not least is the inclusion of additional packages (Nano Containers, DSC, IIS Server, DNS Server, MPIO, DCB, SCOM and SCVMM agent).
What is the Nano Server Recovery Console?
The purpose of the Recovery Console, is to provide direct local access to a Nano Server OS in order to re-establish remote network connectivity. Please note that it does not provide you command line access neither PowerShell access locally, however it does provide you the ability to fix whatever might be causing the remote management tool (Remote PowerShell) to no longer work.
In Windows Server 2016 TP4, the Nano server team have added the following capabilities that you can manage through the Nano Server Recovery Console:
- Show computer name
- Show domain/workgroup
- Logon / Logoff
- Shutdown / Restart
- Enable / Disable NIC
- Show IPv4 / IPv6 address
- Show Gateway
- Show Primary / Secondary DNS
- Show MAC Address
- Show network driver name
- Show network driver version
- Show network driver date
- Show network driver provider
- Set Firewall
- Set Networking
You can select Networking option, and on the network settings page, this where you can list all your network cards, then you can select which NIC you want to see.
By pressing F4, you can Toggle the State (Disable / Enable) for a particular NIC.
By pressing F10, you can see the routing table, and by pressing F10 again, you can Add a static route.
By pressing F11, you can Toggle the DHCP State, and by pressing ENTER, you can set/update the NIC IPv4 address for a particular NIC.
By pressing F12, you can Toggle the DHCP State, and by pressing ENTER, you can set/update the NIC IPv6 address for a particular NIC.
You can select Firewall option, and on the Firewall Rules page, this where you can view all the rules, then you can select which Rule you want to see.
By pressing F4, you can Toggle the State (Disable / Enable) for a particular Firewall Rule.
In today’s blog post, I will share with you on how to build a Hyper-V Cluster running on Nano Server in a Hyper-V Virtual Machines using PowerShell Direct.
I want to point out that this is not supported yet (used for demo purposes only), I am using Nested Virtualization to make it happen.
All you need to do is:
1. Mount the ISO of Windows Server 2016 TP4 installation media.
2. Change to “NanoServer” directory on the TP4 installation media.
3. Import NanoServerImageGenerator.psm1 module.
4. Create a VHDX that contains the Compute, Clustering and GuestDrivers packages.
5. Create two NanoServer Virtual Machines.
6. Create and configure Hyper-V Cluster with PowerShell Direct.
7. Assume you have a Storage Spaces Direct (S2D) as backend storage for Hyper-V.
Step 1
The script to create Nano image should look something like this:
$NanoVMParamHash01 = @{ MediaPath = 'E:\' BasePath = 'C:\NanoServer\' TargetPath = 'D:\Hyper-V\NANO-HV01\NANO-HV01.VHDX' AdministratorPassword = $Password ComputerName = 'NANO-HV01' Compute = $True Clustering = $True GuestDrivers = $True EnableRemoteManagementPort = $True Language = 'en-us' DomainName = 'contoso.com' IPv4Address = '192.168.1.100' IPv4SubnetMask = '255.255.255.0' IPv4Gateway = '192.168.1.1' InterfaceNameOrIndex = 'Ethernet' } $NanoVMParamHash02 = @{ MediaPath = 'E:\' BasePath = 'C:\NanoServer\' TargetPath = 'D:\Hyper-V\NANO-HV02\NANO-HV02.VHDX' AdministratorPassword = $Password ComputerName = 'NANO-HV02' Compute = $True Clustering = $True GuestDrivers = $True EnableRemoteManagementPort = $True Language = 'en-us' DomainName = 'contoso.com' IPv4Address = '192.168.1.101' IPv4SubnetMask = '255.255.255.0' IPv4Gateway = '192.168.1.1' InterfaceNameOrIndex = 'Ethernet' } New-NanoServerImage @NanoVMParamHash01 New-NanoServerImage @NanoVMParamHash02
Run above script from normal PowerShell console on your Hyper-V 2016 TP4 host domain joined and not from PowerShell ISE.
Step 2
Preparing your Hyper-V Host Server to manage and deploy NanoServer Virtual Machines
Install-WindowsFeature -Name Hyper-V, RSAT-Hyper-V-Tools, Hyper-V-Tools, Hyper-V-PowerShell, RSAT-Clustering, RSAT-Clustering-MGMT, RSAT-AD-PowerShell -Verbose
Step 3
One important point to mention that starting with Windows Server 2016 TP4, if you create NanoServer image as VHDX, you need to use Gen 2 VM, and if you create the image as VHD, then you need to use Gen 1 VM instead. I strongly recommend using Gen 2 VM.
We will create two Gen2 Virtual Machines (NANO-HV01, NANO-HV02) and then configuring them using PowerShell Direct.
# CREATE NANO VIRTUAL MACHINES $vSwitchName01 = "NAT_vSwitch" $vSwitchName02 = "PVT_vSwitch" $InstallRoot = "D:\Hyper-V" $CSVVLAN = 7 $LMVLAN = 9 1..2 | % { New-VHD -Path ($InstallRoot + "\NANO-HV0$_\NanoServer_D.vhdx") -SizeBytes 50GB -Dynamic New-VM -VHDPath ($InstallRoot + "\NANO-HV0$_\NANO-HV0$_.vhdx") -Generation 2 -MemoryStartupBytes 4GB -Name NANO-HV0$_ -Path $InstallRoot -SwitchName $vSwitchName01 Set-VMProcessor -VMName NANO-HV0$_ -Count 4 Set-VM -VMName NANO-HV0$_ -AutomaticStopAction ShutDown -AutomaticStartAction Nothing Enable-VMIntegrationService NANO-HV0$_ -Name "Guest Service Interface" Rename-VMNetworkAdapter -VMName NANO-HV0$_ -NewName "MGMT" Set-VMNetworkAdapter -VMName NANO-HV0$_ -Name "MGMT" -DeviceNaming On Add-VMScsiController -VMName NANO-HV0$_ Add-VMHardDiskDrive -VMName NANO-HV0$_ -ControllerType SCSI -ControllerNumber 1 -ControllerLocation 0 -Path ($InstallRoot + "\NANO-HV0$_\NanoServer_D.vhdx") Start-VM -Name NANO-HV0$_ | Out-Null }
Step 4
Configure NANO-HV01 and NANO-HV02 virtual machines using PowerShell Direct.
$DomainPassword = ConvertTo-SecureString -String "P@ssw0rd" -AsPlainText -Force $DomainCred = New-Object -TypeName System.Management.Automation.PSCredential -ArgumentList "Contoso\Administrator", $DomainPassword $LocalPassword = ConvertTo-SecureString -String "P@ssw0rd" -AsPlainText -Force # Set DNS Server NANO-HV01 & NANO-HV02 1..2 | % { $LocalCred = New-Object System.Management.Automation.PSCredential ("NANO-HV0$_\Administrator", $LocalPassword) $NanoDNS = '192.168.1.9' Invoke-Command -VMName NANO-HV0$_ -Credential $LocalCred -ScriptBlock { Param ($NanoDNS) Set-ExecutionPolicy -ExecutionPolicy Unrestricted -Force -Confirm:$false Set-DnsClientServerAddress -InterfaceAlias "Ethernet" -ServerAddresses $NanoDNS ipconfig /flushdns ipconfig /registerdns }-ArgumentList $NanoDNS } # Add Additional vmNICs "Cluster, Live Migration, Nested-vSwitch" $vSwitchName01 = "NAT_vSwitch" $vSwitchName02 = "PVT_vSwitch" 1..2 | % { Add-VMNetworkAdapter -VMName NANO-HV0$_ -SwitchName $vSwitchName02 -Name "Cluster" -Passthru | Set-VMNetworkAdapter -DeviceNaming On Add-VMNetworkAdapter -VMName NANO-HV0$_ -SwitchName $vSwitchName02 -Name "LiveMigration" -Passthru | Set-VMNetworkAdapter -DeviceNaming On Add-VMNetworkAdapter -VMName NANO-HV0$_ -SwitchName $vSwitchName01 -Name "Nested-vSwitch" -Passthru | Set-VMNetworkAdapter -DeviceNaming On -MacAddressSpoofing On Stop-vm NANO-HV0$_; Start-vm NANO-HV0$_ } Sleep 10 # Configure NANO-HV01 Invoke-Command -VMName NANO-HV01 -Credential $DomainCred -ScriptBlock { # Configure Firewall Set-NetFirewallRule -DisplayName "File and Printer Sharing (Echo Request - ICMPv4-In)" -Profile Any -Enabled True -Direction Inbound -Action Allow Set-NetFirewallRule -DisplayName "File and Printer Sharing (Echo Request - ICMPv6-In)" -Profile Any -Enabled True -Direction Inbound -Action Allow Set-NetFirewallRule -DisplayName "Failover Clusters (UDP-In)" -Profile Any -Enabled True -Direction Inbound -Action Allow Set-NetFirewallRule -DisplayName "Failover Clusters (TCP-In)" -Profile Any -Enabled True -Direction Inbound -Action Allow # Rename & Configure vmNICs $NICs = Get-NetAdapterAdvancedProperty | Where-Object -Property DisplayName -eq "Hyper-V Network Adapter Name" foreach ($NIC in $NICs) { $NICName = $NIC.Name $NicNewName = $Nic.DisplayValue Get-NetAdapter -Name $NicName | Rename-NetAdapter -NewName $NicNewName } New-NetIPAddress -InterfaceAlias Cluster -IPAddress 10.1.7.110 -AddressFamily IPv4 -PrefixLength 24 New-NetIPAddress -InterfaceAlias LiveMigration -IPAddress 10.1.9.110 -AddressFamily IPv4 -PrefixLength 24 # Remove DNS registration from Cluster vmNIC Adapter Set-DNSClient –InterfaceAlias “Cluster” –RegisterThisConnectionsAddress $false # Remove DNS registration from LiveMigration vmNIC Adapter Set-DNSClient –InterfaceAlias “LiveMigration” –RegisterThisConnectionsAddress $false # Initialize RAW Disk Get-Disk | Where partitionstyle -eq 'RAW' | Initialize-Disk -PartitionStyle GPT -PassThru | New-Partition -AssignDriveLetter -UseMaximumSize | Format-Volume -FileSystem NTFS -NewFileSystemLabel "Hyper-V" -Confirm:$false } # Configure NANO-HV02 Invoke-Command -VMName NANO-HV02 -Credential $DomainCred -ScriptBlock { Set-ExecutionPolicy -ExecutionPolicy Unrestricted -Force -Confirm:$false # Configure Firewall Set-NetFirewallRule -DisplayName "File and Printer Sharing (Echo Request - ICMPv4-In)" -Profile Any -Enabled True -Direction Inbound -Action Allow Set-NetFirewallRule -DisplayName "File and Printer Sharing (Echo Request - ICMPv6-In)" -Profile Any -Enabled True -Direction Inbound -Action Allow Set-NetFirewallRule -DisplayName "Failover Clusters (UDP-In)" -Profile Any -Enabled True -Direction Inbound -Action Allow Set-NetFirewallRule -DisplayName "Failover Clusters (TCP-In)" -Profile Any -Enabled True -Direction Inbound -Action Allow # Configure vmNICs # Rename & Configure vmNICs $NICs = Get-NetAdapterAdvancedProperty | Where-Object -Property DisplayName -eq "Hyper-V Network Adapter Name" foreach ($NIC in $NICs) { $NICName = $NIC.Name $NicNewName = $Nic.DisplayValue Get-NetAdapter -Name $NicName | Rename-NetAdapter -NewName $NicNewName } New-NetIPAddress -InterfaceAlias Cluster -IPAddress 10.1.7.111 -AddressFamily IPv4 -PrefixLength 24 New-NetIPAddress -InterfaceAlias LiveMigration -IPAddress 10.1.9.111 -AddressFamily IPv4 -PrefixLength 24 # Remove DNS registration from Cluster vmNIC Adapter Set-DNSClient –InterfaceAlias “Cluster” –RegisterThisConnectionsAddress $false # Remove DNS registration from LiveMigration vmNIC Adapter Set-DNSClient –InterfaceAlias “LiveMigration” –RegisterThisConnectionsAddress $false # Initialize RAW Disk Get-Disk | Where partitionstyle -eq 'RAW' | Initialize-Disk -PartitionStyle GPT -PassThru | New-Partition -AssignDriveLetter -UseMaximumSize | Format-Volume -FileSystem NTFS -NewFileSystemLabel "Hyper-V" -Confirm:$false }
Step 4
Create and configure Hyper-V Nano Cluster.
# Creating Nano Hyper-V Cluster with PowerShell Direct $DomainPassword = ConvertTo-SecureString -String "P@ssw0rd" -AsPlainText -Force $DomainCred = New-Object -TypeName System.Management.Automation.PSCredential -ArgumentList "Contoso\Administrator", $DomainPassword $clustername = "NANO-HV" $IPAddress = "192.168.1.103" New-Cluster -Name $clustername -Node NANO-HV01, NANO-HV02 -StaticAddress $IPAddress -NoStorage -Verbose # Rename Nano Cluster Network Names to Match Function and Update Cluster Network Roles (Get-ClusterNetwork -Cluster $clustername | ?{$_.Address -eq "192.168.1.0"}).name = "ManagementOS" # Role 3 = Enabled for client and cluster communication (Get-ClusterNetwork -Cluster $clustername -Name "ManagementOS").Role = 3 (Get-ClusterNetwork -Cluster $clustername | ?{$_.Address -eq "10.1.9.0"}).name = "LiveMigration" # Role 1 = Enabled for Cluster Communication only (Get-ClusterNetwork -Cluster $clustername -Name "LiveMigration").Role = 1 (Get-ClusterNetwork -Cluster $clustername | ?{$_.Address -eq "10.1.7.0"}).name = "CSV" # Role 1 = Enabled for Cluster Communication only (Get-ClusterNetwork -Cluster $clustername -Name "CSV").Role = 1 # Create File Share Witness on an existing Scale-Out File Server with PowerShell Direct Invoke-Command -VMName S2D2 -Credential $DomainCred -ScriptBlock { md C:\ClusterStorage\CSV01\FSW New-SmbShare -Name VMs -Path C:\ClusterStorage\CSV01\VMs -FullAccess Contoso.com\Administrator, Contoso.com\NANO-HV01$, Contoso.com\NANO-HV02$, Contoso.com\NANO-HV$ Set-SmbPathAcl -ShareName VMs } # Configure Hyper-V Nano Cluster with File Share Witness Set-ClusterQuorum -Cluster $clustername –FileShareWitness \\S2D-SOFS\FSW # Configuring SMB Constrained Delegation (require the installation of the Active Directory module for Windows PowerShell) $Storage = "S2D-SOFS" Enable-SmbDelegation –SmbServer $storage –SmbClient NANO-HV01 -Verbose Enable-SmbDelegation –SmbServer $storage -SmbClient NANO-HV02 -Verbose Enable-SmbDelegation –SmbServer $storage -SmbClient NANO-HV -Verbose # Configure Nano Hyper-V Settings for Scale-Out File Server Usage with PowerShell Direct $vmhosts =@("NANO-HV01", "NANO-HV02") $vhdpath = "\\S2D-SOFS\VMs\" $vmconfigpath = "\\S2D-SOFS\VMs\" $lmsettings = "5" foreach ($vmhost in $vmhosts) { Set-VMHost -ComputerName $vmhost -MaximumVirtualMachineMigrations $lmsettings -VirtualHardDiskPath $vhdpath -VirtualMachinePath $vmconfigpath -VirtualMachineMigrationAuthenticationType Kerberos -Verbose New-VMSwitch -ComputerName $vmhost -NetAdapterName "Nested-vSwitch" -Name "Ext_vSwitch" -AllowManagementOS $false } # Enable Nested Virtualization for NanoServer Nodes 1..2 | % { Stop-VM -Name NANO-HV0$_ Invoke-WebRequest https://raw.githubusercontent.com/Microsoft/Virtualization-Documentation/master/hyperv-tools/Nested/Enable-NestedVm.ps1 -OutFile ~/Enable-NestedVm.ps1 ~/Enable-NestedVm.ps1 -VmName NANO-HV0$_ Start-VM -Name NANO-HV0$_ } # Create VM on Nano Hyper-V Cluster $VM = "NANO-VM01" Invoke-Command -VMName NANO-HV01 -Credential $DomainCred -ScriptBlock { New-VM -Name $VM -MemoryStartupBytes 1GB -Generation 2 -VHDPath \\S2D-SOFS\VMs\ServerDataCenter_TP4.vhdx -SwitchName "Ext_vSwitch" } -ArgumentList $VM # Make the VM Highly Available $clustername = "NANO-HV" Add-ClusterVirtualMachineRole -VMName $VM -Cluster $Clustername -Verbose # Start VM (Welcome to Nested Virtualization!) Start-VM -ComputerName NANO-HV01 -Name $vm –Verbose
Here you go… Hyper-V Cluster running on NanoServer in a Nested Virtual Machines.
I believe this is a great way to deploy Hyper-V, because you will get full Hyper-V functionality with only a 500MB disk footprint instead of multiple GB, so to get up and running you can follow the directions here.
Until then… Enjoy your day!
Cheers,
~Charbel