2013 New Year Resolutions

I originally started out this post with “It’s a short list, but…”, and after writing out the list I’d say it’s a pretty reasonable size.

  • No more double spaces to end sentences. Although I think it’s a bigger deal that people would notice and complain than whether or not there’s actually an extra space in there, it just seems to be the way things are going
  • I intend to adhere to the DRY (Don’t Repeat Yourself) coding principle hard core. I’m already rewriting some PowerShell scripts at home to help solidify my commitment
  • I’ve taken a more serious approach to my resume. Gone are fun words like Jedi and Wizard. Replaced are many many bullet points
  • Set a schedule and add more time to my day. For example, I’ll be setting up a calendar reminder starting this weekend to bug me weekly to write a blog post here. By being more schedule-based I hope to be more focused and not waste away time being distracted and less focused on tasks at hand. I already try to avoid watching tv/movies and gaming at the same time – it’s time to expand that out to more aspects of my life
  • No more soda! I’ve quit cold turkey and while I’ve already had a couple panic moments of “OMG I WANT COKE” I’ve been getting by alright. I hope to never give in to the temptation of the free soda at work
  • Find and act on measurable career improvement opportunities. My (kind of former) boss has been helping me with career performance evaluations. His guidance has been super-helpful already. Last night I assessed all of it to look at the bigger picture and will be actively working to improve my “Operational Skills”


Having MDT automatically update WDS remotely

The MDT blog has a great primer on how to update WDS automatically every time you generate new boot media. But I ran into some difficulty because for me WDS lives on a different server

I’m not going to get super-technical, but here’s what I did to solve the problem:

  • I had to install the WDS role on my server hosting MDT. I didn’t configure anything or authorize the server – I just needed it to add the WDSUTIL command. I have a hunch that one could just find where that .exe lives and copy it to a client OS, but thankfully didn’t have to even test that
  • In the UserExit script, I added a /server:myservername flag to the WDSUTIL command. Here’s what it looks like (all one line):

sCmd = “WDSUTIL /Replace-Image /Image:””Lite Touch Windows PE (” & oEnv(“PLATFORM”) & “)”” /server:myserver.fqdn.com /ImageType:Boot /Architecture:” & oEnv(“PLATFORM”) & ” /ReplacementImage /ImageFile:””” & oEnv(“CONTENT”) & “SourcesBoot.wim”””



Automatically upload MDT Boot Images to a vSphere datastore

There’s a pretty good guide out there for making MDT automatically update WDS boot .wim files when you’re updating the media. Based on that, I took things one step further and scripted things so our virtual infrastructure gets the same automated treatment.


  • Your vSphere environment should be at least ESXi 4.x
  • Install the latest version of PowerCLI from VMware. They’re entirely backwards compatible
  • Run the Deployment Workbench with an account that has the appropriate roles and permissions to log into vCenter via PowerShell and upload files to a datastore. You have more options if you want to get tricky with PowerCLI (and you’ll have to explore those if you use ESXi with no vCenter manager!)
  • These instructions assume you haven’t already tweaked things to automate uploading to WDS. I went this route because I did some things a little different than what was in the link above.
Make Magic Happen
  1. Where you installed MDT (probably C:Program FilesMicrosoft Deployment Toolkit) create a subfolder called Scripts
  2. Also where you installed MDT, open up the Templates folder and edit LiteTouchPE.xml (feel free to make a backup first!). Scroll down way to the bottom. Look for the Exits section and change the following:
    • Original line: <Exit>cscript.exe “%INSTALLDIR%SamplesUpdateExit.vbs”</Exit>
    • New Line: <Exit>cscript.exe “%INSTALLDIR%ScriptsUpdateExit.vbs”</Exit>
  3. Use Notepad to create two new files in your new Scripts folder
    • UpdateExit.vbs
    • Update-Vcenter.ps1
  4. Copy the contents at the bottom of this post into the appropriate script
  5. Make sure to change the parts of Update-Vcenter.ps1 that are in bold to reflect your environment – There are three things you need to chage: The vSphere server and the name of the DataStore you want your data uploaded to
