SCCM and Chocolatey


Trying to leverage goodness from various mixtures of Chocolatey with SCCM is definitely not new. Others have been playing around with it for quite some time. However, I wanted to pause from a month of mind-numbing work-related things to jot down some thoughts, realizations, pontifications, gyrations and abbreviations on this.

Much of this idiotic rambling that ensues hereinafter is based on the free version of Chocolatey.  There is also a “Business” version that offers many automation niceties which you might prefer.  There’s a lot more to this Chocolatey thing than I can possibly blabber out in one blog post (even for yappy little old me), such as the Agent Service features, packaging, and so more.  Visit for more.

1 – Is it “Better”?

No.  It’s just different.  But, regardless of whether if “fits” a particular need or environment, it’s often nice to know there’s another option available “just in case”.

2 – Who might this be of use to?

I can’t list every possible scenario, but I would say that if the potential benefits are lined up it kind of points to remote users without the use of a public-facing (or VPN-exposed) distribution point resource.  It also somewhat negates the need for any distribution resource, even cloud based (Azure, AWS), since there’s no need for staging content unless you want to do so.

3 – How does SCCM fit?

At this point (build 1703) it’s best suited for use as a Package object, since there’s no real need for a detection method, or making install/uninstall deployment types.  A Program for installation, and another for uninstallation, are pretty much all that’s needed.

4 – How does an Install or Uninstall work via SCCM?

As an example, to install Git, you would make a Package, with no source content, and then create one Program as (for example only) “Install Git” using command “choco install git -y”, and another as “Uninstall Git” using “choco uninstall git -y”.  (Caveat: some packages incur dependencies, which may throw a prompt during an uninstall.  For those you can add -x before the -y, but refer to the Chocolately documentation for more details)

5 – How do you push updates to Chocolatey apps via SCCM?

You can use the above construct with a third Program named “Update Git” (for example) with command “choco upgrade git -y”.  Another option (and my preference) is to deploy a scheduled task that runs as the local System account, to run “choco upgrade all -y” at a preferred time or event (startup, login, etc.).  And, as you might have guessed by now (if you haven’t fallen asleep and face-planted into your cold pizza), someone has done this for you.

6 – Can you “bundle” apps with Chocolatey with or without SCCM?

Absolutely.  There’s a bazillion examples on the Internet, but here’s one I cobbled together for a quick lab demo a while back.  This one feeds a list of package names from a text file. You can also hard-code the list, or pull it from anywhere that PowerShell can reach it (and not just PowerShell, but any script that you can run on the intended Windows device).

7 – What about MDT?

Here’s a twist, you can deploy Chocolatey packages using MDT, or deploy MDT using Chocolatey.  How freaking cool is that?  If you sniff enough glue, you might even construct a Rube Goldberg system that deploys itself and opens a wormhole to another dimension.  By the time you find your way back, America will be a subsidiary of McDonald’s and we have real hoverboards.

8 – What about applying this to Windows Server builds?

You can.  I’d also recommend taking a look at BoxStarter, and Terraform.  I built a few BoxStarter scripts using Github Gists for demos a while back.  Here’s one example for building and SCCM primary site server, but it’s in need of dusting off and a tune up.  You can chop this up and do things all kinds of different (and probably better) ways than this.

The list of automation tools for building and configuring Windows computers is growing by the day.  By the time you read this sentence, there’s probably a few more.  Hold on, there’s another one.

PS – If you get really, really, reeeeeeally bored, and need something to either laugh at, ridicule or mock, you can poke around the rest of my Github mess.  I don’t care as long as you put the seat back down after flushing.

TextPad – the other editor

Like many developers and script kiddies (God, I hated that term for so long, but have gotten over that finally), over the years, I’ve used a great many different code editors in the course of getting work done on time.  I’ve forgotten more than I can recall, but some that come to mind include emacs, vi, pico, Aurora, EDLIN (ha ha! smack!), good old DOS EDIT (the crackbaby born from EDLIN in a dumpster behind a Walmart), Notepad++, Sublime, Eclipse, Komodo, PrimalScript, Wise Script Editor, ColdFusion, and dozens of app-embedded editors from AutoCAD/VLIDE, to Office VBA, to Visual Studio.  And I’m not counting the interesting graphical experiments like MIT App Inventor.

