Planning for Windows Deployment Services in a BYOC Environment

(This article assumes familiarity with Windows Deployment Services and image deployment in a Windows environment. For more information, please visit TechNet)

Windows Deployment Services (WDS) is an extremely powerful tool that you are likely already using if you are an IT support professional in a mid-sized or enterprise environment. Windows Deployment Services is available with a Windows Server Standard edition license and higher, and centralizes the deployment of Windows OS images and drivers. It allows images to be installed to PCs over the network via PXE boot. It also allows for the creation of “Discovery Images” which are WinPE images that are able to find WDS servers on different subnets (no network configuration required, aside from ensuring a route exists between the field office and the WDS datacenter), which is perfect for field techs that need access to many images, but have limited flash drive space.

Windows Deployment Services is compatible with other valuable deployment tools such as the Microsoft Deployment Toolkit (MDT) and System Center Configuration Manager (SCCM). It’s a common misconception that Microsoft Deployment Toolkit and System Center Configuration Manager replace Windows Deployment Services, but a more accurate statement is that they extend Windows Deployment Services.

However, Windows Deployment Services does have its fair share of gotchas. Chief among them being that you cannot inject drivers into a WinPE that’s newer than the WDS server’s Windows version. So a Windows Server 2012 R2 server cannot (through the GUI) inject drivers into a WinPE for Windows 10 boot image or a Windows 10 install image. This is because the DISM version used by the server is older than the version of the WinPE/Windows 10 image. We’ll get into a workaround for this a little later.

Despite its shortcomings, Windows Deployment Services is still an extremely powerful (but finicky) tool for OS and driver deployment, and for many IT organizations it is “good enough.” If an endless torrent of driver issues plague your WDS environment, it may be attractive to ask upper management to pony up for SCCM. However, this very rarely, if ever, goes well…as long as the lights are still on, at least.

It is much more prudent to fix your WDS environment instead.

BYOC – Scourge of the Earth

My current employer is moving from a BYOC policy back to keeping PCs as internal assets in order to retain control over PCs. However, there are still a smattering of HP, Dell and Lenovo PCs and laptops in our environment, which presents challenges when it comes to deploying drivers. Here are some tips I have gathered fighting the good fight against corrupt and incompatible driver packages.

Tip #1 – Use WinPE for Windows 10

WinPE for Windows 10 is Microsoft’s updated offering of a pre-boot environment. This environment only supports a fraction of Windows features, but it’s just enough to deploy a full version of Windows from it. The reason I prefer the upgrade is because some RealTEK drivers work better (read: they work) on WinPE for Windows 10 rather than WinPE 3.1 (Windows 7 SP1’s version of Windows PE). WinPE for Windows 10 also offers an updated set of generic drivers that works with most Intel NICs out-of-the-box. Using this, I only have to inject 1 driver into the boot image to ensure that 100% of the PCs in the company can PXE boot the WinPE environment (and thus, successfully complete an imaging process).

This, however, creates an issue with WDS if you are running Windows Server 2012 R2 or lower. Since DISM will only operate on images that have a lower system version than itself, Server 2012 R2’s DISM won’t work on the WinPE for Windows 10 boot image to inject drivers, so they’ll need to be manually injected by an administrator using Windows Deployment Toolkit, which offers a newer version of DISM.

Tip #2 – Keep your boot images light

Driver corruption is the number 1 reason that image deployments fail. It is prudent to ensure that your boot images that load WinPE only have the minimum amount of drivers needed for image deployment.

For my boot images, I only include the network drivers as that is all that is needed for the devices in my environment to boot into a WinPE environment and contact the imaging server.

Also, remember to match your driver’s intended Windows version lines up with the WinPE version. Also, watch out for drivers that are specifically made for WDS as they are intended to be used in boot images and WDS driver deployments.

Tip #3 – Use driver groups and filters

This might seem like a no-brainer to some, but I am shocked at how many WDS environments I’ve come across that put all driver packages in the same group with no filters. This makes it extremely difficult to troubleshoot driver issues that may arise via corrupt or incompatible drivers.

A sane grouping and filtering strategy is to group and filter drivers by machine model. This way, if a driver is introduced that is applicable to a lot of PCs, which also happens to break images and deployments — it will minimize impact to just those driver groups, and make it easier to remediate the issue.

With the rapidly changing workplace and BYOC policies becoming commonplace, well-planned imaging strategies have become a must for the modern sysadmin. This post concludes the first part of a series on WDS. In part 2, we’ll talk about how to troubleshoot driver issues within WinPE, and an introduction to answer files.

Until next time!


Posted in Tutorials

1 Comment »

Manipulating CSV Data into Arrays with PHP

While I was working on the DoomCRM project today, I began to think about how we are going to migrate our vast amounts of historic data into our new database, which has a wildly different schema. Well, instead of having people go through and upload everything through the forntend, I decided it would be much easier to have them output the files as a CSV, then have PHP parse it into a usable format.  Well, here’s how I did it (with some easy to understand comments)!

* Let's take the header and put it into a header variable

$header = ["Player name","Player ID","Team","Season","Start","End"];
* Let's place our csv data into a variable. In real-world practice, you'd likely use fopen to open the csv file, assign the first line to the header, and the rest to a different variable.

$str = "

* This bit of code breaks apart $str into an array wherein $line[$x] will contain a single line from the csv. The explode command breaks $str when it sees PHP_EOL, or, in human terms, an end of line character. We then use array_filter to get rid of the blank array entries that the explode command creates. We will need the $count variable to assign a key to our outer array.

