Software deployment through WDS

Published on Wednesday, 4 March 2015

In my environment, I had to set up a new Windows Deployment Services (WDS) configuration for Windows 8.1 Enterprise. To roll out in our office (some 20+ workstations). I wanted to install some additional software at the same time, without using Microsoft Deployment Workbench, because I find the interface too slow. The solution? Read on...


To install additional software through Windows Server 2012 R2 WDS: wrap your software deployment in a PowerShell script and put it as a Synchronous FirstLogonCommands to your ImageUnattend.xml file, created with Windows System Image Manager (WSIM). Or run your PowerShell script manually as a post-installation thingy.

Here is how to install software packages during a Windows Deployment Services (WDS) deployment, without Microsoft Deployment Workbench (available in the Microsoft Deployment Toolkit, or MDT).

Windows Deployment Services (WDS) without Microsoft Deployment Workbench

For some, the Microsoft Deployment Workbench (available in the Microsoft Deployment Toolkit, or MDT) is a bless. It was for me too, but I've always disliked the slow interface. So when I got the opportunity to set up a new Windows Server 2012 R2 deployment server, with WDS, I decided to try to stay away from using the Deployment Workbench. For as far as I can tell, it succeeded pretty well.

Once you have your WDSClientUnattend.xml and ImageUnattend.xml configured the way you want them to be (e.g, they work), you can start messing around with them using Windows System Image Manager (WSIM). Don't forget to make a backup.

Like I said in the beginning of this article, I want to deploy a standardized set of software to newly installed and deployed workstations, and I don't want to use MDT (neither a deployment through Group Policy Objects, or GPO).

On a side note: How do you like and use WDS and MDT for your deployments? Share your thoughts in a comment, thanks!

PowerShell post-Windows installation deployment script

I came up with the following PowerShell script as a manual post-installation software deployment solution:

# PowerShell script to install software packages through # Windows Deployment Services (WDS)Set-Variable -name sharepath -value "\\fileserver\deployment" -scope script # disable SystemRestore, needed to install software because it bugs my Event logs# this may fail in other Windows versions$SysRestore = [wmiclass]"\\$sysname\root\default:systemrestore"$SysRestore.Disable("C:\") # define Office 2013 installation function, set up your config.xml firstfunction installOffice2013 { &$sharepath\Office2013\setup.exe /config standard.ww\config.xml -Wait} # define installation functionfunction installSoftware { Start-Process -NoNewWindow msiexec -argument "/i $sharepath\7z938-x64.msi /quiet" -Wait Start-Process -NoNewWindow msiexec -argument "/i $sharepath\EMET_5.1_Setup.msi /quiet" -Wait Start-Process -NoNewWindow msiexec -argument "/i $sharepath\AdbeRdr11000_mui_Std\AcroRead.msi /quiet" -Wait Start-Process -NoNewWindow msiexec -argument "/update $sharepath\AdbeRdrUpd11010_MUI.msp /quiet" -Wait Start-Process -NoNewWindow msiexec -argument "/i $sharepath\install_flash_player_16_plugin.msi /quiet" -Wait Start-Process -NoNewWindow msiexec -argument "/i $sharepath\install_flash_player_16_active_x.msi /quiet" -Wait Start-Process -NoNewWindow msiexec -argument "/i $sharepath\googlechromestandaloneenterprise.msi /quiet" -Wait Start-Process -NoNewWindow "$sharepath\Thunderbird Setup 31.5.0.exe" -argument '/S /V"/Passive /NoRestart' -Wait Start-Process -NoNewWindow "$sharepath\Firefox Setup 36.0.exe" -argument '/S /V"/Passive /NoRestart"' -Wait Start-Process -NoNewWindow "$sharepath\FileZilla_3.10.1.1_win32-setup.exe" -argument '/S' -Wait Start-Process -NoNewWindow "$sharepath\gpg4win-2.2.3.exe" -argument '/S' -Wait Start-Process -NoNewWindow "$sharepath\npp.6.7.4.Installer.exe" -argument '/S' -Wait Start-Process -NoNewWindow "$sharepath\KeePass-1.28-Setup.exe" -argument '/SILENT' -Wait Start-Process -NoNewWindow "$sharepath\fiddler4setup.exe" -argument '/S' -Wait} # run the installation functionsinstallOffice2013installSoftware

hé kewl, silent installation parameters?! Where did you find these?
Back in 2012 I wrote an article about silent installation switches to use with WDS/MDT. Most of them are in that article and are still valid, go check them out.

Due to spaces in the file name, I renamed the Enhanced Mitigation Experience Toolkit (EMET) installation msi EMET 5.1 Setup.msi tot EMET_5.1_Setup.msi, because the spaces, single and double quote escaping sucked...

Another note is I had to disable Windows SystemRestore, because it creates a restore point for every .msi installation. I also had to bypass PowerShell ExecutionPolicy to execute the installation script successfully:

PowerShell -ExecutionPolicy ByPass -File \\fileserver\deploySoftware.ps1

Hook into Windows Deployment Services' FirstLogonCommands for software installations

As you can imagine, test driving a lot of installations and deployments, I thought it was better to not to have to type the deploySoftware.ps1 PowerShell command anymore. So I looked further.

In our Microsoft courses, we've learned that in the WDS oobeSystem (or Out Of Box Experience) configuration pass, settings are applied before the "Windows Welcome" message starts. Some options usually used are language or creating user accounts.

To me, utilizing the WDS oobeSystem sounded ideal for deploying software during an installation. The component Microsoft-Windows-Shell-Setup contains elements and settings that control how the Windows operating system shell is installed on a destination computer. It also contains FirstLogonCommands.

FirstLogonCommands specifies commands to run the first time a user logs on to the computer. These commands run only once.

Long story short, just add your deploySoftware.ps1 script as a FirstLogonCommands in your ImageUnattend.xml file.

See the image below:

Deploy Software through WDS

How to Deploy Software through WDS, automated as a FirstLogonCommand

FirstLogonCommands ImageUnattend.xml

In plain XML, the ImageUnattend.xml lines are:

<FirstLogonCommands>    <SynchronousCommand wcm:action="add">        <Order>1</Order>        <CommandLine>PowerShell -ExecutionPolicy ByPass -File \\fileserver\\deploySoftware.ps1</CommandLine>        <Description>Installs software to deployed work stations</Description>        <RequiresUserInput>false</RequiresUserInput>    </SynchronousCommand></FirstLogonCommands>

Conclusion deploying software through Windows Deployment Services

I hope you liked this article. I haven't found many online references for using FirstLogonCommands to deploy software during a WDS deployment of Windows 7, 8 or Windows 8.1. Certain tasks, sequences and hooks might be better (smoother, faster) when used in Windows Deployment Toolkit, but I didn't really like the Workbench tool.

As always, timtowtdi.