Quick Guide – Deploying Nano Server using PowerShell

Earlier today, during the Microsoft Ignite conference, the Windows Server Technical Preview 2 (Build 10074) was released. In the setup, there is also the new Nano Server (available as a WIM file).

Note: For additional info, check the Getting Started with Nano Server info.

NANO
The NanoServer.wim image on the Windows Server Technical Preview 2 (Build 10074) media.

To deploy the Nano Server you do the following

To be able to add the packages to the Nano Server you need to use DISM from either Windows 10 ADK or a Windows 10 / Windows Server Technical Preview 2 machine.

In the below sample I also copy a setupcomplete.cmd file to the image that runs ipconfig, and I’m adding an unattend.xml file to set computername, password, and timezone.

  1. Copy the NanoServer folder from the Windows Server Technical Preview 2 ISO to a folder, I copied to folder to C:Setup.
  2. Create a new VHD file, and apply the NanoServer.wim image to it. I used the Convert-WindowsImage.ps1 script from TechNet since it can creates VHD and VHDX files even without Hyper-V installed.
  3. Mount the VHD file
  4. Add any additional packages
  5. Create a VM using the the VHDX file and boot it on that image
  6. Done

Sample unattend.xml for Nano Server (named NanoUnattend.xml in my example)

<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-Shell-Setup" processorArchitecture="amd64" publicKeyToken="31bf3856ad364e35" language="neutral" versionScope="nonSxS">
      <ComputerName>NANO-001</ComputerName>
    </component>
  </settings>
  <settings pass="oobeSystem">
    <component name="Microsoft-Windows-Shell-Setup" processorArchitecture="amd64" publicKeyToken="31bf3856ad364e35" language="neutral" versionScope="nonSxS">
      <UserAccounts>
        <AdministratorPassword>
          <Value>P@ssw0rd</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>ViaMonstra</RegisteredOwner>
      <RegisteredOrganization>ViaMonstra</RegisteredOrganization>
    </component>
  </settings>
</unattend>

Here are the PowerShell commands:

# Setting a few variables
$NanoImage = 'C:\VHD\NanoServer.vhd'
$NanoPackages = 'C:\Setup\NanoServer\Packages'
$NanoUnattendFile = 'C:\Setup\Scripts\NanoUnattend.xml'
$DISMFile = 'dism.exe'
# Example when using a non-Windows 10/2016 machine with Windows ADK 10 installed
# $DISMFile = ‘C:\Program Files (x86)\Windows Kits\10\Assessment and Deployment Kit\Deployment Tools\amd64\DISM\dism.exe’
$SetupCompleteCMDFile = 'C:\Setup\Scripts\SetupComplete.cmd'
 
# Create the VHD file (Note, you need to disable the version control in Convert-WindowsImage.ps1 if running this on Windows 10)
C:\Setup\Scripts\Convert-WindowsImage.ps1 -SourcePath C:\Setup\NanoServer\NanoServer.wim -VHD C:\VHD\NanoServer.vhd -Edition 1
  
# Mount the created VHD file and get the drive letter
Mount-DiskImage -ImagePath $NanoImage
$NanoVolume = Get-DiskImage –ImagePath $NanoImage | Get-Disk | Get-Partition | Get-Volume
 
# Add packages using native PowerShell cmdlets, requires Windows 10 or Windows Server 2016 host
Add-WindowsPackage –Path "$($NanoVolume.DriveLetter):\" –PackagePath "$NanoPackages\Microsoft-NanoServer-Compute-Package.cab"
Add-WindowsPackage –Path "$($NanoVolume.DriveLetter):\" –PackagePath "$NanoPackages\en-US\Microsoft-NanoServer-Compute-Package.cab"
Add-WindowsPackage –Path "$($NanoVolume.DriveLetter):\" –PackagePath "$NanoPackages\Microsoft-NanoServer-FailoverCluster-Package.cab"
Add-WindowsPackage –Path "$($NanoVolume.DriveLetter):\" –PackagePath "$NanoPackages\en-US\Microsoft-NanoServer-FailoverCluster-Package.cab"
Add-WindowsPackage –Path "$($NanoVolume.DriveLetter):\" –PackagePath "$NanoPackages\Microsoft-NanoServer-Guest-Package.cab"
Add-WindowsPackage –Path "$($NanoVolume.DriveLetter):\" –PackagePath "$NanoPackages\en-US\Microsoft-NanoServer-Guest-Package.cab"
Add-WindowsPackage –Path "$($NanoVolume.DriveLetter):\" –PackagePath "$NanoPackages\Microsoft-NanoServer-OEM-Drivers-Package.cab"
Add-WindowsPackage –Path "$($NanoVolume.DriveLetter):\" –PackagePath "$NanoPackages\en-US\Microsoft-NanoServer-OEM-Drivers-Package.cab"
Add-WindowsPackage –Path "$($NanoVolume.DriveLetter):\" –PackagePath "$NanoPackages\Microsoft-NanoServer-Storage-Package.cab"
Add-WindowsPackage –Path "$($NanoVolume.DriveLetter):\" –PackagePath "$NanoPackages\en-US\Microsoft-NanoServer-Storage-Package.cab"
Add-WindowsPackage –Path "$($NanoVolume.DriveLetter):\" –PackagePath "$NanoPackages\Microsoft-OneCore-ReverseForwarders-Package.cab"
Add-WindowsPackage –Path "$($NanoVolume.DriveLetter):\" –PackagePath "$NanoPackages\en-US\Microsoft-OneCore-ReverseForwarders-Package.cab"
 