Today I typically use Visual Studio Code, PowerShell ISE, the PowerShell console, Notepad++, and Visual LISP IDE (VLIDE) when the need arises.

But one that I always seem to miss is TextPad.

One reason for that, is that I was (at the time) bouncing frequently between a lot of different languages, and I found the need to standardize on one editor that was:

  • Flexible / Customizeable
  • Powerful and Capable
  • Cheap!! (very, very cheap)

But here’s the rub: Helios (the developer) insists it’s not a “code editor” at all, but rather, a “text editor”.  Never mind all the syntax and snippet add-ons available for more “code” languages than “human” languages, they stand by that assertion.

TextPad has offered many standard code editing features since it’s early days, and is now at version 8.x, with updates emerging several times a year (so far).

Workspaces. Dictionaries. Macros.  Syntax definitions.  External tools.  Regex string functions.  Customizeable toolbars and panels.  In short, it’s very flexible and easy to customize.  In my (humblest of humbled) opinion, TextPad has the easiest and “best” (subjective) snippet management features of any editor.  Some others today are equal to it, but it had those features ten years ago.  And I’m a curmudgeon that barks “newer does *not* always mean *better*” hrmpff!! (and then I turn slowly and run away as fast as I can).



Here’s an example scenario for adding a language and support features for PowerShell v5 on Windows 10.  After installing TextPad, don’t launch it just yet.

  • Download the syntax files for languages you want to use from here.
  • Download my PowerShell v5 syntax file from here (because they’re slow to add new submissions from customers)
    • Note: Rather than being C/C++ based, this one works best with a PERL mapping, hence the “PERL=1” parameter at the top.
  • Drop the PowerShell5.syn file under %USERPROFILE%\AppData\Roaming\Helios\TextPad\8\
  • Open TextPad, click the Configure menu item and select “New Document Class”.
    • Class name: “PowerShell” or “PowerShell 5”
    • Class members: *.ps1, *.psm1, *.psd1
    • Enable syntax highlighting: check
      • Select the syntax file from drop-down list
    • Finish
  • Click Configure / Preferences
    • Note: for general editor settings, look under General, File, Editor and View at the top of the list.
    • Expand Document Classes
    • Expand “PowerShell” (or whatever you named it)
    • Select “Colors”
      • Set desired colors for Keywords 1 to 6, etc.
    • Select “Tabulation”
      • Modify tab settings as desired
  • Scroll to the bottom of the Preferences list (left-hand panel) and select “Tools”
    • Click “Add” > “Program”
      • C:\Windows\System32\WindowsPowerShell\v1.0\powershell.exe
      • Parameters: -ExecutionPolicy ByPass -File “$File”
      • Initial folder: $FileDir
      • Capture output: check
      • Suppress output until completed: uncheck
      • Sound alert when completed: (check or uncheck, you decide)
    • Click OK

Now, open a sample PowerShell script, and click Tools / External Tools / PowerShell (you can also press CTRL+1 to execute PowerShell, or CTRL+n, where (n) is the ordered number of the external tool in your list).  For the setup shown below, I could press CTRL+2 to run the script.  Note that there is only a full script run (like F5  in other editors), but no partial execution (like F8) for now.



  • You can change the path to use a OneDrive, Google Drive or other cloud sync folder, and then drop your files there for portability, much like Notepad++ offers.  To configure this, click on Configure / Preferences / Folders.
  • You can modify all support folder paths as well, including macros, snippets, etc.
  • I also have a PowerShell 5 snippet sample file for TextPad available here.


Is it “better” than other editors?  That’s a subjective question, for the most part.  As with programming languages, each seems to be better at some things than the alternatives.  The real measure is focusing on which features matter most and then comparing on just those areas.

Interview: Jon Szewczak


Name: Jon Szewczak

Job Title: Official: Programmer III
Job Title: Unofficial:  SQL Server DBA / .NET Web Architect / Windows / Intel Server Administrator / Pain in the a$$


I first met Jon somewhere between 2000-2004, while working on a rather large CAD software development project.  Me being older, and somewhat stuck in my ways, at first I had a tough time being questioned about “why” when it came to API choices and strategic decisions.  But it turned out to be a life-changing experience for me.  I had forgotten the adaptive mindset that has to exist when working with software, relying instead on hard-worn habits, some of which were from lack of being immersed in more dynamic environments.