That’s it! It’s working well for me in MDT 2012 Update 1 + ESXi 4.1. If you also want to do the WDS auto-update stuff, just update the UpdateExit.vbs script. If you’re having trouble, you can run the PowerShell script on its own. Just give it a file path/name as an argument and it’ll upload that file to your datastore.

UpdateExit.vbs Contents


‘ // ***************************************************************************
‘ //
‘ // Copyright (c) Microsoft Corporation. All rights reserved.
‘ //
‘ // Microsoft Deployment Toolkit Solution Accelerator
‘ //
‘ // File: UpdateExit.vbs
‘ //
‘ // Version: <VERSION>
‘ //
‘ // Purpose: “Update Deployment Share” exit script
‘ //
‘ // ***************************************************************************
Option Explicit

Dim oShell, oEnv, sCmd, rc
‘ Write out each of the passed-in environment variable values

Set oShell = CreateObject(“WScript.Shell”)
Set oEnv = oShell.Environment(“PROCESS”)

WScript.Echo “INSTALLDIR = ” & oEnv(“INSTALLDIR”)
WScript.Echo “DEPLOYROOT = ” & oEnv(“DEPLOYROOT”)
WScript.Echo “PLATFORM = ” & oEnv(“PLATFORM”)
WScript.Echo “TEMPLATE = ” & oEnv(“TEMPLATE”)
WScript.Echo “STAGE = ” & oEnv(“STAGE”)
WScript.Echo “CONTENT = ” & oEnv(“CONTENT”)
‘ Do any desired WIM customizations (right before the WIM changes are committed)

If oEnv(“STAGE”) = “WIM” then

‘ CONTENT environment variable contains the path to the mounted WIM

End if
‘ Do any desired ISO customizations (right before a new ISO is captured)

If oEnv(“STAGE”) = “ISO” then

‘ CONTENT environment variable contains the path to the directory that
‘ will be used to create the ISO.

End if
‘ Do any steps needed after the ISO has been generated

If oEnv(“STAGE”) = “POSTISO” then

‘ CONTENT environment variable contains the path to the locally-captured
‘ ISO file (after it has been copied to the network).

sCmd = “C:windowsSystem32WindowsPowerShellv1.0powershell.exe -File “”C:Program FilesMicrosoft Deployment ToolkitScriptsUpdate-Vcenter.ps1″” ” & oEnv(“CONTENT”)
WScript.Echo “About to run command: ” & sCmd

rc = oShell.Run(sCmd, 0, true)
WScript.Echo “PowerShell rc = ” & CStr(rc)

WScript.Quit 1

End if

 Update-Vcenter.ps1 Contents

Add-PSSnapIn VMware.VimAutomation.Core -ErrorAction SilentlyContinue
Connect-VIServer -Server your.vSphere.Server -ErrorAction Stop
$datastore = Get-Datastore “Your datastore
New-PSDrive -Location $datastore -Name iso -PSProvider VimDatastore -Root “”

#Copy ISO to deployment share
foreach ($arg in $args) { Copy-DatastoreItem -Item $args -destination “iso:” }

Remove-PSDrive iso
Remove-PSSnapIn VMware.VimAutomation.Core


Update: I realized there’s one weird situation where people following this might run into problems. If you have an NFS datastore, you may not be able to write to your datastore directly through vCenter. If that’s the case, you’ll want to connect directly to a ESXi host instead. Check out the New-VICredentialStore command for how to do this without storing your password in the script.



Automatically Update your MDT Reference Images

Typical workflow for handling reference images in MDT:

  1. Import OS install media from an ISO you downloaded off Technet / Microsoft Volume Licensing
  2. Build a task sequence to deploy it (I call this my Build Image task)
  3. Capture it to the Captures folder on your deployment share
  4. Import the captured OS
  5. Build a task sequence to deploy it (I call this my Deploy Image task)