$line = array_filter(explode(PHP_EOL,$str));
$count = 0;

* Now we take each $line as value $a and break it up into array $b using the comma character

foreach($line as $a) 

  * So now we have the following..
  * $b[0]=Player Name
  * $b[1]=Player ID
  * $b[2]=Team
  * $b[3]=Season
  * $b[4]=Start
  * $b[5]=End
  * We can now create the loop to assign our values to our new array.
  * The loop below takes the array size of the header (in this case it's 6), and assigns our comma separated values, which are stored in array $b, to the $out array, with a key of the the header key value.

    $out[$count][$header[$i]] = $b[$i];

Quesitons? Feel free to contact me on Twitter – @shark_rad

Posted in Tutorials

No Comments »

Let’s Play Doom – Compiling Odamex in Ubuntu 16.04 – 3 Easy Steps!

Everybody loves the demon-bashing, heart-racing, classic FPS Doom. Sometimes, when you feel the urge for some of them classic old-school FPS feels, you just gotta play some Doom. Fortunately, Odamex, will allow you to do just that. Odamex is a online multiplayer port for Doom fully delivers, and unlike other Doom ports that try and turn the game into Quake, Odamex feels  authentic. Now, if you’re a Linux junkie like myself, you’ll be happy to know that Odamex is one of the few multiplayer ports that will run in it.  So here’s how to install Odamex in 3 easy steps.

1. First, let’s update the apt-get repositories and install some dependencies.

$ sudo apt-get update
$ sudo apt-get install cmake gcc g++ git libsdl2-dev libsdl2-mixer-dev libwxgtk3.0-dev

WARNING: If you are installing Odamex 0.7.0 or lower, ie, not the master branch on GitHub, you will need to install libsdl1.2-dev and libsdl-mixer1.2-dev, and NOT the sdl2 libraries.

2. Next, we’ll enter your Home directory,  clone the Odamex repository into our home folder, prep our build folder, and call cmake to generate the makefile.

$ cd ~
$ git clone
$ cd odamex
$ mkdir build
$ cd build
$ cmake ..

3. And now, our last step! If everything went smoothly, we can now compile Odamex with

$ make

Once your compiler does its job you will end up with client, odalaunch, master, and server folders inside your your build folder. You can now run Odamex issuing the following:

$ cd client
$ ./odamex


Posted in Tutorials

No Comments »

Utilizing BASH and AWK to Merge Text Files

Sometimes, you need BASH to do some oddball things. This is one such task.


You are given two text files, file P,  which contains an alpha descending list of people, and file F, which contains a list of filenames belonging to that person. You would like to merge these files into a single, tab-delimited text file for later processing. Well, here’s how you can use BASH to do so!

$ nano ~/
echo "********** DIP FILE PREPARER **********"
echo ""
echo "
This program accepts 2 input files, an index file (f) containing the split PDF files and an index file (p) which contains the ids of the people to be matched with their file.  Please make sure that both files are sorted by alpha-descending (A to Z) order and that both files have the same number of lines, or the script will be unable to match them properly.
echo "==============================================================="
echo "1. Prepare ref or file index file"
echo "2. Merge ref_index.txt and file_index.txt"
echo "3. Display example pre-processed index file"

echo "What would you like to do?"
read action

case $action in
  "1") 	echo "Preparing file name index file"
       	echo "Please input full or relative file path to your index file containing a list of files: "
       	read file_index
       	echo "Please enter an output file name (no file extension is necessary): "
       	read output_file_index
       	awk '{ printf "\x22%s\x22\n",$0}' $file_index > $output_file_index.txt
       	echo "File output to $output_file_index.txt"
  "2")	echo "Please input location of index file"
	read file_index
	echo "Please input location of ref file"
	read ref_index

	# get line count of each file
	ln_file_index=$(awk 'END {print NR}' $file_index)
	ln_ref_index=$(awk 'END {print NR}' $ref_index)

	# check if line counts are equal
	if [ "$ln_file_index" == "$ln_ref_index" ]; then
		echo "Files match!"
		echo "Please input Round Name (RG 2017, FED 2017, etc.)"
		read round
		echo "Preparing parser_output.txt"
		echo -e "\x22ref\x22\t\x22filename\x22\t\x22round\x22" >> parser_output.txt
		# loop and output lines into output file
		for (( x=1; x<=$ln_file_index; x++ ))
			echo "Processing $file_index line $x"
			file_line=$(awk "NR==$x{print;exit}" $file_index)
			ref_line=$(awk "NR==$x{print;exit}" $ref_index)
			echo -e "$ref_line\t$file_line\t\x22$round\x22" >> parser_output.txt
		echo "Processing complete"
		echo "Files do not match!  Please make sure that the files have a matching line count"
		echo "$file_index line count  $ln_file_index"
		echo "$ref_index line count $ln_ref_index"
  "3")	cat sample_index.txt|less

Posted in Tutorials

No Comments »

Installing Laravel 5.3 On a Fresh Copy of Ubuntu 16.10

In this video, we’ll go step-by-step and install Laravel 5.3 onto Ubuntu 16.10. We’ll tackle Laravel’s dependencies, as well as understand what they do. This tutorial should work for earlier versions of Ubuntu as well.

If you’ve enjoyed this video please stop by to comment or subscribe to my channel.

Happy Coding!

Posted in Tutorials

No Comments »