Use DeployImage Module and PowerShell to Build a Nano Server: Part 3


Summary: Sean Kearney uses the New-UnattendXMLContent cmdlet in his DeployImage module to automate naming the Nano Server.

Honorary Scripting Guy, Sean Kearney, is here today to continue with our work in easing the deployment of a Nano Server or other WIM files with the DeployImage module.

   Note   This is a five-part series that includes the following posts:

But most of us are used to going to a computer, swapping in the computer name, and joining the domain via the GUI.

But this is not the only way to do it. If you’re just getting into deploying Windows or images, there is a powerful file called Unattend.xml, which can contain all of this information.

Unattend.xml can do many post-installation tasks, including some critical ones we’ll need for Nano Server, such as:

  • Join a computer to a domain or workgroup
  • Define local accounts
  • Define IP addresses
  • Name workstations and servers
  • Define the time zone

The reason some of us don’t use Unattend.xml (I initially didn’t for years) is due to its large XML file. XML is a great format that can be a small mini-database of sorts. The problem is XML, for the first time user, can be a tad confusing.

Here is an example of an Unattend.xml file that defines a server name, ownership, and other properties of a computer:

<?xml version="1.0" encoding="utf-8"?>
<unattend xmlns="urn:schemas-microsoft-com:unattend">
 <settings pass="specialize">
  <component name="Microsoft-Windows-Shell-Setup" processorArchitecture="amd64" publicKeyToken="31bf3856ad364e35" language="neutral" versionScope="nonSxS" xmlns:wcm="http://schemas.microsoft.com/WMIConfig/2002/State" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
   <ComputerName>testpc</ComputerName>
   <RegisteredOrganization>Nano Organization</RegisteredOrganization>
   <RegisteredOwner>Nano Owner</RegisteredOwner>
   <TimeZone>Eastern Standard Time</TimeZone>
  </component>

I’m cutting off the rest of the file because an Unattend.xml file can get quite long.

The good part about an Unattend.xml file and Windows PowerShell is they are quite easy to build out. Because we can take sections that we need and store them as here-string content or files on a drive, we can parameterize all of the information. In the following simple example, we have a here-string with a first and last name:

$Info=@”
FirstName – John
LastName – Smith
“@

If I want to pass parameters into this, I can change the data I need to substitute into Windows PowerShell objects. In the following example, I am changing “John” and “Smith” to objects:

$First=’John’
$Last=’Smith’

$Info=@”
FirstName – $First
LastName – $Last
“@

So you can see how this could be useful in an Unattend.xml file, which brings us to the New-UnUnattendXMLContent cmdlet.

With the DeployModule imported, you can run Get-Help against this cmdlet to see the available parameters:

Get-Help New-UnAttendXMLContent

Image of command output

As you can see, most of the parameters we’ll need for an UnAttend.xml file are now parameters in Windows PowerShell. This won’t create the actual file, but it will populate and produce the XML content for you to consume in whatever manner you wish. This can also be ported directly to an Unattend.xml file by using the Add-Content cmdlet.

Here is a simple example of creating an Unattend.xml file for a computer called TESTNano:

New-UnattendXMLContent –computername ‘TESTNano’

If you know the name for your proposed time zone, you can set that default for TESTNano by using the TimeZone parameter, for example:

New-UnattendXMLContent –Timezone ‘Pacific Standard Time’ –Computername ‘TESTNano’

This will also default to a workgroup configuration.

We can also create a domain-joined system by using the JoinDomain switch and providing the needed credentials. Here’s a simple example for the Contoso domain:

New-UnattendXMLContent –computername ‘TESTNano’ –joindomain –Domainname ‘Contoso’ –Domainaccount ‘JoinAccount’ –DomainPassword ‘P@ssw0rd’ –DomainOU ‘CN=Ourusers,DC=Contoso,DC=local’

You can create an Unattend.xml file by using this cmdlet in the following manner. We’ll take the previous example and build a file from it:

$Content= New-UnattendXMLContent –computername ‘TESTNano’ –joindomain –Domainname ‘Contoso’ –Domainaccount ‘JoinAccount’ –DomainPassword ‘P@ssw0rd’ –DomainOU ‘CN=Ourusers,DC=Contoso,DC=local’

Add-Content Unattend.xml –value $content

For an Unattend.xml file to work, it needs to sit within the \Windows\System32\Sysprep folder on the disk you expand the WIM file to.

When the new Windows starts, it will check for and parse this file to determine what additional configurations are needed, including how many reboots are required. The process we’ll be looking at tomorrow in our sample script involves building such a file after we expand the image.

Take a swing by tomorrow when we’ll do the fun stuff, which is actually deploying the Nano Server WIM file to a VHD or a physical disk and actually building out a server!

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

Comments (3)

  1. Tim says:

    I am not having any success with domain joining using the unattend.xml file that is output by this procedure. When the VM boots, I’m getting the ‘azure’ screen of death. I have followed the instructions in the TechNet quick start article and get the VM
    to join the domain, so I know my environment is working.

    First, I followed these instructions and received the ASOD. So I figured I would try it in a method that I knew was working.

    What I did was run through this process and create an unattend.xml file. I then use it in the TechNet quick start (New-NanoServerImage) by mounting the VHDX file produced and copying this unattend.xml file over the top of the unattend.xml created by the TechNet
    procedure. Boot the VHDX and receive ASOD. I played with it, putting in just sections of this unattend.xml into the TechNet unattend.xml. As soon as I enter the section for domain join, ASOD. I stop the VM, mount the VHDX, delete the unattend section, restart
    the VM, and it completes. According to the Panther log, when the unattended join section is in the file, it is saying it is an invalid unattend file.

  2. @Tim

    Thanks! I’ll double check the format on the Unattend for Domain join. I’ll get it corrected for you and update the module asap!

    Cheers!
    Sean

  3. @Tim

    Thanks for the feedback. It was a minor typo that broke the XML with Domain Join. All is now fixed and updated in the PowerShellGallery as well as GitHub.

    Cheers!
    Sean

Skip to main content