After a few months of being a one-man-team, I had a tough time getting used to someone asking questions and offering other ideas to the project.  But Jon has a way of presenting ideas that make you listen, rather than just shoving it in your face.

We initially disagreed on quite a few technical aspects, but over time our thinking became more in sync, which I attribute much towards me learning to listen more.  Everyone I’ve ever worked with has rubbed off on me in various ways, and Jon is one of those who left a positive influence on me (I don’t have many positive attributes, so even one is better than none).  Anyhow, let’s get to it…

1. Describe what you do for a living – to someone who has no idea what it means.

Hmmm. That can be hard. My job title is Programmer III – like Superman III only not as cool and no Richard Pryor. That title means that I make computers do things by typing in commands that it can understand after a bunch of translating.

I have designed and implemented a vast majority of the programming code that runs the complex website at I also develop, maintain, and support several custom desktop applications that the associates at my company use on a daily basis.

But over the years, I have taken on other roles within the IT department. When I was brought in, I was immediately the “subject matter expert” on SQL Server, by virtue of having worked with it in my previous job. I was by no means an expert. However, lots of querying and reading and researching allowed me to actually morph into a much more competent data professional.

I manage the non-mainframe data warehouse, and I make sure that any applications or users that are touching it, do so in a manner that is nearly transparent to all parties involved. It’s a really tough job now because of aging hardware and increasing demands.

A few years ago, our parent company decided to implement a “Shared Services” IT model. Which means that all of the Network and Server support teams across many different locations were merged into one team – including the few that worked at my office. What that effectively did, was make all of team members work everywhere but my office and server room. The servers were suffering from neglect. So, since it was critical to my SQL Server(s), I started taking over the admin duties.

2. How did you get into this type of work?

I originally didn’t set out to be a computer programmer or an IT person. I was originally going to be a Drafter. I went to school to be a drafter and earned in an Associates in Computer-Aided Drafting (CAD) and Design. While I was there I took one class in CAD programming with AutoCAD. It was interesting, but I didn’t really see the huge potential of it at the time.

When I graduated and got my first job as a drafter in the Shipbuilding industry, I went to work for a place that used AutoCAD software, but it was highly-customized with the same programming techniques as I saw in college. That’s where I met an individual who is still a veritable genius in CAD programming.  This guy took me under his wing and showed me how AutoCAD could be made to do things that I never even dreamed of.  I started working right away on programming AutoCAD to do all kinds of things for me. Anything that I did more than once, I tried to figure out how to make it a one step command.

When some of my co-workers saw that, they wanted the shortcuts and macros and programs that I had developed too. So I started to share. Many more years later, I met Dave Stein (of this illustrious Blog [edit: his words, not mine, I promise, and no, I didn’t pay him for that]) and we (along with a few others) started really working on ShipWorks. ShipWorks was an automation tool-suite for AutoCAD that put the phrase “tool-suite” to shame. It was more of an application unto itself than a tool-suite.

Anyway, my CAD programming went on for many more years, but it was never my main job. It always was filler work. That is until I finally got an opportunity to program full-time – in the Modeling and Simulation arena.

3. What area or aspect of technology are you most excited about?

That’s kind of tough. There is so much cool programming out there that I look at and say “how did they do that? I wanna do that!” I am fascinated by wireless tech, and the way it has interconnected so many aspects of our life. Game programming is also another arena that amazes me. Getting 3D graphical characters to do things on the television screen with so much realism is just incredible.

4. What gives you the most satisfaction today?

I like to see things working the way they were meant to. Whether it’s an API, or a web page, or a desktop application, it doesn’t matter. I like to see it work and work efficiently. There is so much “just get it done” crap code in my company that it is really hard to describe. The people who originally wrote the legacy applications, really had no idea what they were doing to make an efficient application – it bugs every time I have to fix a bug or something. I have to fight the desire to rip it all apart and do it right.

5. Name the 3 most inspiring people in your life or career?

The first would be Brad Hamilton. He is the individual who took me under his wing as a “wet behind the ears” kid and showed me how and encouraged me to really dig into CAD programming to make things better, quicker, more robust, and more efficient.

