Quick Fix : Registry key to disable Hardware Graphic acceleration for Office

July 22, 2014 FoxDeploy

Hope this helps guys!

reg add HKCU\\Software\\Microsoft\\Office\\15.0\\Common\\Graphics /v DisableHardwareAcceleration /t REG\_DWORD /d 0x0 /F

Continue Reading...

Using Try/Catch efficiently over a large list of commands

July 16, 2014 FoxDeploy

If you want to try catch over multiple commands, try this. We’re using the Invoke character to run a number of commands through a single try/catch block because frankly we can’t be bothered to type that much!

#Invoke-Expression errors are considered non terminating, which means Try/Catch won't natively work.  You need to set 

# errorActionPreference = 'Stop' in order to force this behavior, to allow try/catch to do its job 
$ErrorActionPreference = 'Stop' 
$com =@" Get-ChildItem c:\\drivers, Get-ChildItem hklo:, Get-ChildItem c:\\temp "@

$com.Split(',') | ForEach-Object {

try { Invoke-Expression $\_ -ErrorAction Stop }

catch { "Something went wrong" }



First off, we set $ErrorActionPreference = ‘Stop’, as Invoke-Expression errors are considered non-terminating for the interests of robust script execution. This means that if an error is encountered, it will be written out to screen and the show will attempt to go on, the script will continue running, etc. A terminating error, by comparison, will stop the show and display its output to the screen. In order to coerce PowerShell into exploring our Catch scripting block, we need to set the $ErrorActionPreference to Stop, so PowerShell will treat this seriously. If you want to see this principle in action, try running the above from the console with $ErrorActionPreference = “Continue”. You’ll notice that the error is displayed on screen and the Catch is never initiated! For this reason, we’re setting the value to ‘Stop’. Don’t worry though, if you run this in a script, the default ErrorActionPreference setting of Continue will be reinstated after the script runs. Speaking of which, be careful in the ISE, as variables set there tend to stick through your whole session.

So, $com contains all of our commands we want to run. We’re splitting the array at the comma to get a number of commands, then ForEach invoking the contents of the variable (ForEach stores the current object in a group of objects within the $_ special variable). IF there is an error, we’re catching it. This is not ideal, as sometimes we want to only catch certain types of errors. You could create special catch commands for each type of error, as shown.


$com.Split(',') | ForEach-Object {

try { Invoke-Expression $\_ -ErrorAction Stop }

catch \[System.Management.Automation.DriveNotFoundException\]{ "Double check that drive letter..." }

catch { "Something else went wrong" } } 

In this case, we specifically catch for errors of the type ‘System.Management.Automation.DriveNotFoundException’, and then redirect all other output to a generic catch block.

If you’d like more information about catching specific errors, check Ed’s post here : http://blogs.technet.com/b/heyscriptingguy/archive/2010/03/11/hey-scripting-guy-march-11-2010.aspx

Continue Reading...

Three tips for effectively using Try/Catch in PowerShell

July 16, 2014 FoxDeploy


As my responsibilites have grown and I’ve found myself crafting tools not just for my own use, but that will outlive me at clients and within the firm, I’ve recently become a complete convert to using error-handling in my functions.

If you’ve ever been in a situation in which you’re using someone else’s tools and they don’t account for common errors, I’m sure you understand the need for including common error-checking an validation in your own toolmaking. If you’ve never run into it yourself, maybe my tale can help you.

Long ago, in an SCCM migration project, I took over midstream for the build out of eighteen some-odd Secondary Site servers of an entrenched ConfigMan infrastructure. My task was to rebuild these Distribution Points (DPs) from 2003 to 2008 R2 Server, and to assist, a number of tools had been created. One streamlined the installation of prerequisites, while another–ExportPKGs–exported a list of all packages on the site as .PKG files I’d copy to the destination server. This tool also created a manifest of all of the packages found and included in the directory, ExportPKGs.txt. Finally, ImportPKGs would import those .PKG files directly into the target site server by means of automating the PreloadPkgOnSite.exe binary included in SCCM.

The issue that arose was that when using the ExportPKG, a log file was created which stored the status of each package on site. When I’d then run the ImportPkg tool, this same log file would be imported and the items enumerated, then fed into PreloadPkgOnSite.exe binary to import the package, thereby bypassing a lengthy copy operation from the primary to this new DP. When the Import tool ran, it would record a backup of the log file specified in the InputFile parameter, then overwrite the log file with its results.

Since these DPs were all over the world, I had to work some very odd hours (almost as odd as what I’m working right now from the East coast USA to migrate AD users in New Zealand in their own work hours) and during a particularly weird one, I flubbed the syntax of the command. This meant that the following files existed: • ExportPKGs - Now contained garbage, 0 length • BackupPKGs - Contained the previous content of ExportPKGs

Realizing my mistake, I then dilligently reread my syntax, then accidentally hit Up and then Enter into the command prompt. Both log files now contained garbage and I was no longer able to import the TXT file. To resolve the situation, I had to manually push all the likely packages from the 2007 Primary Site to this DP. What would have been a four hour decompress and import operation became a 28 hour slog of copy-decompress-import. It was a mild nightmare.

This issue clarified forever the need for good error proofing and validation in my tools. In my work, I’ve come up with the following tips for properly implementing Try/Catch in your PowerShell functions and tools.

Tip 1 Be lazy

It’s unpleasant to admit it, but we know that our users may not always be the most diligent about reading instructions. Yes, your elegantly crafted Word doc may go unperused, your beautiful Readme.txt may not be bookmarked and even your properly-implemented comment-based help may never be read. Trust on your users to skip all dialog boxes, dismiss all popups for credentials, and provide pure garbage for what mandatory parameters you do specify.

You can work around this by including parameter validation to ensure that your inputs really make sense for your process. Run through the tool, and try to imagine what mistakes a user might make. Maybe your parameter or switch names are too similar, or rely on easily confused nomenclature. Try to dismiss all credential, file-picker and other similar dialog boxes.

Tip 2 Have a friend try your code

We know how our code should work, in fact, most of the time, we could do the process manually and are making tools to enable others to perform a subset of tasks with safeties in place, or to save our own time. Since we know what to do, we also know which parameters or switches really matter, and whether or not we’re actually supporting pipeline input in our function. We know to provide data in a single-item per line form, not a comma separated value or Excel file!

Having a friend test your code will show you all of the ways you never thought to run your code. And adding the error handling for this will likely double the length of your functions if not more.  When you walk your tester through the process, begin with giving hardly any instruction at all.  Ideally, you’ll catch a half-dozen or more instances in which you can better your coding through Error Checking.

On a recent project, it wasn’t until I was scheduled to go on vacation and had to train someone else on one of the tools I created that I realized how many different ways he may innocently misuse the tool, and with potentially disastrous affect!

Tip 3 Don’t use a catch-all

This is the ostrich method to dealing with problems. If you set a single catch statement, or worse, use -ErrorAction SilentlyContinue, you’re just denying problems and can end up deep into your tool with no real idea of what kind of input you’re dealing with. You’re setting yourself up for a resume generating event if you do this.

Tip 4, Bonus tip: Fail safe

I said three tips, but I had to throw in this bonus. It’s used in weapons systems, reactors, and automated investment platforms (well, sort of): fail safes.

If you’re unsure of the quality of your Error Catching, try to ensure that under worse-case scenario circumstances, you don’t pull an Emory or nuke your datacenter from orbit.

Scripting can very easily turn one small problem into infrastructure wide outages, and turn you from being a respected automation engineer into that guy who accidentally nuked the CEO’s Laptop

One method I like to use on my tools destined for others is to add a mandatory -WhatIf to very serious commands.  I effectively override ConfirmImpact settings to make my end-users confirm that they really want to move User A into Groups A-Z or likewise.  It’s just one more click but adding a measure like this can ensure that your users are reading impact (for instance, you can use $Confirm = Read-Host “Type Confirm exactly as listed on screen to commit $action” or something similar as a method of shifting culpability to those who should know better).

An additional trick to failing safe it to set a subset of actions as Verboten and never allow them to execute.  If you have a Function which removes users from a Security Group, at no point should Domain Admins or Enterprise Administrators be allowed as acceptable input.

Continue Reading...

Download a full YouTube playlist with PowerShell

July 08, 2014 FoxDeploy

Recently, a colleague approached me requesting pointers on the quickest possible way to download a YouTube playlist.  I’d used KeepVid.com previously, to download videos one at a time, but never found a good tool to use to download a full playlist.  So I decided to make one!


This tool depends on you already having the wonderfully useful youtube-dl.exe downloaded on your system.  I placed it in my %PATH% directory, but you can also run this code directly from wherever you placed the binary.  Get the tool here if you don’t already have it:  http://rg3.github.io/youtube-dl/

You should make sure your link loads in Playlist form.  It should look like this:


You can get your playlist by selecting the URL from a page that will generally look like this.

If it doesn’t contain a playlist, this method won’t work for you.  Once you have your URL, provide it in the $PlayListURL in the top line of the code:

$Playlisturl = "http://www.youtube.com/playlist?list=PL1058E06599CCF54D&" 
#Next, the real magic happens in this ungainly one-liner

$VideoUrls= (invoke-WebRequest -uri $Playlisturl).Links | ? {$\_.HREF -like "/watch\*"} | \` ? innerText -notmatch ".\[0-9\]:\[0-9\]." | ? {$\_.innerText.Length -gt 3} | Select innerText, \` @{Name="URL";Expression={'http://www.youtube.com' + $\_.href}} | ? innerText -notlike "\*Play all\*"

We’ll break it down element by element:

We begin by Invoking a WebRequest for our URL and selecting all of the links. Next, we select only the playlist items that contain a direct video reference (contains “/watch”), then further filter to remove those without a playtime in the innerText field, which indicates direct links to times within videos.

Next, we remove items with a title with less than three characters, to remove duplicate entries, then we move on down the pipeline to set up a calculated property to perform some adjustment to the URL property.  We finally remove all items that survived to this point, which have ‘Play All’ in their name (which is typically reserved for the first entry in a playlist.

Sample output of a playlist

This gets saved and then fed to the binary one by one!

ForEach ($video in $VideoUrls){ Write-Host "Downloading $($video.innerText)" .\\youtube-dl.exe $video.URL } 

This process supports WGET, so your downloads can even resume!

Completed Code

$Playlisturl = "http://www.youtube.com/playlist?list=PL1058E06599CCF54D" 
$VideoUrls= (invoke-WebRequest -uri $Playlisturl).Links | ? {$\_.HREF -like "/watch\*"} | \` ? innerText -notmatch ".\[0-9\]:\[0-9\]." | ? {$\_.innerText.Length -gt 3} | Select innerText, \` @{Name="URL";Expression={'http://www.youtube.com' + $\_.href}} | ? innerText -notlike "\*Play all\*"


ForEach ($video in $VideoUrls){ Write-Host ("Downloading " + $video.innerText) .\\youtube-dl.exe $video.URL } 
Continue Reading...

Listen to my team on the PowerScripting podcast

June 17, 2014 FoxDeploy

Hi guys,

A few weeks ago, our team–The Kitten Mittons–had the honor of being on the PowerShell.org PowerScripting podcast to talk about PowerShell and our experiences competing in and winning the 2014 Winter Scripting games.  My team mates, including Jason Morgan and Julie Andreacola, are incredibly sharp, and teaming up with them was such a great experience.

You can listen to us here: http://powershell.org/wp/2014/06/15/episode-273-powerscripting-podcast-the-scripting-games-team-winners/

Tune in later this week, I’m about to release a guide on how you should, and how you shouldn’t attempt to add -WhatIf support to your scripts.

Continue Reading...

Read my contributions to The DSC Book

June 09, 2014 FoxDeploy

Hi guys,

I was honored when Don Jones contacted me, wanting to use my DSC post in ‘The DSC Book’, a free ebook available from PowerShell.org.

Download your copy here!

Continue Reading...

Microsoft MVP

Five time Microsoft MVP, and now I work for the mothership

Need Help?

Get help much faster on our new dedicated Subreddit!

depicts a crowd of people in a night club with colored lights and says 'join the foxdeploy subrreddit today'

Blog Series
series_sml_PowerShellGUI series_sml_IntroToRaspberryPi Programming series_sml_IntroToWindows Remote Management Series The Logo for System Center Configuration Manager is displayed here Depicts a road sign saying 'Learning PowerShell Autocomplete'

Blog Stats