This looks mundane, but doing steps 3, 4 and 5 sucks! Trying to remember exactly how you customized your task sequence is no way to live when it’d be way easier to re-use the existing Deploy Image task when updating your reference image.  I also would love it if I’m not the only one who can perform updates to reference images ….so I figured it all out and now I live happily every after!
It’s a little extra work up front, but here’s how you can turn updating your reference images into a one step process that anyone could perform:
  1. Create a script called Relocate.cmd in your Scripts directory off the Deployment Share that contains the following one-liner:
    • move /Y "%DEPLOYDRIVE%Captures%1.wim" "%DEPLOYDRIVE%Operating Systems%1"
  2. Create your Build Image task. Keep the ID short. For example, let’s say we’re deploying a general purpose Windows 8 image.  My Task Sequence ID that builds the reference image is 8_GP
  3. Run this task sequence and capture your reference image. Make sure to save it to the Captures folder and name it after your task sequence. For my example, this is .Captures8_GP.wim
  4. This one time, you’ll need to use the Import Operating System wizard. Be sure to name the folder for this operating system to match your task sequence that builds the reference image. For my example, I have .Operating Systems8_GP8_GP.wim
  5. Go back into your Build task sequence and add a custom task that runs the following command as the final step (you don’t need to set the Start In value):
    • cmd /? %SCRIPTROOT%Relocate.cmd %TaskSequenceID%

      Note: Do to ever-vigilent WordPress Security, I had to change out the letter C to a question mark. Pleaee change it back when trying on your own.

  6. Create your new Deploy Image task sequence using the OS from the previous step. I recommend that for your Task Sequence ID you use something like 8_GP_DEPLOY
You’re done! At this point, to get the latest Windows Updates into an image, just run your “Build Image” task  sequence – the WIM is captured and automatically replaces the OS that gets deployed when someone runs the “Deploy Image” task.
There is one word of caution: Significant changes to the OS in your WIM (Service pack, new IE version, etc.) might break the Deploy OS task. If that happens go through step 3 and step 6 again so that the MDT can “refresh” what it knows about the deployment OS you’re using


Microsoft Deployment Toolkit trickiness

So over the past few days I learned a very long and slow lesson about why the Microsoft Deployment Toolkit only has instructions for using local storage. Turns out, there’s either a bug in WinPE or in certain storage filers’ (NetApp) implementation of CIFS.   Due to one of those two factors, connecting to network storage from WinPE is buggy. It works just enough to make you want to blame everything else in the universe because it should “just work”.

Well, after I got over that, I was still stuck with a server with no available local storage, and a huge NetApp volume sitting there doing nothing. So I decided to get tricky. We have good network performance and an awesome storage admin, so I decided to virtualize my deployment share. I created a fixed disk 200 GB VHD file and had it mount to  path on the local storage. Using the Disk Manager GUI in Server 2008 R2 made this easy, but it also could have been done via diskpart if you want to go all CLI (I have yet to see straight-forward PowerShell stuff for working with VHDs directly).

This was cool and so far has been working pretty well, although I have yet to do an in depth comparison of deployment speeds when I have more than one or two clients doing an install.

One final challenge I had was that on a reboot the VHD would disappear until someone went and remounted it. I fixed that by doing the following:

  1. Create a script with two lines (don’t include the 1. and 2.) and save it in the same folder on the NetApp/filer/whatever as your VHD file. I called my “Dev.dp” because this is a Dev environment and the script will be run with DiskPart
    1. SELECT VDISK FILE=”\uncpathtoyourfile.vhd”
  2. Open Task Scheduler and in the Actions pane pick Create Basic Task…
  3. Give your task a name. For the trigger, pick “When the computer starts”
  4. For the action, choose Start a Program. Use the following info:
  5. Program/script:  c:windowssystem32diskpart.exe
  6. Add arguments:  /s “\uncpathtoyourDev.dp”
  7. Click the check box to open properties when you’re done. In the General tab, change these settings:
    1. Use Change User or Group to set an account that has permissions on the NetApp. For me that was MYDOMAINsvc.deploy
    2. Pick Run whether user is logged on or not
    3. Check Run with highest privileges
  8. In the setting tab, you may want to back off the failure conditions or have the task retry if it fails (but don’t forget if for some reason it was already mounted, the task will fail because of that)

