Summary: Use the new cmdlets in the DeployImage module to simplify the deployment of a Nano Server.
Honorary Scripting Guy, Sean Kearney, is here to get into the really fun part of deploying a Nano Server—the actual deployment part.
Note This is Part 4 of a five-part series. Also see:
- Use DeployImage Module and PowerShell to Build a Nano Server: Part 1
- Use DeployImage Module and PowerShell to Build a Nano Server: Part 2
- Use DeployImage Module and PowerShell to Build a Nano Server: Part 3
Yesterday, I showed you the New-UnattendXMLContent cmdlet to help you name the Nano Server and provide direct settings, such as the time zone. Today we’re going to look at creating partitions and applying the image—our actual process.
If you were to try to apply Nano Server to a VHD file, it’s actually very easy in Windows 10. You can natively create the VHD, mount it, and then access it directly as if it were a physical disk. Following is a simple example of creating a new VHD file, mounting it, and then assigning it to a disk object in PowerShell. Our example is called Sample.VHD and is a 20 gigabyte dynamic disk in the C:\FOO folder:
New-VHD C:\FOO\sample.vhd -SizeBytes 20gb –Dynamic
Mount-VHD C:\FOO\sample.vhd
$Disk=Get-Disk C:\FOO\sample.vhd
If this was a physical disk inside a computer (not a VHD), I would normally use the Get-Disk cmdlet and filter on the type of SCSI, SATA, or SAS. But DeployImage has a cmdlet with that wrapped into it. We can grab all internal disks in the following manner:
Get-AttachedDisk
It’s simply a wrapper around Get-Disk | Where-Object { $_.BusType }, but I find it a little nicer to use.
For a physical disk on a target server (if there is only one), we can use this:
$Disk=Get-AttachedDisk
Next we need to partition the disk. For this, I’ve set up a small cmdlet to deal with the two most common partition setups for WIM files: basic MBR and GPT.
You can create your own custom script for this, but if you’d like to easily create a GPT partition on a physical disk, you can use the New-PartitionStructure cmdlet. It has three mandatory parameters for a physical disk: the disk object, the operating system drive letter, and the boot drive letter.
This cmdlet will clear the old partition structure, create a new one, format the needed drives, and assign the drive letters. Here is an example on a physical disk with the new boot drive being assigned drive letter G and the operating system drive being assigned drive letter H:
$OSDrive=’H’
$BootDrive=’G’
New-PartitionStructure -Disk $disk -BootDrive $Bootdrive -OSDrive $OSDrive
We can use the same structure on a virtual disk, but we can also lay out a simple MBR structure. This will be part of the simple process of converting a WIM to a VHD. In this case, both the boot drive and the operating system share the same drive.
New-PartitionStructure -Disk $disk –MBR -BootDrive $Bootdrive -OSDrive $OSDrive
Now that we have a partition structure, we can use the Expand-WindowsImage cmdlet on the operating system drive letter.
Remember that custom Nano Server WIM file we created on Tuesday? Grab the location provided (it was defaulting to ‘C:\Nanotemp\Nanocustom.wim’):
$Wimfile=’C:\Nanotemp\Nanocustom.wim’
Expand-WindowsImage –imagepath "$wimfile" –index 1 –ApplyPath "$OSDrive`:\"
Now that we have an image on a disk, we can build out our Unattend file content to automatically name the system and join it to the Contoso domain (remember yesterday’s example):
$Content= New-UnattendXMLContent –computername ‘TESTNano’ –joindomain –Domainname ‘Contoso’ –Domainaccount ‘JoinAccount’ –DomainPassword ‘P@ssw0rd’ –DomainOU ‘CN=Ourusers,DC=Contoso,DC=local’
Add-Content C:\Foo\Unattend.xml –value $content
Copy-item C:\Foo\Unattend.xml –destination “$OSDrive`:\Windows\system32\Sysprep\unattend.xml” –force
We are actually almost done—except for two key pieces. We need drivers for the target computer (we need to see that hard disk and network card), and we need to apply boot code.
The cmdlet for adding drivers is nice and simple—you need to provide the source folder for your drivers and the destination for the Windows folder. The beautiful part is that the cmdlet will recurse through the folder structure and grab all the drivers from there.
$DriverPath=’C:\Drivers’
Add-WindowsDriver -Driver $DriverPath -Recurse -Path "$OSDrive`:\" -ErrorAction SilentlyContinue
Now there is only one additional piece—making the system bootable. There are two commands in Windows for making a disk bootable: BCDBoot and Bootsect. For most cases, we can use BCDBoot.
To make this process more seamless, BCDBoot and Bootsect have been wrapped into a cmdlet called Send-Bootcode, which only needs the drive letter for the boot drive and the operating system drive.
Send-Bootcode –bootdrive $Bootdrive –osdrive $OSdrive –bootdrive $Bootdrive
...and we’re done. Yep. You’ve just deployed a Nano Server. If you use a VHD as the target and create the MBR partition with the same code, you’ve converted a WIM to a VHD.
Within the DeployImage structure is a script called DeployNanoServerPhysical.ps1, which is a simple example of this post in action.
Come back tomorrow for our final day of this series. I’ll combine last week’s work of a bootable Windows PE image with PowerShell and this week’s work. I’ll show you how to automatically build out deployment media.
I invite you to follow the Scripting Guys on Twitter and Facebook. If you have any questions, send email to them at scripter@microsoft.com, or post your questions on the Official Scripting Guys Forum. See you tomorrow. Until then, always remember that with great PowerShell comes great responsibility.
Sean Kearney, Honorary Scripting Guy, Cloud and Datacenter Management MVP