The next would be Dave Stein – and no that’s not just a shameless “suck up” plug. Dave welcomed me as a partner in the ShipWorks venture and then handed the management of it over to me when he needed to move on. This allowed me to grow as an application manager and showed me that there is much, much, much more to programming and application development then just typing some lines of code.

The last, and most important is my wife. Without her I would not be where I am, I would not be as successful as I am, I would not be anything.

[edit: I’m hoping to get Brad involved with this interview effort as well.  Like Jon describes, Brad is someone who made a huge impact on me for many years.  Words like genius, visionary, and Grateful Dead fan, don’t begin to describe him.  I’m not so sure about that Dave guy.  But 2 of 3 isn’t bad.]

6. If I hadn’t gone into this field, I’d probably be ____?

Still working as a CAD designer in the shipbuilding industry. I am not one who changes things often or lightly, so I probably would have stuck to it. I am so glad that I did not.

7. Favorite place to travel?

I don’t really have one. Some place that is relaxing. I don’t do much of that, and I always think it would be nice to find a place where I can do nothing – guilt free.

8. What 3 books, movies or other works have influenced you most in life?

I am not a person who reads a lot of self-help or motivational things. I watch movies for the escapism, so there’s hardly anything influential there. I love the well written poetry of Robert Frost, Edgar Allen Poe and others.

But, really, the only two influential things I can think of here are controversial, depending on your personal beliefs and stances.  The first is The Bible. And I’m more specifically talking about the New Testament and the teachings of Jesus Christ. I am Catholic – but I’m also a progressive Catholic. I don’t always agree with everything the Catholic Church teaches or espouses, but overall I am in line with it. At any rate, the most important things I have taken from Christ’s teachings are acceptance and a need to care for those who cannot do it for themselves.

The other book that I always come back to is Six Hours One Friday by Max Lucado. In it he makes this point: Life is not Futile, Failure is not Fatal, and Death is not Final. It’s a wonderful way to try to live.

9. There’s never enough ______.


10. There’s way too much _____.


But, That’s Not All…

