Deploy a Windows Nano Server on Hyper-V with PowerShell

Hello,

Microsoft announce Windows Server Nano a while ago, but the first version available is in the Windows Server 2016 Technical Preview 2 released at Ignite 2015 last week.You can found a “NanoServer” folder at the root of the ISO file :

NanoFolder

Inside it :

InsideNanoFolder

In the ReadMe.txt there is a link to the Microsoft Nano Server documentation :

For detailed information on deploying and managing Nano Server, please go to this link: http://www.aka.ms/nanoserver

This link uses DISM.exe, in this post, we’ll use PowerShell. First, you need the “Convert-WindowsImage.ps1” PowerShell script from Technet.

Then, you can use those lines :

#WorkPlace
$Path = "D:SourcesWindows Server 2016Nano"
$IsoPath = "D:SourcesWindows Server 2016en_windows_server_technical_preview_2_x64_dvd_6651466.iso"
$VMPath = "C:VM"
'Packages','WIM','VHD' | % {New-Item $Path$_ -ItemType Directory}

#Mount ISO
$MountedIso = Mount-DiskImage -ImagePath $IsoPath -PassThru
[String]$DriveLetter = ((Get-Volume | ? {($_.Size/1GB -as [int]) -eq ($MountedIso.Size/1GB -as [int])}) | Select-Object -ExpandProperty DriveLetter) + ":"

#Copy files
Get-ChildItem -Path "$DriveLetterNanoServerNanoServer.wim" | Copy-Item -Destination "$PathWIM"
Get-ChildItem -Path "$DriveLetterNanoServerPackages" -Recurse | Copy-Item -Destination "$PathPackages"

#Dismount the ISO
Dismount-DiskImage $MountedIso.ImagePath

#Gen2
D:Convert-WindowsImage.ps1 -Sourcepath "$PathWIMNanoServer.wim" -VHD "$PathVHDNanoServer.vhdx" -VHDformat VHDX -Edition 1 -VHDPartitionStyle GPT
#Gen1
D:Convert-WindowsImage.ps1 -Sourcepath "$PathWIMNanoServer.wim" -VHD "$PathVHDNanoServer.vhd" -VHDformat VHD -Edition 1


#Inject Package - Gen 2
$MountedVHD = Mount-DiskImage -ImagePath "$PathVHDNanoServer.vhdx" -Passthru
[String]$DriveLetter = (Get-Volume | ? {($_.Size/1GB -as [int]) -eq ($MountedVHD.Size/1GB -as [int])} | Select-Object -ExpandProperty DriveLetter) + ":"

Add-WindowsPackage –Path $DriveLetter –PackagePath $PathPackagesMicrosoft-NanoServer-Compute-Package.cab         #Hyper-V
Add-WindowsPackage –Path $DriveLetter –PackagePath $PathPackagesMicrosoft-NanoServer-FailoverCluster-Package.cab #Cluster
Add-WindowsPackage –Path $DriveLetter –PackagePath $PathPackagesMicrosoft-NanoServer-Guest-Package.cab           #VM Drivers
Add-WindowsPackage –Path $DriveLetter –PackagePath $PathPackagesMicrosoft-NanoServer-OEM-Drivers-Package.cab     #OEM Drivers
Add-WindowsPackage –Path $DriveLetter –PackagePath $PathPackagesMicrosoft-NanoServer-Storage-Package.cab         #SOFS
Add-WindowsPackage –Path $DriveLetter –PackagePath $PathPackagesMicrosoft-OneCore-ReverseForwarders-Package.cab  #OneCore
Dismount-DiskImage $MountedVHD.ImagePath

#Inject Package - Gen 1
$MountedVHD = Mount-DiskImage -ImagePath "$PathVHDNanoServer.vhd" -Passthru
[String]$DriveLetter = (Get-Volume | ? {($_.Size/1GB -as [int]) -eq ($MountedVHD.Size/1GB -as [int])} | Select-Object -ExpandProperty DriveLetter) + ":"