#Add packages using dism, requires Windows 10, or Windows 10 ADK DISM version. I used the default installation folder for the ADK.
& $DISMFile /Add-Package /PackagePath:"$NanoPackages\Microsoft-NanoServer-Compute-Package.cab" /Image:"$($NanoVolume.DriveLetter):\"
& $DISMFile /Add-Package /PackagePath:"$NanoPackages\en-US\Microsoft-NanoServer-Compute-Package.cab" /Image:"$($NanoVolume.DriveLetter):\"
& $DISMFile /Add-Package /PackagePath:"$NanoPackages\Microsoft-NanoServer-FailoverCluster-Package.cab" /Image:"$($NanoVolume.DriveLetter):\"
& $DISMFile /Add-Package /PackagePath:"$NanoPackages\en-US\Microsoft-NanoServer-FailoverCluster-Package.cab" /Image:"$($NanoVolume.DriveLetter):\"
& $DISMFile /Add-Package /PackagePath:"$NanoPackages\Microsoft-NanoServer-Guest-Package.cab" /Image:"$($NanoVolume.DriveLetter):\"
& $DISMFile /Add-Package /PackagePath:"$NanoPackages\en-US\Microsoft-NanoServer-Guest-Package.cab" /Image:"$($NanoVolume.DriveLetter):\"
& $DISMFile /Add-Package /PackagePath:"$NanoPackages\Microsoft-NanoServer-OEM-Drivers-Package.cabab" /Image:"$($NanoVolume.DriveLetter):\"
& $DISMFile /Add-Package /PackagePath:"$NanoPackages\en-US\Microsoft-NanoServer-OEM-Drivers-Package.cabab" /Image:"$($NanoVolume.DriveLetter):\"
& $DISMFile /Add-Package /PackagePath:"$NanoPackages\Microsoft-NanoServer-Storage-Package.cab" /Image:"$($NanoVolume.DriveLetter):\"
& $DISMFile /Add-Package /PackagePath:"$NanoPackages\en-US\Microsoft-NanoServer-Storage-Package.cab" /Image:"$($NanoVolume.DriveLetter):\"
& $DISMFile /Add-Package /PackagePath:"$NanoPackages\Microsoft-OneCore-ReverseForwarders-Package.cab" /Image:"$($NanoVolume.DriveLetter):\"
& $DISMFile /Add-Package /PackagePath:"$NanoPackages\en-US\Microsoft-OneCore-ReverseForwarders-Package.cab" /Image:"$($NanoVolume.DriveLetter):\"
 
# Apply the unattend.xml file to the offline Windows image
& $DISMFile /Apply-Unattend:$NanoUnattendFile /Image:"$($NanoVolume.DriveLetter):\"
 
# Copy the unattend.xml file to the offline Windows\Panther folder
New-Item -ItemType Directory "$($NanoVolume.DriveLetter):\Windows\Panther"
Copy-Item $NanoUnattendFile "$($NanoVolume.DriveLetter):\Windows\Panther\Unattend.xml"
 
# Copy the SetupComplete.cmd file
New-Item -ItemType Directory "$($NanoVolume.DriveLetter):\Windows\Setup"
New-Item -ItemType Directory "$($NanoVolume.DriveLetter):\Windows\Setup\Scripts"
Copy-Item $SetupCompleteCMDFile "$($NanoVolume.DriveLetter):\Windows\Setup\Scripts"
 
Dismount-DiskImage -ImagePath C:\VHD\NanoServer.vhd

Create a virtual machine

Once you have the VHD file, you can simply create a virtual machine using it. Here is a sample script to do that:

$VMLocation = "D:\VMs"
$VMNetwork = "Internal"
$VHDLocation = "C:\VHD"
$VHDFile = "NanoServer.vhd"
 
# Create Nano Server 001
$VMName = "NanoServer-001"
$VMMemory = 512MB
$VMDiskSize = 60GB
New-VM -Name $VMName -MemoryStartupBytes $VMMemory -SwitchName $VMNetwork -Path $VMLocation -NoVHD
New-Item "$VMLocation\$VMName\Virtual Hard Disks" -ItemType directory
Copy-Item "$VHDLocation\$VHDFile" -Destination "$VMLocation\$VMName\Virtual Hard Disks"
Add-VMHardDiskDrive -VMName $VMName -Path "$VMLocation\$VMName\Virtual Hard Disks\$VHDFile"

Once the machine booted (takes quite a while), you can start managing it remotely.

Connecting to the machine

To connect remotely, you can use PowerShell. The default administrator password is blank.

Set-Item WSMan:\localhost\Client\TrustedHosts -Value 192.168.1.102 -Concatenate
Enter-PsSession -ComputerName 192.168.1.102 -Credential Administrator

Note: The -Concatenate parameter keeps existing trustedhosts values, thanks Kaido Järvemets for pointing that out 🙂

Once logged in, you can change the password using the net user command: net user administrator P@ssw0rd

image

Happy Deployment, Johan

About the author

Johan Arwidmark

0 0 votes
Article Rating
Subscribe
Notify of
guest
0 Comments
Inline Feedbacks
View all comments

>