I sometimes do work on the side for people, setting up websites and what not. One of the sites I helped out with is for THE UNBATTLE PROJECT ( It is a non-profit organization helping to provide much needed counselling and therapy services to Veterans and Active Duty Military members.

It’s a very worthy cause, and (full disclosure) I am friends with the CEO of the organization. It’s in its beginning phases and could use all of the publicity and help that can be provided. So please spread the word.

Dave: Thank you!

PowerShell, Excel and AD stuff

smh.  I thought this might help some other folks, maybe.  Maybe not.  Anyhow…


Fetch the heading row from a CSV file and strip off those which contain a “_” (underscore) prefix, and those which are null (hint: when saving out of Excel as CSV UTF-8, or many mainframe apps, there is often trailing ,,,,,,,,,,, stuff on each row, even the heading row.  In fact, you can find rows of nothing but ,,,,,,,,,,,,,,,,,,,,,,,,,, at the end of the file, due to poorly written application features, but wtf).

This allows for making a custom spreadsheet that has a mix of column names you want and those you want to ignore (again, just using underscore prefix).  This example fetches only the column names which are valid AD user account attributes.  You can modify this however you want.

function Get-UserAttributes {
  param (
    [string] $InputFile 
  Write-Verbose "[Get-UserAttributes]"
  $attlist = @()
  $csvRaw = Get-Content -Path $InputFile
  # filter out columns with underscore prefix, null columns created by Excel output to CSV
  $attlist = $csvRaw[0].ToLower().Split(",") | ? {$_ -notlike "_*"} | ? {$_ -ne ""}
  $attlist = $attlist | ? {$_ -ne "samaccountname"} | ? {$_ -ne "name"} | ? {$_ -ne "path"}
  return $attlist

Notice I’m leaving out SamAccountName and Path, which is just due to this one particularly weird, glue-sniffing, drano-swilling, squirrel-roasting, car-chasing mess of a task on a messy project.  I fetch those from the actual CSV import.

So, to clarify (putting down the glue and the squirrel for now), this fetches the column names as one array, and fetches the rest of the data as one big chunk via Import-Csv.  But when iterating the big chunk, I only read the columns which are members of the Attributes array.  Sort of like letting anyone into the party, but only giving backstage passes to the ones with the weirdest costume.

Also, the “_LOAD” column, which controls whether the row should be processed (1) or ignored (not 1), and the $RowLimit parameter allows for limiting the CSV input to just the first N rows (or zero for unlimited).


$csvFile = "ADUsersList.csv"
$RowLimit = 0
if (!(Test-Path $csvfile)) {
  Write-Host "error: $csvfile not found"
else {
  $rowNum = 1
  $attlist = Get-UserAttributes -InputFile $CsvFile
  $attcount = $attlist.Length
  Write-Verbose "info: $attcount attributes returned"

  Write-Verbose "info: reading input data file..."
  $csvData = Import-Csv -Path $CsvFile | ? {$_._LOAD -eq 1}
  if ($RowLimit -gt 0) {
    $csvData = $csvData[0..$($RowLimit-1)]
  $csvRows = $csvData.Count
  Write-Verbose "info: loaded $csvRows entries"
  Write-Verbose "info: processing accounts..."
  foreach ($row in $csvData) {
    $sam = $row.sAMAccountName
    $upath = $row.PATH
    $uname = $sam
    Write-Verbose "info: [$rowNum] user = $sam"
    Write-Verbose "info: [$rowNum] path = $upath"
    ... do magical stuff here...

That’s it for now.  The script is much bigger and uglier, just not as ugly as I am, so it gets a weekend pass.

Anyhow, I hope it helps.  Now, where’s that squirrel hiding?…


PowerShell – The Little Stuff

While working with a customer to help them diagnose a problem with one of their scripts, one little, tiny, teeny, eeentsy-weentsy, itty-bitty, microscopic modification made a HUGE difference in finding the root cause of their issue.  It was a script that reads a custom formatted input file and runs the data through a bunch of ETL-type processing.

This wind farm isn't in Virginia, and APCo's proposal doesn't include building any new wind. But the cows are cute. Photo credit: NREL

Old rusty decrepit script

$inputdata | 
  foreach-object {
    write-verbose "updating record $($"

New shiny and sparkling script

$rownum = 1
$inputdata |
  foreach-object {
    write-verbose "[$rownum] updating record $($"

Notice the difference?  This made it easy to jump directly to the offending line in the input file and inspect for the information causing their script to puke all over the new sofa.  Not a big deal for small input files, but for 10,000+ lines it can help shorten the task of locating a problem.

Get Hyper-V Guest GUID values

As with the previous post on Getting Hyper-V Guest BIOS Serial Numbers, this turned-around flavor gets the GUID values.

param (
  [parameter(Mandatory=$True)] [string] $HypervHost,
  [parameter(Mandatory=$False)] [string] $GuestName = ""
if ($GuestName -ne "") {
  Get-WmiObject -ComputerName $HypervHost `
    -Namespace root\virtualization\v2 -class Msvm_VirtualSystemSettingData | 
      ? {$_.elementName -eq $GuestName} |
        Select-Object -ExpandProperty InstanceID
else {
  Get-WmiObject -ComputerName $HypervHost `
    -Namespace root\virtualization\v2 -class Msvm_VirtualSystemSettingData | 
      ? {$_.InstanceID -notlike 'Microsoft:Def*'} |
        Select-Object elementname, InstanceID | 
          Sort-Object elementName

Get Hyper-V Guest BIOS Serial Numbers

On occasion, I’ve need to fetch the BIOS serial number for Hyper-V guest machines BEFORE they’re powered-on.  Anyhow, here’s *a* way to fetch the serial numbers for all guests, or one guest in particular, from the Hyper-V host using PowerShell.

param (
  [parameter(Mandatory=$True)] [string] $HypervHost,
  [parameter(Mandatory=$False)] [string] $GuestName = ""
if ($GuestName -ne "") {
  Get-WmiObject -ComputerName $HypervHost `
    -Namespace root\virtualization\v2 -class Msvm_VirtualSystemSettingData | 
      ? {$_.elementName -eq $GuestName} |
        Select -ExpandProperty BIOSSerialNumber
else {
  Get-WmiObject -ComputerName $HypervHost `
    -Namespace root\virtualization\v2 -class Msvm_VirtualSystemSettingData | 
    ? {$_.BIOSSerialNumber -ne $null} |
      Select elementname, BIOSSerialNumber |
        Sort-Object elementName