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:
- Use DeployImage Module and PowerShell to Build a Nano Server: Part 1
Introducing the DeployImage module and the cmdlets for Nano Server.
- Use DeployImage Module and PowerShell to Build a Nano Server: Part 2
Use the New-NanoServerWim cmdlet from the DeployImage module to build an updated Nano Server WIM file.
- Use DeployImage Module and PowerShell to Build a Nano Server: Part 3
Use the New-UnattendXMLContent cmdlet in his DeployImage module to automate naming the Nano Server.
- Using DeployImage and Windows PowerShell to Build a Nano Server: Part 4
Use the new cmdlets in the DeployImage module to simplify the deployment of a Nano Server.
- Using DeployImage and Windows PowerShell to Build a Nano Server: Part 5
Use the DeployImage module to build bootable Windows PE media with deployment content.
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"?>
<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">
<TimeZone>Eastern Standard Time</TimeZone>
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:
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:
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:
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 firstname.lastname@example.org, 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