Add-WindowsPackage –Path $DriveLetter –PackagePath $PathPackagesMicrosoft-NanoServer-Compute-Package.cab         #Hyper-V
Add-WindowsPackage –Path $DriveLetter –PackagePath $PathPackagesMicrosoft-NanoServer-FailoverCluster-Package.cab #Cluster
Add-WindowsPackage –Path $DriveLetter –PackagePath $PathPackagesMicrosoft-NanoServer-Guest-Package.cab           #VM Drivers
Add-WindowsPackage –Path $DriveLetter –PackagePath $PathPackagesMicrosoft-NanoServer-OEM-Drivers-Package.cab     #OEM Drivers
Add-WindowsPackage –Path $DriveLetter –PackagePath $PathPackagesMicrosoft-NanoServer-Storage-Package.cab         #SOFS
Add-WindowsPackage –Path $DriveLetter –PackagePath $PathPackagesMicrosoft-OneCore-ReverseForwarders-Package.cab  #OneCore
Dismount-DiskImage $MountedVHD.ImagePath

#Creating VM
#Gen2
New-Item "$VMPathNanoGen2Virtual Hard Disks" -ItemType Directory
Copy-Item -Path "$PathVHDNanoServer.vhdx" -Destination "$VMPathNanoGen2Virtual Hard DisksNanoServer.vhdx" -Force
New-VM -VHDPath "$VMPathNanoGen2Virtual Hard DisksNanoServer.vhdx" -MemoryStartupBytes 1024MB -Name NanoServerGen2 -Path $VMPathNanoGen2 -Generation 2
Set-VMMemory -VMName NanoServerGen2 -DynamicMemoryEnabled $True -MaximumBytes 1024MB -MinimumBytes 64MB -Buffer 10
Set-VMProcessor -Count 2 -VMName NanoServerGen2
Set-VM -AutomaticStopAction ShutDown -VMName NanoServerGen2
#Gen1
New-Item "$VMPathNanoGen1Virtual Hard Disks" -ItemType Directory
Copy-Item -Path "$PathVHDNanoServer.vhd" -Destination "$VMPathNanoGen1Virtual Hard DisksNanoServer.vhd"
New-VM -VHDPath "$VMPathNanoGen1Virtual Hard DisksNanoServer.vhd" -MemoryStartupBytes 1024MB -Name NanoServerGen1 -Path $VMPathNanoGen1 -Generation 1
Set-VMMemory -VMName NanoServerGen1 -DynamicMemoryEnabled $True -MaximumBytes 1024MB -MinimumBytes 64MB -Buffer 10
Set-VMProcessor -Count 2 -VMName NanoServerGen1
Set-VM -AutomaticStopAction ShutDown -VMName NanoServerGen1

Note : You may want to use PowerShell 5 or Windows 10 to use the “Add-WindowsPackage”  cmdlets.

You can then run a Nano Server in an Hyper-V VM, gen1 or gen2, event on Windows 8.1 from your laptop :

NanoGen1

NanoGen2

Note : Be patient, first boot can be quite long :

Hyper-V-NanoServer

Than, you can connect remotely with PowerShell :

Enter-PsSession -ComputerName 192.168.1.21 -Credential Administrator

If you didn’t use a unattend file like this one (special for Nano Server) :

<?xml version='1.0' encoding='utf-8'?>
<unattend xmlns="urn:schemas-microsoft-com:unattend" xmlns:wcm="http://schemas.microsoft.com/WMIConfig/2002/State" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
  <settings pass="offlineServicing">
    <component name="Microsoft-Windows-UnattendedJoin" processorArchitecture="amd64" publicKeyToken="31bf3856ad364e35" language="neutral" versionScope="nonSxS">
      <ComputerName>NanoServer</ComputerName>
    </component>
  </settings>
  <settings pass="oobeSystem">
    <component name="Microsoft-Windows-Shell-Setup" processorArchitecture="amd64" publicKeyToken="31bf3856ad364e35" language="neutral" versionScope="nonSxS">
      <UserAccounts>
        <AdministratorPassword>
           <Value>MySecurePassword</Value>
           <PlainText>true</PlainText>
        </AdministratorPassword>
      </UserAccounts>
      <TimeZone>Pacific Standard Time</TimeZone>
    </component>
  </settings>
  <settings pass="specialize">
    <component name="Microsoft-Windows-Shell-Setup" processorArchitecture="amd64" publicKeyToken="31bf3856ad364e35" language="neutral" versionScope="nonSxS">
      <RegisteredOwner>ItForDummies</RegisteredOwner>
      <RegisteredOrganization>ItForDummies</RegisteredOrganization>
    </component>
  </settings>
</unattend>

You may need to edit your trusted host :

Set-Item WSMan:\localhost\Client\TrustedHosts -Value 192.168.1.21 -Concatenate

Leave a Reply