Académique Documents
Professionnel Documents
Culture Documents
1 | Page
Create Bootable WinPE Media...............................................................................21
Sample Automation Scripts...................................................................................... 21
Automation.ps1..................................................................................................... 22
Get-ServiceProfile............................................................................................... 22
Populate Parameters.......................................................................................... 23
Partition-Disk...................................................................................................... 24
Mount-Vdisk........................................................................................................ 25
Create-Unattend................................................................................................. 26
Setup-Complete..................................................................................................... 27
ServerSetup.ps1 (Windows Server)....................................................................28
NanoSetup.ps1 (Nano Server)............................................................................30
Variables.xml...................................................................................................... 31
ForcePxeBoot......................................................................................................... 31
Summary.................................................................................................................. 32
Author...................................................................................................................... 32
Introduction
If you are regularly deploying Windows operating systems, the combination of Cisco
UCS tools and Microsoft tools work together to speed up the deployment of Windows
Server operating systems. The purpose of this document is to provide step-by-step
guidance to configure an environment that enables automating the deployment of
Windows Server. This includes the various operating system installation options,
such has Hyper-V Server, Standard or Datacenter, Core or Full, plus it shows how to
use the procedure for a new installation option available in Windows Server 2016
called Nano Server.
The primary components used for this automation process are Cisco UCS Manager,
Cisco UCS PowerTool, Microsoft PowerShell, and Microsoft WinPE.
2 | Page
Microsoft WinPE Windows Preinstallation Environment (WinPE) is a
lightweight version of Windows used for the deployment of PCs, workstations,
and servers, or troubleshooting an operating system while it is offline.
The core of this solution is WinPE. WinPE is a stripped down version of Windows
that can be booted via PXE, USB, DVD, or UCS Manager virtual media, providing a
way to quickly get a working operating system onto the system being targeted for
deployment.
Out of the box, WinPE contains basic elements. To make it really useful, it generally
has to be modified. For example, it comes with a minimum number of device
drivers. Therefore, it is often necessary to add additional device drivers that you
know will be needed to deploy your system. For Cisco, that means the enic driver at
a minimum, but can also include other specific hardware drivers. It also comes with
basic scripting abilities. For purposes of this document, it will be tailored to provide
the flexibility of PowerShell.
This document will describe the procedure to create virtual hard disk (VHD) images
of Windows Server and Nano Server and a bootable WinPE image that can used for
deploying those VHDs to Cisco UCS hardware. This procedure will create a virtual
hard disk that can be used for natively booting the physical system. This actually
provides more flexibility in deployment because a VHD can be easily mounted to
another Microsoft operating system and files added or removed, making the options
for deployment nearly limitless.
There are four major sections in this document.
1. Workstation configuration what tools, directories, etc. need to be configured
to run the sample automation shown in this document
2. Microsoft operating system virtual hard disks automating the creation of the
virtual hard disks that will eventually be used to boot the Cisco UCS server
3. Tailor WinPE how to tailor WinPE to automate the deployment of the VHDs
4. Sample automation scripts scripts developed to automate the deployment
and configuration of the VHDs
Note: Though these scripts have been extensively tested, they are provided AS IS
with no warranties, confer no rights, and are not supported by the author or Cisco
Systems. They should be evaluated and tested for each individual environment to
ensure they meet the standards in place.
Outline
1. Workstation configuration
a. Download and install the latest Assessment and Deployment Kit (ADK)
b. Directory configuration
c. Local user account
d. Cisco UCS PowerTool / [Java]
2. Microsoft operating system virtual hard disks
a. Windows Server (Hyper-V Server)
b. Nano Server
3. Tailor WinPE
3 | Page
a. Basics
b. Inject Cisco drivers
c. Install Windows PowerShell
d. Install Cisco UCS PowerTool
e. Custom Scripts
f. Create bootable WinPE media
4. Sample Automation Scripts
This document assumes deployment into a Cisco UCS managed environment. The
scripts automatically determine the name of the computer on which the scripts are
running by making use of the capabilities of Cisco UCS Manager. If these scripts are
to be used in an environment that is not managed by UCS Manager, for example a
CIMC managed environment, a different method will have to be used to determine
the computer name. Once that method is implemented and the scripts changed to
reflect the alternate method, these scripts should work (though they have not been
tested in a CIMC environment).
Workstation Configuration
A workstation for preparing the WinPE environment will need to be configured. This
can be a Windows 8.1, Windows 10, Windows Server 2012 R2, or Windows Server
2016 system. It is recommended to use the latest version available of the operating
system to ensure that you are using the latest tools. This process assumes
Windows 10 (Windows Server 2016), but slight modification will make it possible to
use Windows 8.1 (Windows Server 2012 R2).
You will also be using this workstation for creating the VHD files that will eventually
be deployed to the physical servers. The target VHD file will be copied to a local
physical disk on the server being deployed and then be used to native boot from
VHD instead of booting from an installation performed to the local physical disk.
4 | Page
By default, several options will be pre-selected. All that is needed for this process
are the Deployment Tools and Windows Preinstallation Environment (Windows PE).
Unselect all options but those two and click Install.
Directory Configuration
The workstation in this example is used for several purposes:
C:\WinPE
This directory and three subdirectories are created by the ADK. These directories
hold the content of the files used to create the targeted WinPE media. You specify
the exact location and name of this directory when you start the WinPE creation
process and it creates the directory structure.
5 | Page
C:\WinPE\fwfiles there are two files contained in this directory. They are used
when you create bootable WinPE media, depending on the type of media created.
The proper file is automatically selected so you do not need to be concerned about
these files.
C:\WinPE\media this directory contains all the files needed for creating the
WinPE media. For the most part, the only file you are likely to reference is the
C:\WinPE\sources\boot.wim. This is the file you are going to mount and tailor to
your needs.
C:\WinPE\mount this directory is used to mount the boot.wim file so you can
access the contents of the WIM file.
E:\Share
You create this directory and the subdirectories on the workstation. It files that will
be used in the tailoring of both the WinPE media and the VHD target, as well as the
automation scripts and configuration files. Again, this directory structure is the
structure used for this document. It can be on any volume, and it needs to be
shared for network access with specific ACLs.
Note: Some of the sample scripts presented in this document have this value hard-
coded. If you use a different root directory, you will need to make changes to the
hard-coded values in the sample scripts.
The following subdirectories of the \Share need to be in place. The first subdirectory
is \Automation. It contains six common subdirectories and then a series of
subdirectories used to contain information specific to individual servers that are
being deployed.
E:\Share\Automation\Base This is an optional subdirectory that can be used
during the creation of the Nano Server image.
E:\Share\Automation\Drivers This subdirectory contains all the device drivers
that need to be added to any image being created. At a minimum, you should
include the UCS VIC enic driver. Go to Cisco.com and download the appropriate
driver ISO files. Mount the ISO file. Copy the driver files for each driver that you
want to add to the image into this directory. You may want to create a separate
subdirectory for each unique driver, just to keep things straight. For example, here
is a sample directory for the Cisco UCS C240 M4 servers used for this document.
6 | Page
E:\Share\Automation\Mount This subdirectory is used as a mount point for the
install.wim file when tailoring it into a virtual hard disk. Nothing is permanently
stored here.
E:\Share\Automation\Nano This subdirectory is used to contain the automation
scripts for building a Nano Server image. The scripts are copied to this subdirectory
from the Windows Server distribution media.
E:\Share\Automation\Scripts This subdirectory contains scripts that are
common across any deployment process used to automate the deployment of a
specific server. These scripts will be executed by WinPE, but it is easier to manage
these scripts on the workstation than it is to manage them on the WinPE image.
Scripts that are used to tailor a specific image will be contained within a different
subdirectory.
E:\Share\Automation\VHDs This subdirectory will contain the created VHD from
the Windows Server or Nano Server wim file. Each VHD will be a base image that
can be tailored later in the process by including other script files. For example, you
might want to have four images for Windows Server 2016 Standard Core, Standard
with Desktop, Datacenter Core, and Datacenter with Desktop. Due to the way Nano
Server images are created, you might want to have images for Compute with
Cluster, Compute Standalone, File Services with Cluster, File Services Standalone,
and any other combinations that are appropriate to your environment. This
document will show you how to create an individual image, but it will not show the
creation of all those listed above.
The following PowerShell commands will create the above directory structure.
New-Item -Path E:\Share\Automation -ItemType Directory
New-Item -Path E:\Share\Automation\Base -ItemType Directory
New-Item -Path E:\Share\Automation\Drivers -ItemType Directory
New-Item -Path E:\Share\Automation\Mount -ItemType Directory
New-Item -Path E:\Share\Automation\Nano -ItemType Directory
New-Item -Path E:\Share\Automation\Scripts -ItemType Directory
New-Item -Path E:\Share\Automation\VHDs -ItemType Directory
7 | Page
E:\Share\Automation\<SPname>\Scripts This subdirectory contains scripts
particular to tailoring the system. It must contains a Variables.xml file that define
things like IP addressing, passwords, domain join information, etc. A sample is
shown later in this document. If anything besides the basics covered in the
common automation file is required, those files would also be present. For example,
you might need a SetupComplete.cmd file which is executed upon completion of the
installation. That script may call another script, ServerSetup.ps1, to perform other
functions such as domain join or role installation.
E:\Share\Automation\<SPname>\Logs This subdirectory is used to store log
files created during the automation steps. The access to this subdirectory differs
from the rest of the subdirectories. The rest of the subdirectories are configured for
Read/Execute access for the local account used to access the root share. Because
log files will be written during the automation process, the ACL on this subdirectory
is changed to add Write and Modify access for the local account.
NewSPdirectory.ps1
The following script will take a Service Profile name as input and create the proper
subdirectory structure. It requires that the $shareRoot and $shareUser variables be
modified to reflect the customer environment. Before running this script, the
$shareUser variable must be defined as a local user on the workstation
(NewShareUser.ps1 script is shown in the next section).
Note: Remember when entering the Service Profile name that is it case sensitive
within UCS Manager.
Param
(
[Parameter(Mandatory = $true, Position = 0)] # Service Profile name
[String]$spName
)
If (Test-Path $spPath)
{
Write-Host "Directory $spPath already exists. Exiting" -ForegroundColor Red
Exit
}
# Get ACL on log directory. Build Modify permission for share user. Add to ACL.
$acl = Get-Acl $spLogs
$colRights = [System.Security.AccessControl.FileSystemRights]"Read,Modify,ExecuteFile,ListDirectory"
$permission = $shareUser,$colRights,"ContainerInherit,ObjectInherit,None,Allow
8 | Page
$accessRule = New-Object System.Security.AccessControl.FileSystemAccessRule $permission
$acl.AddAccessRule($accessRule)
$acl | Set-Acl $spLogs
Copy Files
Once the above directory structure is created, you must copy in any custom script
files (Variables.xml, ServerSetup.ps1) and executables appropriate for the platform
you are targeting. Additional scripts and executables you may reference within
ServerSetup.ps1 also must be copied into the appropriate directories.
NewShareUser.ps1
$userName = Read-Host "Username for share access"
$password = Read-Host "New password for $userName" -AsSecureString
$confirmpassword = Read-Host "Confirm the password" -AsSecureString
If ($password -ne $confirmpassword)
{
Write-Host "Entered passwords are not same. Script is exiting" -ForegroundColor Red
Exit
}
$pwd =
[Runtime.InteropServices.Marshal]::PtrToStringAuto([Runtime.InteropServices.Marshal]::SecureStringTo
BSTR($password))
$computerName = $env:ComputerName
9 | Page
$compobj = [ADSI]"WinNT://$computerName"
$user = $compobj.create("user", $userName)
$user.SetPassword($pwd1)
$user.SetInfo()
$user.Description = "Special account for deployment automation"
$user.SetInfo()
$computer = [ADSI]"WinNT://$computerName,computer"
$Users = $computer.psbase.Children | Where-Object {$_.psbase.schemaclassname -eq "user"}
ForEach ($user in $users)
{
If ($user.Name -eq $userName)
{
$Name = $user.Name
$flags = $user.userFlags.Value
$flags = $flags -bor $PASSWD_CANT_CHANGE
$flags = $flags -bor $DONT_EXPIRE_PASSWD
$user.userFlags.Value = $flags
$user.SetInfo()
Break
}
}
%windir%\system32\WindowsPowerShell\v1.0\profile.ps1 applies to
all users and all shells
10 | P a g e
%windir%\system32\WindowsPowerShell\v1.0\
Microsoft.PowerShell_profile.ps1 applies to all users, but only to the
Microsoft.PowerShell shell
%UserProfile%\My Documents\WindowsPowerShell\profile.ps1
applies only to the current user, but affects all shells
%UserProfile%\My
Documents\WindowsPowerShell\Microsoft.PowerShell_profile.ps1
applies only to the current user and the Microsoft.PowerShell shell
At a minimum you should modify the third one for the user that will be running the
scripts. If you do not modify the appropriate profile(s), it will be necessary to import
the proper PowerTool module(s) within any script that calls PowerTool cmdlets.
The following PowerShell command provides a sample import command to be
inserted into the appropriate profiles:
Import-Module Cisco.UCS.Core, Cisco.UCSManager
Optionally, if you plan on running the UCS Manager console or UCS KVM from your
workstation, you will need to install the latest version of Java. UCS Manager version
3 and later has an HTML5 interface that can be used from any browser supporting
HTML5, but the UCS KVM still requires Java.
11 | P a g e
A local share is specified to contain the output, as well as containing a
subdirectory with Cisco drivers needed for installation (- localShare
E:\Share\Automation for this sample)
The sample command line for executing this script (assuming it is in the connected
directory) is:
PS E:\Share\Automation\Scripts> .\NewWindowsServerVHD.ps1 isoPath F:
-osIndex Datacenter localShare E:\Share\Automation
The output from this script using the above parameters is a 50 GB dynamically
expanding VHDX file with the Windows Server 2016 Datacenter Desktop Experience
installation. The VHDX contains the UCS drivers required to boot physical UCS
servers. It relies on the previous automation scripts and processes to tailor for this
environment by inserting unattend.xml and StartupComplete.cmd files and making
the VHDX file bootable by the physical machine.
NewWindowsServerVHD.ps1
#Requires -RunAsAdministrator
Param
(
[Parameter(Mandatory = $true, Position = 0)] # Drive letter of ISO
[String]$isoPath,
$isoPath = $isoPath.trim()
$sourcesPath = Join-Path $isoPath "sources"
$wimSource = Join-Path $sourcesPath "install.wim"
$localShare = $localShare.trim()
$driversPath = Join-Path $localShare "Drivers"
$wimPath = Join-Path $localShare "install.wim"
$mountDir = Join-Path $localShare "Mount"
$fatalErr = $false
# Test entered local share exists and has proper driver files
If (!(Test-Path $localShare -PathType Container))
{
$fatalErr = $true
Write-Warning "Local share directory does not exist"
}
12 | P a g e
If (!(Test-Path $driversPath -PathType Container))
{
$fatalErr = $true
Write-Warning "Local share directory does not contain Drivers sub-directory"
}
If (!(Get-ChildItem -Path $driversPath -Filter enic6x64.inf -Recurse ))
{
$fatalErr = $true
Write-Warning "Local share directory does not contain Ethernet driver files"
}
If ($fatalErr)
{
Write-Error "Argument error prevents script from running. Aborting." -Category InvalidArgument
Exit
}
Switch ($osIndex)
{
StandardCore {$installIndex=1;$vhdName="WS2016_Std_Core.vhdx"}
Standard {$installIndex=2;$vhdName="WS2016_Std.vhdx"}
DatacenterCore {$installIndex=3;$vhdName="WS2016_DC_Core.vhdx"}
Datacenter {$installIndex=4;$vhdName="WS2016_DC.vhdx"}
}
$vhdxPath = Join-Path $localShare "VHDs\$vhdName"
# Mount the wim file and add the Cisco drivers. Use version from ISO to ensure compatibility
. $sourcesPath\Dism.exe /Mount-Image /ImageFile:$wimPath /index:$installIndex /MountDir:$mountDir
. $sourcesPath\Dism.exe /Add-Driver /Image:$mountDir /Driver:$driversPath /Recurse
. $sourcesPath\Dism.exe /Unmount-Image /MountDir:$mountDir /commit
# Create a VHDX
$drive = New-VHD -path $vhdxPath -SizeBytes 50gb -Dynamic | `
Mount-VHD -Passthru | `
Get-Disk -number {$_.DiskNumber} | `
Initialize-Disk -PartitionStyle MBR -PassThru | `
New-Partition -UseMaximumSize -AssignDriveLetter:$false -MbrType IFS | `
Format-Volume -Confirm:$false -FileSystem NTFS -NewFileSystemLabel $osIndex -Force | `
Get-Partition | `
Add-PartitionAccessPath -AssignDriveLetter -PassThru | `
Get-Volume).DriveLetter
$driveLetter = "$($drive):\"
Dismount-VHD $vhdpath
# Cleanup
Remove-Item $localShare\install.wim
13 | P a g e
Write-Output "Processing completed at:" (Get-Date)
Note: The above script assumes Windows Server 2016 for the naming convention
of the created VHD file. The script will work with Windows Server 2012 R2 media,
too, but it will still use the Windows Server 2016 naming convention. You would
need to manually change the name of the created VHDs to reflect a different
naming convention. It can also be used for Hyper-V Server. For Hyper-V Server, the
only valid index value is 1, so you would select StandardCore as the image to
use.
Nano Server
Nano Server is a remotely administered server operating system optimized for
private clouds and data centers. It is similar to Windows Server in Server Core
mode, but significantly smaller, has minimal local logon capability, and only
supports 64-bit applications, tools, and agents. It takes up far less disk space, sets
up significantly faster, and requires far fewer updates and restarts than Windows
Server. When it does restart, it restarts much faster.
This process creates a VHD that is used to boot a physical machine using the pre-
installed Cisco UCS drivers.
1. Start PowerShell as an administrator. Mount the Windows Server ISO. This
example assumes it is mounted to drive letter J: Create a directory in which
you will build the Nano Server VHD. This example assumes
E:\Share\Automation\VHDs.
2. Copy the required Cisco driver files into the Drivers subdirectory
(E:\Share\Automation\Drivers).
3. Connect to E:\Share\Automation\Nano and copy the files from
J:\Nanoserver\NanoServerImageGenerator\ to this directory.
Copy J:\Nanoserver\NanoServerImageGenerator*.*
5. Create a VHD that sets a computer name, includes the OEM and Cisco
drivers, and the Hyper-V role and Failover Clustering feature by running the
following command. It will prompt you for an administrator password for the
new VHD:
14 | P a g e
selected. This will assist in writing the automation scripts because you
will be working with known values in referencing the base images.
c. ComputerName Nano_C_C creates an unattend.xml file in the VHD
which sets the name of the computer to Nano_C_C.
d. OEMDrivers include the OEM device drivers for the most common
hardware that are included with the Nano Server distribution. This
does not include any of the Cisco-specific drivers.
e. DriverPath E:\Share\Automation\Drivers include all drivers in this
subdirectory. This is where the Cisco drivers are stored.
f. DeploymentType Host specify the deployment type. Host to a
physical server. Guest to a VM.
g. Edition Datacenter specify the edition, Standard or Datacenter. This
specifies licensing and capabilities. Datacenter should be selected if
the server is being deployed with Hyper-V (-Computer parameter), as a
member of a Storage Spaces Direct cluster (-Storage parameter),
and/or it will have shielded VMs deployed to it (-Packages Microsoft-
NanoServer-ShieldedVM-Package parameter).
h. Compute include the Hyper-V role in the image.
i. Clustering include the Failover Cluster feature in the image.
j. EnableRemoteManagementPort allow for remote management of the
system
k. The execution of above script will ask for the local administrators
password. It is possible to include the password in the above
command by adding this parameter: AdministratorPassword (ConvertTo-
SecureString String P@55w0rd AsPlainText Force)
15 | P a g e
2. Mount the copied VHD
3. Open <driveletter>:\Windows\Panther\Unattend.xml with Notepad
4. Change the name of the computer (<ComputerName></ComputerName>)
5. Save the changes when exiting from Notepad
6. Proceed to passing each file to each physical server by using the WinPE
bootable media described at the beginning of this document
Besides the Compute and Clustering switches shown above, there are several
other switches that can be used independently or in conjunction with other switches
to define roles and features to be included in the image. See Getting Started with
Nano Server for more switches. https://technet.microsoft.com/en-
us/library/mt126167.aspx
Remote Management
Since Nano Server does not support either a GUI or RDP for remote management,
you need to manage it remotely. The above process will configure a Nano Server for
remote management. There are also some things that you need to do on the
system from which you are going to manage the Nano Server. For complete details
on how to set up a PowerShell remote management session to the Nano Server, see
the above referenced document, Getting Started with Nano Server, for more details.
16 | P a g e
Examples shown in this document depend upon CDN being defined in the Service
Profiles.
Tailor WinPE
Once the above setup is complete, click on the Windows icon on the task bar and
type Deployment. This will automatically search and find the Deployment and
Imaging Tools Environment. Right-click and select Run as Administrator. This will
bring up a command window in the deployment tools directory. All commands
shown in this section are performed from this command window.
Shortcut for launching is C:\ProgramData\Microsoft\Windows\Start
Menu\Programs\Windows Kits\Windows ADK\Deployment and Imaging Tools
Environment.
Basics
The first thing we need to do is create a distribution copy the basic WinPE files that
we will be using into a directory. Execute the following copype command in the
command window:
copype amd64 C:\WinPE
This command creates the specified directory for you. It specifies to create a
distribution for 64-bit Windows because Windows Server 2012 and later only come
in 64-bit versions, and we are not concerned with building a distribution for 32-bit
operating systems at this time. You can place this anywhere on your system. The
above directory will be used as the example directory throughout this document.
17 | P a g e
Included in the files copied is a boot.wim file that we will be modifying. In order to
modify it, we need to mount it to make it available to the system. The following
DISM command mounts the file.
Dism /Mount-Image /ImageFile:C:\WinPE\media\sources\boot.wim /index:1
/MountDir:C:\WinPE\mount
When inserting multiple device drivers into the image, you may issue a single
command to load all the drivers. This command will find all .inf files in the specified
directory and any subdirectories.
Dism /Add-Driver /Image:C:\WinPE\mount /Driver:E:\Share\Automation\Drivers /Recurse
NOTE: If you plan on using onboard RAID for the boot SSDs that are available for
some systems (Wellsburg Dual 4-port SATA Storage Control Unit from Intel), make
sure to include those drivers in the WinPE image. This also requires the addition of
a Storage Profile to be used in your Service Profile. It will be configured like this:
18 | P a g e
To see what device drivers are injected into this image, issue the following
command:
Dism /Get-Drivers /Image:C:\WinPE\mount
At this time you could create a bootable copy of WinPE that would be able to boot
the physical hardware and present you with access to both the network and storage
devices. But the goal is to automate the deployment of the Windows operating
system, so we will perform a few more steps.
After extracting the driver installation files, you can delete the ChipsetSetup.exe file.
19 | P a g e
Directory of E:\Share\Automation\Drivers
<DIR> Cisco-VIC
<DIR> Cisco-VICmgmt
<DIR> Intel-C600
<DIR> Intel-Chipset
<DIR> LSI-12GSAS
Directory of E:\Share\Automation\Drivers\Cisco-VIC
10,092 enic6x64.cat
9,094 enic6x64.inf
292,016 enic6x64.sys
Directory of E:\Share\Automation\Drivers\Cisco-VICmgmt
8,781 vicmgmt64.cat
2,432 vicmgmt64.inf
31,432 vicmgmt64.sys
1,721,576 WdfCoInstaller01009.dll
Directory of E:\Share\Automation\Drivers\Intel-C600
721 dpinst.xml
7 MegaSR1
105,533 MegaSR1.cat
237,623 MegaSR1.inf
444 megasr1.md5
910,248 megasr1.sys
1,014 nodev.inf
50,282 txtsetup.oem
Directory of E:\Share\Automation\Drivers\Intel-Chipset
39,638 Chipset.cat
14,634 Chipset_SMBus.inf
61,224 Chipset_System.inf
9,182 Chipset_Thermal.inf
6,618 Chipset_USB.inf
8,154 Chipset_Win78only.inf
Directory of E:\Share\Automation\Drivers\LSI-12GSAS
42,261 DriverConfigParam.def
13,376 lsinodrv.inf
18,024 lsi_sas3.cat
26,990 LSI_SAS3.inf
839,680 lsi_sas3.pdb
100,688 lsi_sas3.sys
14,603 lsi_sas3_win8.1_2012R2.txt
159,056 wdcfg.exe
Windows PowerShell
WinPE is designed to be a very compact image because it is often used for PXE
booting a system, and for that purpose it is desired to keep the image as small as
20 | P a g e
possible. As a result, it comes with the basic command-line capabilities. But with
higher speed networks, and using WinPE from bootable USB or DVD media, the
larger image created by adding PowerShell to the image gives you the ability to
create powerful scripts for WinPE to execute for tailoring images.
The following commands demonstrate how to install the six optional PowerShell
components into the WinPE image that are required for this example. You will notice
that there are two lines per component the component and its associated
language pack. Both are required to be installed. Additionally, the added
components often need to be added in a specific sequence. The following list
follows the prescribed sequence.
For a full list of optional components that can be added to WinPE, see
http://msdn.microsoft.com/windows/hardware/commercialize/manufacture/desktop/
winpe-add-packages--optional-components-reference.
21 | P a g e
Dism /Add-Package /Image:C:\WinPE\mount /PackagePath:C:\Program Files (x86)\Windows
Kits\10\Assessment and Deployment Kit\Windows Preinstallation
Environment\amd64\WinPE_OCs\WinPE-WMI.cab
Dism /Add-Package /Image:C:\WinPE\mount /PackagePath:"C:\Program Files (x86)\Windows
Kits\10\Assessment and Deployment Kit\Windows Preinstallation
Environment\amd64\WinPE_OCs\en-us\WinPE-WMI_en-us.cab"
Dism /Add-Package /Image:C:\WinPE\mount /PackagePath:"C:\Program Files (x86)\Windows
Kits\10\Assessment and Deployment Kit\Windows Preinstallation
Environment\amd64\WinPE_OCs\WinPE-NetFX.cab"
Dism /Add-Package /Image:C:\WinPE\mount /PackagePath:"C:\Program Files (x86)\Windows
Kits\10\Assessment and Deployment Kit\Windows Preinstallation
Environment\amd64\WinPE_OCs\en-us\WinPE-NetFX_en-us.cab"
Dism /Add-Package /Image:C:\WinPE\mount /PackagePath:"C:\Program Files (x86)\Windows
Kits\10\Assessment and Deployment Kit\Windows Preinstallation
Environment\amd64\WinPE_OCs\WinPE-Scripting.cab"
Dism /Add-Package /Image:C:\WinPE\mount /PackagePath:"C:\Program Files (x86)\Windows
Kits\10\Assessment and Deployment Kit\Windows Preinstallation
Environment\amd64\WinPE_OCs\en-us\WinPE-Scripting_en-us.cab"
Dism /Add-Package /Image:C:\WinPE\mount /PackagePath:"C:\Program Files (x86)\Windows
Kits\10\Assessment and Deployment Kit\Windows Preinstallation
Environment\amd64\WinPE_OCs\WinPE-PowerShell.cab"
Dism /Add-Package /Image:C:\WinPE\mount /PackagePath:"C:\Program Files (x86)\Windows
Kits\10\Assessment and Deployment Kit\Windows Preinstallation
Environment\amd64\WinPE_OCs\en-us\WinPE-PowerShell_en-us.cab"
Dism /Add-Package /Image:C:\WinPE\mount /PackagePath:"C:\Program Files (x86)\Windows
Kits\10\Assessment and Deployment Kit\Windows Preinstallation
Environment\amd64\WinPE_OCs\WinPE-StorageWMI.cab"
Dism /Add-Package /Image:C:\WinPE\mount /PackagePath:"C:\Program Files (x86)\Windows
Kits\10\Assessment and Deployment Kit\Windows Preinstallation
Environment\amd64\WinPE_OCs\en-us\WinPE-StorageWMI_en-us.cab"
Dism /Add-Package /Image:C:\WinPE\mount /PackagePath:"C:\Program Files (x86)\Windows
Kits\10\Assessment and Deployment Kit\Windows Preinstallation
Environment\amd64\WinPE_OCs\WinPE-DismCmdlets.cab"
Dism /Add-Package /Image:C:\WinPE\mount /PackagePath:"C:\Program Files (x86)\Windows
Kits\10\Assessment and Deployment Kit\Windows Preinstallation
Environment\amd64\WinPE_OCs\en-us\WinPE-DismCmdlets_en-us.cab"
Note: The location of PowerShell packages to be installed will vary according to the
version of the system on which the ADK is installed. The commands shown above
were installed on Windows 10 (Windows Server 2016). If using Windows 8.1
(Windows Server 2012 R2), the /PackagePath will need to point to C:\Program Files
(x86)\Windows Kits\8.1\Assessment and Deployment Kit\Windows Preinstallation
Environment\amd64\WinPE_OCs\.
22 | P a g e
The following steps perform a manual installation of UCS PowerTool. It assumes that
UCS PowerTool is installed on the system that is tailoring the WinPE image.
mkdir "C:\WinPE\mount\Program Files\WindowsPowerShell\Modules\Cisco.UCS.Core "
mkdir "C:\WinPE\mount\Program Files\WindowsPowerShell\Modules\Cisco.UCSManager "
attrib +s "C:\WinPE\mount\Program Files\WindowsPowerShell\Modules\Cisco.UCS.Core "
attrib +s "C:\WinPE\mount\Program Files\WindowsPowerShell\Modules\Cisco.UCSManager "
copy C:\Program Files (x86)\WindowsPowerShell\Modules\Cisco.UCS.Core\*.*
C:\WinPE\mount\Program Files\WindowsPowerShell\Modules\Cisco.UCS.Core
copy C:\Program Files (x86)\WindowsPowerShell\Modules\Cisco.UCSManager\*.*
C:\WinPE\mount\Program Files\WindowsPowerShell\Modules\Cisco.UCSManager
Startnet.cmd
When WinPE is booted, simply use Notepad to edit the contents of this file.
Notepad C:\WinPE\mount\Windows\System32\Startnet.cmd
When you are modifying Startnet.cmd, make sure you keep the wpeinit command at
the beginning of the file. Here is a sample Startnet.cmd file. Note in the PowerShell
command that there is a space between the period (.) and X:. This is required.
WinPE uses X: as its in-memory drive when it is running.
wpeinit
REM If DHCP is unavailable, configure the following command for your environment
REM netsh int ip set address "ethernet" static 192.168.10.190 255.255.255.0
192.168.10.1
Note: During your initial testing and debugging of your scripts, you may want to
remove the trailing exit command. This allows you to manipulate your scripts
23 | P a g e
within WinPE. The trailing exit command will cause WinPE to automatically reboot
the system.
WinPE_Automation.ps1
Since we have PowerShell available to us, it is easy to write the basic file necessary
to perform the minimum number of steps on the environment before launching the
primary script, Automation.ps1.
This sample file performs the following tasks:
Using a procedure like this allows for files to be changed in the download directory
quickly to change the deployment procedure without any need to make alterations
to the created WinPE image.
Though you can create this file in any existing directory on the WinPE image,
because it is not part of the regular distribution, I like to create a temp directory and
create the file there. Create a temp directory and use Notepad to create the file. (If
you do create the file in a different directory, make sure you change your
Startnet.cmd to reflect the different location than that shown in this sample).
md C:\WinPE\mount\Temp
notepad C:\WinPE\mount\Temp\WinPE_Automation.ps1
# Access the share for the automation files and for writing log files
New-SmbMapping -LocalPath S: -RemotePath $shareName -UserName $shareUser -Password
$sharePWD
Try
{
dir $shareScripts\Automation.ps1
}
Catch
{
# Failed to connect to share. Exit
Exit
}
Exit
24 | P a g e
Dismount WinPE Media
When all modifications have been performed, dismount the WinPE image and
commit the changes.
Dism /Unmount-Image /MountDir:C:\WinPE\mount /commit
If you do not want to save the image with modifications, discard all changes made.
Dism /Unmount-Image /MountDir:C:\WinPE\mount /discard
You can burn this to a DVD or simply mount it as virtual media to UCS Manager. I
will be using it as virtual media.
To create a bootable USB device, use the following command (F: is the location of
the USB media):
MakeWinPEMedia /UFD C:\WinPE F:
Windows Server comes with an optional role that can make it a PXE-boot server.
This role is known as Windows Deployment Services (WDS). This is a role that has
been available on Windows Server almost since the beginning of Windows Server
and it is well-established and used in many customer environments. It is common
to install the modified WinPE into a WDS deployment as the boot image for a PXE
boot. Installation of WDS and its configuration are beyond the scope of this
document. More information can be found at https://technet.microsoft.com/en-
us/library/hh831764(v=ws.11).aspx.
25 | P a g e
Unattend.xml XML file written by Automation.ps1 to the VHD created by this
process to automate the operating system deployment.
ServerSetup.ps1 custom script called by Setupcomplete.cmd to run against
any installation of Windows Server that is not a Nano installation. Stored in
E:\Share\Automation\<SPname>\Scripts.
NanoSetup.ps1 custom script called by Setupcomplete.cmd to run against
any installation of Nano Server. Stored in
E:\Share\Automation\<SPname>\Scripts.
The following examples demonstrate some of the things that you might want to
include in your automation scripts.
Automation.ps1
This is the primary script called by WinPE_Automation.ps1 in Startnet.cmd that will
tailor the installation environment when WinPE boots. You can add and remove
things here according to your specific needs. I will separate the complete file into
smaller sections to explain what the different sample sections are doing.
It is assumed that a single script named Automation.ps1 will be created. It will
include a mandatory parameter be passed to it. This script will be called by the
automation built into Startnet.cmd and will pass the Service Profile name as the
parameter.
Get-ServiceProfile
This section determines the name of the Service Profile assigned to the physical
machine on which it is running. The name of the Service Profile is used for finding
the directory in which the files customized for this Service Profiles configuration are
storage.
<#
Create paths to root automation shares
Read UCSM variable file
Import the Cisco UCSM PowerTool module
Connect to UCSM using credentials from above variables
Get the NIC information for the physical machine
Get all Service Profiles from UCSM
Compare NIC MAC addresses between running machine and each Service Profile until match is found
Match on MAC means we have found the Service Profile that defines this physical machine
Save the Service Profile name to be used for unique identification
#>
26 | P a g e
$ucs = [XML](Get-Content -Path $shareScripts\UCSM-Variables.xml)
Note: The above script references a file named UCSM-Variables that contains
access information stored in plain text not a secure way to handle credentials. A
more secure way would be to capture the password and store it securely into a file.
The following command will capture and store the password securely.
Read-Host -AsSecureString | ConvertFrom-SecureString | Out-File C:\Creds.txt
You can then retrieve the secure password from the file whenever needed and build
the needed credentials to use to connect to UCS Manager.
$pwd = Get-Content C:\cred.txt | ConvertTo-SecureString
Populate Parameters
WinPE_Automation.ps1 finds that information and passes it to this script when it
launches Automation.ps1. That value is used to determine the location of share
subdirectories and is also used to rename the computer to match the name of the
Service Profile.
27 | P a g e
NOTE: The <JoinDomain> section in this sample XML file works for non-Nano Server
installations. This sort of domain join operation is not supported in Nano Server,
yet.
<#
This section tailors the automation to a specific machine.
Using the $computerName variable defined in the previous section, it defines
some paths in order to read an .xml file configured for this specific
Service Profile.
<Var>
<LocalAdminPwd>password.1</LocalAdminPwd>
<WindowsProductKey>6XBNX-4JQGW-QX6QG-74P76-72V67</WindowsProductKey>
<TimeZone>Pacific Standard Time</TimeZone>
<BaseVHD>WS2016_DC.vhdx</BaseVHD>
<MgmtNIC>
<Name>Mgmt</Name>
<IP>192.168.10.75</IP>
<Mask>24</Mask>
<GW>192.168.10.1</GW>
<DNS>192.168.20.201</DNS>
</MgmtNIC>
<JoinDomain>
<Short>LJ</Short>
<FQDN>LJ.net</FQDN>
<User>Adminstrator</User>
<PWD>password.1</PWD>
</JoinDomain>
</Var>
#>
# Create paths for accessing the Service Profile Name share subdirectory
$spRoot = Join-Path -Path $shareRoot -ChildPath $computerName
$spExecutables = Join-Path -Path $spRoot -ChildPath "Executables"
$spLogs = Join-Path -Path $spRoot -ChildPath "Logs"
$spScripts = Join-Path -Path $spRoot -ChildPath "Scripts"
Partition-Disk
This section partitions a raw disk that will be used to host the native boot VHD
<#
Define variables used in the creation of the various partitions
Determine type of boot BIOS or UEFI
Clean data from ANY disk that has data ***
Find the first of the smallest disks to use as the OS disk
Initial disk and create partitions
#>
$Guid_GptType_Recovery = "{de94bba4-06d1-4d40-a16a-bfd50179d6ac}"
$Guid_GptType_Efi = "{c12a7328-f81f-11d2-ba4b-00a0c93ec93b}"
$Guid_GptType_Msr = "{e3c9e316-0b5c-4db8-817d-f92df00215ae}"
28 | P a g e
$Partition_Size_BIOSboot = 500MB
$Partition_Size_EFIboot = 99MB
$Partition_Size_Msr = 16MB
$Partition_Size_Recovery = 450MB
wpeinit
wpeutil InitializeNetwork
wpeutil WaitForNetwork
wpeutil UpdateBootInfo
29 | P a g e
Mount-Vdisk
This section configures the virtual hard disk to native boot the physical server.
<#
Copy VHDX file from share
Mount VHDX file
Find the diskpart volume number of the mounted vdisk
Assign a letter to that volume
Create bcdboot file on that volume
Copy tailoring scripts and executables to the VHD
Creates directories on the VHD and copies files to them
#>
If (!(Test-Path "$($vhdDrive)\Windows\Setup\Scripts"))
{
New-Item -Path "$($vhdDrive)\Windows\Setup\Scripts" -ItemType Directory
}
Copy-Item -Path $shareDrivers\*.* -Destination "$($vhdDrive)\Cisco\Drivers"
Copy-Item -Path $spExecutables\*.* -Destination "$($vhdDrive)\Cisco\Executables"
Copy-Item -Path $spScripts\*.* -Destination "$($vhdDrive)\Windows\Setup\Scripts"
Create-Unattend
This section creates an unattend.xml file that is automatically read during the
automatic installation process of the Windows operating system. This unattend.xml
file is created to a lowest common denominator regarding features that are
30 | P a g e
available to both Nano Server and Windows Server. Windows Server unattend.xml
supports many additional parameters. The file is written into the root directory of
the VHD file created.
Caution: Do not use this file without first determining that it meets your specific
needs.
<#
Set Registered Organization and Owner
Set computer name
Set time zone
Set Windows Product Key
Set local administrator password
Hide display of EULA
Set locale to en-US
#>
@"
<?xml version="1.0" encoding="utf-8"?>
<unattend xmlns="urn:schemas-microsoft-com:unattend">
<settings pass="specialize">
</settings>
<settings pass="oobeSystem">
<component name="Microsoft-Windows-Shell-Setup" processorArchitecture="amd64"
publicKeyToken="31bf3856ad364e35" language="neutral" versionScope="nonSxS"
xmlns:wcm="http://schemas.microsoft.com/WMIConfig/2002/State" >
<AutoLogon>
<Password>
<Value>$($xVar.Var.LocalAdminPwd)</Value>
<PlainText>true</PlainText>
</Password>
<LogonCount>1</LogonCount>
<Username>Administrator</Username>
<Enabled>true</Enabled>
</AutoLogon>
<UserAccounts>
<AdministratorPassword>
<Value>$($xVar.Var.LocalAdminPwd)</Value>
<PlainText>true</PlainText>
</AdministratorPassword>
</UserAccounts>
<OOBE>
<HideEULAPage>true</HideEULAPage>
<NetworkLocation>Other</NetworkLocation>
</OOBE>
</component>
31 | P a g e
<component name="Microsoft-Windows-International-Core" processorArchitecture="amd64"
publicKeyToken="31bf3856ad364e35" language="neutral" versionScope="nonSxS" >
<InputLocale>en-us</InputLocale>
<SystemLocale>en-us</SystemLocale>
<UILanguage>en-us</UILanguage>
<UserLocale>en-us</UserLocale>
</component>
</settings>
</unattend>
Setup-Complete
This section create a SetupComplete.cmd file. Once the Windows installation setup
is completed, it looks for this file on the first boot. If found, it will execute whatever
is in this file. It is a handy place to create additional tailoring that could not be
accomplished with the unattend.xml file.
Caution: Do not use this file without first determining that it meets your specific
needs.
<#
Set pagefile settings to small pagefile.sys
Set power configuration to run at maximum
Change PowerShell execution policy to allow for execution of script files
Determine OS being deployed and execute appropriate server setup script
Delete unattend.xml file
#>
@"
PowerShell "Set-ItemProperty -Path 'HKLM:\SYSTEM\CurrentControlSet\Control\Session
Manager\Memory Management' -Name ExistingPageFiles -Value
'\??\C:\pagefile.sys','\??\D:\pagefile.sys'"
set LOCALAPPDATA=%USERPROFILE%\AppData\Local
del C:\unattend.xml
Shutdown -r -t 0
"@ | Out-File "$($vhdDrive)\Windows\Setup\Scripts\SetupComplete.cmd" -Encoding asci -Append
Notice the last PowerShell command above that is being written to the
SetupComplete.cmd file. It is testing the name of the VHD used to provision the
environment. It is assuming a naming convention whereby any Nano installation
32 | P a g e
has a VHD name starting with Nano. Anything else is assumed to be a Windows
Server installation, not a Nano Server installation.
This process of a script calling another script shows how easy it is to chain
additional scripts together and to start their execution from within
SetupComplete.cmd. For example, you might want to enable/disable firewall rules,
set system parameters, and/or run specific applications. Below show a couple of
scripts that could be used to configure a Windows Server (full or core) or Nano
Server installation. If you want to set up something that requires a system reboot,
such as joining a domain or installing a role like Hyper-V, you will need to define that
as a PowerShell workflow, as a workflow will continue running after a system reboot.
Clean-BCD
When using UEFI booting, the Windows boot process makes use of firmware storage
for storing boot options. If you redeploy the same server more than once, old
entries in the bootmgfw.efi file can cause the automation process to fail. This
section of the script examines the contents of bootmfgw.efi and removes any stale
entries, i.e. any entries that are not valid for the current environment.
$BcdEdit = Join-Path -Path $env:SystemRoot -ChildPath "\system32\bcdedit.exe"
Start-Process -FilePath $BcdEdit -WindowStyle Hidden -Wait
33 | P a g e
}
You should end your Automation.ps1 script with the following commands to
dismount the VHD, disconnect from UCSM, and exit PowerShell.
Dismount-DiskImage -ImagePath $imagePath
Disconnect-Ucs
Exit
Variables.xml
This is a sample file containing just the basic information. It is possible to modify
some of the other scripts or add additional scripts to read more information from
this file to increase the automation capabilities. This sample file contains a
minimum number of variables to demonstrate what is possible. Additional
variables can be added to augment other automation capabilities that you may wish
to implement.
<?xml version="1.0" encoding="utf-8"?>
<Var>
<LocalAdminPwd>password.1</LocalAdminPwd>
<WindowsProductKey>6XBNX-4JQGW-QX6QG-74P76-72V67</WindowsProductKey>
<TimeZone>Pacific Standard Time</TimeZone>
<BaseVHD>Nano_C_C.vhdx</BaseVHD>
<MgmtNIC>
<name>Mgmt</name>
<IP>192.168.10.75</IP>
<Mask>24</Mask>
<GW>192.168.10.1</GW>
<DNS>192.168.20.201</DNS>
</MgmtNIC>
<JoinDomain>
<Short>LJ</Short>
<FQDN>LJ.net</FQDN>
<User>Adminstrator</User>
<PWD>password.1</PWD>
</JoinDomain>
</Var>
34 | P a g e
JoinDomain specify domain to join and credentials with privileges that can join
members to the domain. These values can be passed into the unattend.xml file to
automate the joining to the domain. This sample shows using the domain
administrator account. It is common practice to create an account with just the
privilege to add members to the domain instead of using domain administrator
credentials. It is possible to pass these values into an unattend file that will be used
for a non-Nano Server installation. Nano Server does not implement the unattend
steps that support joining a domain in this manner. See Getting Started with Nano
Server for details on how to configure an unattend that can be used by Nano Server.
UCSM-Variables.xml
This file contains the basic information needed to log into the UCS Management
domain.
<?xml version="1.0" encoding="utf-8"?>
<UCSM>
<IP>192.168.10.210</IP>
<User>admin</User>
<PWD>password.1</PWD>
</UCSM>
Unattend.xml
This file is created in the Create-Unattend section of the Automation.ps1 file. The
sample shown in this document is a simplistic example, as the unattend file has lots
of capabilities of configuring options. This capability has been around since the
beginning of Windows Server and is well understood by any customer that has any
form of deployment automation. Explanation of the capabilities of this file is beyond
the scope of this document.
When reviewing the Create-Unattend section of the Automation.ps1 file, you will see
there is variable substitution used. This allows for variable values to be passed into
the unattend file to tailor the file for each server being deployed.
35 | P a g e
$xVar = [XML](Get-Content -Path C:\Windows\Setup\Scripts\Variables.xml)
36 | P a g e
# Enable Remote Shutdown
Set-NetFirewallRule -Name Wininit-Shutdown-In-Rule-TCP-RPC -Enabled True -Profile Any
##################
# Not Remote Management requirements, but common changes
##################
37 | P a g e
$xVar = [XML](Get-Content -Path C:\Windows\Setup\Scripts\Variables.xml)
38 | P a g e
ForcePxeBoot
The following script can be used to force a PXE boot of your system. This is handy
during testing. After you have installed an operating system to a server, it will want
to boot to the operating system when the system is restarted. The following script
uses IPMI to make a one-time change to the boot environment to boot from LAN and
then restarts the machine. It requires that you have an IPMI user and IPMI Policy
defined in the Service Profile assigned to the server. Inputs to this script include the
IPMI username (it is case-sensitive), its password, and the CIMC IP address.
# Restart server to PXE boot
Write-Host ''
Write-Host -ForegroundColor Yellow 'Enter credentials for IPMI user. Username is case-sensitive.'
IPMI Policy
39 | P a g e
Service Profile Policy
Summary
The above sample shows a fairly minimal solution to automating the deployment of
Windows Server operating systems. You could add additional variables in the
Variables.xml file to define different options that you want to perform. Then modify
the above scripts to make additional changes, such as adding roles and features to
Windows Server installations or joining a domain, depending upon the variables
defined.
Cisco UCS Manager and PowerTool add other capabilities that are not possible with
other computer systems. For example, you may find situations where you would
want WinPE to perform some different tasks. You could keep a library of different
WinPE images tailored for specific situations. Then you could script the addition of
the WinPE ISO to the virtual media of a given server and then initiate a boot. This
means that it would be possible to automatically deploy servers on demand without
the need to customize a PXE server.
With a little imagination, you can automate just about anything you can think of.
Enjoy!
Author
Tim Cerling
Technical Marketing Engineer
Cisco Systems
40 | P a g e