At this point you’re all done. When diskpart mounts the VHD it will automatically restore the mount point or drive letter that was used last time it was mounted. You can now use a filer to store your deployment data, but have it behave as if it were local storage because that’s the only way your deployment server will work. And your system can survive a reboot without manually re-attaching the drive!



Windows 8 Installation GUI makes me mad

Maybe this is trivial, but it really irks me:

As Windows 8 first loads a user profile, it gives a mini-tutorial on how to move the mouse into a corner to access your start menu or metro apps or whatnot.  It’s nice enough, except for one tiny thing – except for the very beginning of the animation, nowhere does it say “Tutorial” on it.  I started my first Win8 install, walked away, and happened to walk back when the animation is repeatedly saying “Move the mouse to any corner of the screen.” I thought that I had problems with my mouse or my USB drivers and did all kinds of keyboard button pushing and plugging/unplugging/replugging. When the tutorial finally went away I figured it just gave up.

So yeah…. all I’m asking for is some kind of text above or below the animation that indicates stuff is going on in the background and I just need to sit tight. Seems like a basic tenant for UX design to me!



DirectX 11 and Windows 8

So this is more of a call for help than an actual blog post.  For anyone working with Windows 8 RTM… anyone know what’s up with DirectX?  I’m supporting developers who are antsy for the supposed improvements with DirectX 11.1.  When I run dxdiag I see a very generic “DirectX Version: DirectX 11”. Searching the registry I found HKLMSOFTWAREMicrosoftDirectX has Version and InstalledVersion values.

The Version string appears to have not changed since Windows XP (reflects DirectX 9). I’m having difficulty converting the InstalledVersion binary string into anything useful.

So, what’s the deal? Is Windows 8 running DirectX 11.1?  Or 11.0? Inquiring developers want to know! There’s also the age old question of whether 11.1 will be released for Windows 7 as well. I would think so based on Microsoft’s history of past minor version releases.



Tech Ed – Part 3 of 3

Originally I thoght I could get away with splitting things into two posts. But like some kind of nerdy AM/PM commercial, there’s just too much good stuff!

Here are summaries for the rest of the panels I attended at TechEd last month:



TechEd 2012 Part 2 of 3

Well, I’ve gone over the MDT stuff from TechEd, but that was just one day. There were four other days for me to wander around and get into trouble! Here’s a quick summary, with deep-dives possible in future posts:

Edit: That was a giant wall of text! I’ve broken some things out into a Part 3 for a future post.



TechEd 2012 Part 1 of 3

I can’t believe I let my last, somewhat negative post sit there for so long! It’s time to be positive and look at the future.

Last month I flew out to Florida with a coworker for Microsoft’s TechEd conference. I hate be a “fanboi”, but Microsoft really has be excited about Server 2012 after seeing what exactly their vision is for their operating system. They call it a Cloud OS which is a bit of a stretch, but it’s also not completely inaccurate – they’re doing a great job of making it easy to prevent one-offs for any server you stand up. For example: they’re worked out the DHCP server role so that you can have multiple servers and high availability but only a single management point – in the Server Manager console, just lump multiple servers together and they’ll communicate with each other to replicate the scopes/leases/reservations for you; no more 80/20 split or other fail-over methods required. I use that as an example because DHCP is near and dear to me at work at the moment, but all of the server roles are being tweaked for that kind of behavior.

There was a lot of great things I learned about. I’ll go over the general stuff in a follow-up post, but to get started the rest of this post is dedicated to my day 1, where I spent 8 hours in a room with a personal hero of mine: Michael Niehaus. He’s the lone wolf developer and project manager of the Microsoft Deployment Toolkit. Along with a guest speaker, he showed off a lot of what’s coming in MDT 2012 Update 1, and went over many of the most challenging aspects of OS deployments and how to overcome them. The seminar was cohosted by an MVP consultant who is well known for running http://deploymentbunny.com/. The stuff below is in no particular order, and I had a hard time telling what exactly was exclusive to the not-yet-released Update 1.