How did you learn about (insert tech here)?

I see this question posted a great deal on social media. The answers are often as different as the folks asking/ answering the question. Many times it depends upon the context and the subject of the request as well.

This has prompted me to provide my own answer to the everlasting question…maybe even some unsolicited advice…

When I began my journey more than two decades ago, there were none of these “social media” outlets available to bring us together to share information. Instead, we had to use search engines like webcrawler, ask, and others to hopefully find some white paper or bulletin board where someone posted an FAQ or statement about what we were trying to get done. If that was unsuccessful, it was off to the local library or bookstore to find a manual about it. Basically, it was just a step above stone tablets, messages in a bottle, smoke signals, and carrier pigeons. Not unlike our very own search for the grail.

Charging Unto

Today, everything is virtually at our fingertips. Information can be obtained by simply typing in a keyword or two about anything our minds and hearts desire…sometimes we get too much, or even completely unrelated (horrifying) information we never wanted in the first place.


My point is that if we need information or examples of how to perform some function of our jobs, there is a plethora of available things to find. All we need do is look. Over the course of my career, I’ve looked, found, and even contributed to that information (as have many of you out there).

There are three lessons here:

  1. There are no stupid questions; unless they remain unasked, and you need the information.
  2. Never be afraid to ask questions. We all had to begin somewhere.
  3. When you know the answer, share it. This moves us all forward.

This brings us to the list of sites that I personally look at when I need answers. This list may not be complete, the sites may not be the foremost authority, but they do usually point me in the right direction at the very least. Your list of “go to” sites may be similar, or completely different.

Whatever list we go through should always be updated, added to, and/ or trimmed so that the information we find is as current and up to date as we can get.

My List (at least the start of it):

Using ConfigMgr Compliance to Manage Security Configuration Baselines (Part 3)

If you haven’t already done so, below are links to the previous posts in this series to give you a chance to go back and read them to get caught up.

And now… on to part 3!

Where we are so far…

In the previous post (part 2) we did the following:

  • Exported (backed up) the Group Policies we wanted to create ConfigMgr Configuration Items from.
  • Generated all of the INF files using the exported Group Policies.

Next, we need to generate two things that we will need for the ConfigMgr Configuration Items.

  1. Generate the scripts
    1. Setting discovery scripts
    2. Setting remediation scripts

Generating the Scripts

We have some choices here, we can manually create each PowerShell script by hand for each setting we need to monitor and enforce compliance on, or we can be smart about it and leverage a single script with functions in it to write the scrips we need for us. Since I dislike having to type so much, we opted for the latter.

For our script, it needs to do the following actions:

  1. Get all of the INF files we generated
  2. Process each one
  3. Output a PowerShell script for setting discovery
  4. Output a PowerShell script for setting remediation

If we ran the script from part 2, all of our INF files should reside in a directory structure in the same path as the script. This makes it very easy to get all of our INF files. We can simply add these three lines at the top of our script.

This will get all of the files with the INF file extension under the directory ‘Custom-INF-Files’ and store them in the variable ‘$CustomINFFiles’.

Next, we need to process all of the custom INF files which means we will need a ‘Foreach’ loop… like this.

So far we have the INF files, and the ‘Foreach’ loop, now we need to add functionality that will actually do what we need. The easiest way would be to leverage functions (or snippets of code already produced and easily located on the internet. Other ways might be to see if people we know have already done something close to what we want to do. Thankfully, we didn’t need to reinvent the wheel in this area.

Since we can’t do file copies from within Configuration Items, we needed a way to copy the INF file for the setting we are checking. To do this we read the INF file into a base64 encoded string and write the string back to a file like this.

With a little help from DR Scripto’s Microsoft Dev Blog post ‘Use PowerShell to Work with Any INI File‘ we get the following function.

With some assistance from @theznerd, we were able to modify the function from Dr Scripto to create the code needed for our discovery scripts. Sample below…

Now we need to perform the remediation. Since we’ve chosen to use ‘secedit.exe’ that is what our PowerShell script will run to import the setting that we’ve determined to be “Compliant” with our organization’s security policy. We’ll first write the file from base64 and then run ‘secedit.exe’ to import it into the ‘secedit.sdb’ (local security policy database) on the target system.

Now we just need to pull the function together while being careful to escape special characters where needed so that our discovery and remediation scripts will be written and function properly. (In the interest of maintaining focus, I’m not going to get into the explanation of escaping special characters in PowerShell at this time.) Our final function for generation of our discover and remediation scripts looks like this. (Use the toolbar above the snippet to expand or copy the code)

We needed to actually output the generated script files now, so I just used a 3 line function that can be used to write text into any file that accepts text or strings as content.

Putting it together

All we need to do now is take our code snippets, add them to the Foreach loop and add a few things to make it all work for us, then save the file as ‘Generate-CMConfigItemScripts.ps1’

(Use the toolbar above the snippet to expand or copy the code)

After running the script we should now have all of the pieces needed to create our ConfigMgr Configuration Items and the settings within them.

Generate Scripts

In the next and final part, we’ll go through creating the Configuration Items and the Configuration Baselines with remediation enabled…with PowerShell.

Have a great week! See you soon!

Using ConfigMgr Compliance to Manage Security Configuration Baselines (Part 2)

In part 1, we set the stage for the work we are about to do. We briefly went over the items that led up to our decisions. In the next parts, we’ll walk you through what we did. If you would like, you can go back and read Using ConfigMgr Compliance to Manage Security Configuration Baselines (Part 1) to get caught up.

Active Directory Group Policy

We need to get the settings that were already configured within the domain so that we can create the needed INF file templates for the non-registry policy settings.

To do this, let’s fire up an elevated PowerShell session and do the following:

If you know the name of the GPO you are looking for, you can simply export it to the desired location of your choice. Like this…

If you don’t know the name of the policy you are looking for, you can get the names using the following…

Or, if we only know part of the GPO name, we can search for all of those that have the portion of the name we remember in it. Example – to get all GPOs that contain the word ‘Default’ in the name…

But what if we want to have a choice of exporting ALL Group Policies, or just those with a specific word or term in their name? Well, we would script that. The script might look something like this (The script below is the same script we used for our customer. I’m just placing it here for others to use if they wish.) By the way, you can also copy the code below and save it as ‘Export-GroupPolicyObjects.ps1’. It can be used to backup GPOs in the future as well.

(The code below can be expanded and copied using the snippet toolbar at the top)

If we run the above script with the following command-line

We see this output…

Output example from Export-GroupPolicyObjects.ps1 script

OK, so now we have our GPO exported to “C:\Temp\GPOExports\Default Workstation Policy”. Let’s go take a look at the INF file. The file we need from the GPO is ‘GptTmpl.inf’. It should be located in “C:\Temp\GPOExports\<GPOName>\<GPOGuid>\DomainSysvol\GPO\Machine\Microsoft\Windows NT\SecEdit”.

First, let’s tackle the User Rights Assignments since they won’t be converted to ConfigMgr Configuration Items with the script.

Open the ‘GptTmpl.inf’ file with notepad to edit it. We need to remove all of the lines we don’t need.

You’ll notice that the INF is broken up into sections with each section header specified between the square brackets “[ ]”. There are three (3) sections we are interested in. They are:

  • Unicode
  • Version
  • Privilege Rights

All of the other sections can be removed. Once this is done, you should have a file that looks similar to below.

GptTmpl.inf Example 1

Depending upon your organization’s security requirements, there may be more or less entries. Save the file as ‘UserRights.inf’ in the folder “C:\Temp\INF Files” so that we can create our individual custom INF files for use in our compliance remediation scripts.

Another way to create the custom INF files for our use is to leverage a script that will go through and generate them for us. The script code below will do just that. Just copy and save the code as “Generate-AllCustomINFFiles.ps1”

(The code below can be expanded and copied using the snippet toolbar at the top)

When you run the above script, the screen output should look something like this…

Generate-AllCustomINFFiles.ps1 script output screen

Now that we have this much ready to go, we can move on to generating our discovery scripts for the ConfigMgr Configuration Items.

Below are links to the other posts in this series.

Using ConfigMgr Compliance to Manage Security Configuration Baselines (Part 1)

You want me to do what?

The alarm clock is screaming at me to get the heck out of bed. I snooze it twice, then finally get up. Once I’ve dressed, I cruise to the kitchen for some much needed coffee because I stayed up waaay too late the night before. After coffee, I walk to my home office where my laptop awaits, along with a likely plethora of emails to respond to before continuing work on a client’s project. It seems like just another day, nothing new… on cruise control.

As soon as I sit down, I check Teams to see what’s going on and if anybody needs any immediate assistance with some technical issue they are experiencing. Wouldn’t you know it, my manager is pinging me to discuss an upcoming project for one of our clients.

Manager: “Hey! We have a project slated to start next week, and I think it’s right up your alley!”

I’ve heard this before

Me: “Awesome! What needs to be done?”

Manager: “Our customer needs to have some ConfigMgr work done around Compliance Settings.”

Compliance Settings in ConfigMgr? This is going to be another quick and easy engagementnothing too difficult or strange to worry about

Me: “Great! I’m in.”

famous last words

There was much more conversation than that, but I will spare you the details and just cut to the kick-off call with the customer…

Customer: “We have a security audit approaching, and we need to apply security settings to our servers and workstations. As well as be able to document and convey our strategy moving forward according to our security specifications.”

Me: “No problem, what exactly are we looking at doing? Don’t you already have Active Directory GPO to set these?”

Customer: “We do… but moving forward as an organization we are moving away from GPO for many of the ‘STIG’ settings and want to leverage ConfigMgr to accomplish our goals.”

Me: “STIG settings?”

Customer: “Yup.”

I’ve not had to do much with STIG settings in the past because these were always handled by the various security teams. Surely I was selected for this project by mistake, right? But I like to think that I’m an intelligent guy, I can figure this out..let’s roll with it

Me: “OK, do you have the settings rules identified and your organizational settings documented?”

Customer: “We do, in total there are close to 3 to 5 HUNDRED security settings that need to be checked, monitored, and remediated when needed on an ongoing basis for Windows Server 2016 alone. We need the same done for Windows Server 2008, 2012, 2012 R2, 2016, 2019, and Windows 10.”

Did he just say “3 to 5 HUNDRED security settings for Windows Server 2016 alone”??… holy cow that’s a lot

Me (as if it didn’t even phase me): “No problem, when does it need to be done?”

Customer: “We’d like to have this done yesterday or as soon as possible, because the Federal audit begins in about a month.”

HmmmThat’s 3 to 5 hundred settings for each for 6 operating systemsThat means a potential of 3,000 settings to check, remediate, and report on in a month for a Federal auditWhat have I gotten myself into here?

Me: “I’m not sure that we can get up to 3,000 settings done in under 4 weeks, but we’re going to try. If we don’t make it by the time the audit starts, we definitely will have a documented strategy in place that we can communicate.”

Customer: “Excellent! That will work. Is Monday good for you as a start day?”

Me: “Works for me!”

The whole time we were on the call, I was searching the internet for everything that I could find about applying STIG settings with ConfigMgr Compliance. Let me just say this…there is a serious lack of documentation around this…

I made the commitment, I better deliver. Time to get to work.

What are some of the ways that I can do this?

Below are simply a few of the ways that we can get this job done. These are in no way intended to be the final word on the subject.

Active Directory Group Policy

We can also create a backup of the policies and then grab the settings we need from the ‘GptTmpl.inf’ file. With the settings we need, we can create INF files to be used to effect the settings desired using ‘secedit.exe’.

During my searches, I found the Microsoft Security Compliance Toolkit. The description of the toolkit from Microsoft says that it is a set of tools that allow administrators to “download, analyze, test, edit and store Microsoft-recommended security configuration baselines for Windows and other Microsoft products, while comparing them against other security configurations.”

After having downloaded the toolkit, I found that it is preconfigured Group Policy Objects that can be imported into the domain. Once imported, we are able to modify the policies to match what internal security teams have determined to be the best for their organizations. This is all well and good, except that many of these settings may not be tested in an environment and carry with them the potential to cause widespread issues upon deployment if they aren’t vetted first. Remember, each environment is different. Different applications, jurisdictions, requirements, work styles, people, and cultures. Also these preconfigured policies may have far more settings configured than what is needed by a particular organization.

Further, if an organization already has a large number of policy objects and filters within the domain that are deployed . The aggregation of these policies and filters can conflict (if they are not planned and modeled properly), and cause performance issues in applying the policies. This can result in policy processing timeouts that are seen by incomplete application of the settings, or policies not being applied at all; as reflected by the errors reported in client event logs.

Tattoo the Local Registry

The term is exactly as it sounds. It means to manual create or import registry settings that remain static on a destination system.

Registry settings will work for a great number of things except policies like renaming guest accounts, renaming administrator accounts, password complexity, and user rights assignments to name a few. If your organization decides that a change or modification is needed, all that needs to be done is to push out the settings with a deployment tool or script that applies the changes through PowerShell remoting, or WinRM. However, if the setting is determined to need removal, we might run into some difficulties if we don’t have a toolset that allows us to perform this action in bulk. The recommendation is to avoid registry tattooing; if it cannot be avoided, only tattoo settings that we know will NEVER change after they are initially set.

Manually Edit the Local Security Policy

Using the command ‘secpol.msc /s’ at the command prompt (elevated), will open up the “Local Security Policy” editor. From here we can go through each of the desired settings and make the changes necessary to effect the security posture as defined by our organization. Of note here is the ability to set a configuration as needed, then export that configuration from the command-line using ‘secedit.exe’. Once we have the configuration exported, we can then import that same configuration onto other systems using different command-line options for ‘secedit.exe’.

This is great if we only have a few dozen systems to manage. When we begin talking about hundreds or even thousands of machines, we need to be looking for a better way (or combining this with other methods).

Use PowerShell Desired State Configuration (DSC)

In Microsoft Docs, there is an article called “Quickstart: Convert Policy into DSC” that describes how to convert Group Policy backups into DSC. This works great if we are converting the canned policies from the Microsoft Security Compliance Toolkit. Mileage may vary when we try to use it on a GPO backup from and existing policy within our domain. The command ‘ConvertFrom-GPO’ within the ‘BaselineManagement’ PowerShell module doesn’t seem to handle the quotes and apostrophes within the legal banner and header text in the GPO correctly. As of January 2021, this has been an issue for almost three years with no movement toward getting it fixed. To get around the issue, you’ll need to modify the ‘GptTmpl.inf’ file within the GPO backup or remove the settings from a copy of the GPO prior to making the backup.

Once we are able to successfully run the ‘ConvertFrom-GPO’ command, a MOF file is created with all of the settings contained in the GPO. This MOF file can then be used to apply our DSC configuration to our target systems.

Please note that to successfully apply the configuration, two additional modules will be needed on the target systems:

Of course, this method is not without its potential issues. If your environment leverages FIPS policies as part of the security configuration, the PowerShell modules needed will not be able to be installed onto target systems. We’ll need to figure out a way to download and install those modules offline in order to have success.

OK, so what now? What’s my path?

Pick a Pony and Ride That Thing!

Ultimately, we chose to do a combination of the following:

  • Active Directory Group Policy
    • Grab the ‘GptTmpl.inf’ files from GPO backups
    • Create custom INF files for each of the non-registry policy settings we need
  • Create PowerShell discovery scripts to determine compliance with the settings
  • Create PowerShell remediation scripts that run ‘secedit.exe’ to import the custom INF files we created
  • Create ConfigMgr Configuration Items for registry policies using a PowerShell script “Convert-GPOtoCI
  • Create ConfigMgr Configuration Items for non-registry policies and leverage the custom discovery & remediation scripts we’ve created

We decided to do the work this way because:

  • In order to install PowerShell modules onto the target systems, we would have needed a rollout plan for that including change management because of the potential impact on the environment
  • FIPS policies were in place and modules could not be downloaded from the gallery
  • ‘Secedit.exe’ was on every target Operating System within scope
  • We had time constraints that didn’t allow addition of project effort and scope at the time

With the decision made, we needed to get moving. Time was not our friend.

Continue the series…

Food recipes: Low Fat – Low Carb – Low Calorie Hamburger Chili

This recipe is great for those of us trying to lose weight and eat healthy while on the road or even in our home markets. You can play around with the seasonings to adjust the flavor to your liking, but overall this is a great flavor!


  • 3 lbs – 96%/4% Lean Ground Beef
  • 17 – Pureed Roma Tomatoes
  • 1.5 tbsp – White Wine Vinegar
  • 3 tbsp – Sea Salt
  • 3 tsp – Ground White Pepper
  • 3 tsp – Ground Black Pepper
  • 2 tsp – Jalepeno Tobasco Sauce
  • 2 tsp – El Tapatio Sauce
  • 4 tbsp – Fresh Minced Garlic
  • 6 tbsp – Dried Minced Onion
  • 2 tsp – Ground Oregano
  • 2 tsp – Ground Cumin
  • 1 tsp – Cajun Spice or Cayenne Pepper
  • 1 tbsp – Ground Chili Powder


In Large Skillet add the the following and brown lightly. Then remove from heat and set aside.

  • 3 lbs – 96%/4% Lean Ground Beef
  • 2 tbsp – Dried Minced Onion
  • 1 tbsp – Fresh Minced Garlic
  • 1 tsp – Ground White Pepper
  • 1 tsp – Ground Black Pepper
  • 1 tbsp – Sea Salt

In large crockpot mix the following and set on high heat and stir occasionally.

  • 17 – Fresh Roma Tomatoes pureed (stems removed)
  • 2 tbsp – Sea Salt
  • 2 tsp – Ground White Pepper
  • 2 tsp – Ground Black Pepper
  • 2 tsp – Jalepeno Tobasco Sauce
  • 2 tsp – El Tapatio Sauce
  • 2 tbsp – Fresh Minced Garlic
  • 4 tbsp – Dried Minced Onion
  • 2 tsp – Ground Oregano
  • 2 tsp – Ground Cumin
  • 1 tsp – Cajun Spices or Ground Cayenne Pepper
  • 1 tbsp – Ground Chili Powder
  • 1.5 tbsp – White Wine Vinegar

Once tomato mixture is seasoned and hot, add the browned ground beef from skillet and stir well. Turn crockpot down to low and let simmer 6 to 10 hours stirring occasionally. Adjust spices to taste before serving.

Makes 20-24 X 4 ounce servings (1/2 Cup)

Nutritional information:

Serving Size: 4 oz. (1/2 Cup)
Calories – 97
Cal from Fat – 24
Total Fat – 2.7g
Saturated Fat – 1g
Trans Fat – 0g
Cholesterol – 34g
Sodium – 181mg
Potassium – 0
Total Carb – 2.4g
Dietary Fiber – .5g
Sugars – 1.25g
Protein – 14.25g
Vitamin A – 6.25%
Vitamin C – 15.1%
Iron – 9.6%

Enjoy!! Please comment with variations and opinions!

List of Beers & Ciders that I enjoy

The older I get, the more I find myself trying new things; especially different beers and ciders from right here in the United States and around the world. It occurs to me that I should probably keep a list of those I like, then maybe write something up about each of them. So….here is the list so far (though it is limited at this time). If you have some suggestions on those that I need to try, please feel free to suggest them in the comments.

That’s all I have the time for today. As I get time, I will add to the list. Eventually, I will begin to write a little about them each to document what I like about them.


Windows 10: In-place upgrade w/ PGP Desktop Encryption

Overview/ Intro

Recently, I’ve had a few customers who use full disk encryption from Symantec (Symantec PGP, Symantec Endpoint Encryption, or Symantec Desktop Encryption) on client computers instead of Microsoft BitLocker. “Why?”… well… it’s most likely that they have a really good Symantec sales rep. Either that or they implemented prior to BitLocker being ready for prime time and never bothered to change the solution. And yes, I prefer the Microsoft solution for its ease of management and integration points.

The most recent customer was running Windows 7 with Symantec Desktop Encryption (complete with the server component for management) for full disk encryption. Their goal was to upgrade all Windows 7 clients to Windows 10 (Current Branch) without decrypting the volume, if possible. They also use SCCM for endpoint management, software deployment and OSD. Our solution needs to leverage SCCM and an In-Place Upgrade Task Sequence.

To achieve the goal, we have some options available to us (there may be more than I’ve listed here, but you get it):

  1. Nuke and Pave (treat it like bare metal or replacement scenario)
    • Capture user files and data to a network location (USMT)
    • Delete all partitions on the physical disk
    • Install/ Apply Operating System
    • Install applications
    • Install drivers
    • Restore user files and data from network location (USMT)
  2. Include the encryption drivers by modifying the setup command-line
    • Leverage the “/ReflectDrivers” command-line option
  3. Suspend disk encryption
    • Suspend Bitlocker (if used)
  4. Decrypt the drive
  5. Use vendor supplied upgrade scripts
  6. Use a varying combinations of the above options

Ultimately, we chose option 6 (a combination of options 2 and 5). This was because of the following:

  • “Nuke and Pave” might take additional dev time to determine “What is user data?” for USMT to be right.
  • Symantec Encryption Server didn’t have an option to suspend encryption.
  • Decryption takes waaayyyy too long, and isn’t a valid option with the requirements given by the customer.


Based upon the customer requirements and the options chosen, we will need the following items to build our solution:

  • A healthy and functional Configuration Manager Hierarchy
  • In-Place Upgrade Task Sequence
  • Vendor supplied upgrade scripts from Symantec
    • A google search for the correct scripts for your version of PGP is needed. Simply find the version(s) you need and download the appropriate zip file(s).
    • SUGGESTED GOOGLE SEARCH TEXT: “Win10 In-Place upgrade PGP <version> “
      • <version> = the version of PGP you are using.
      • Ours was 10.4.1 located here
      • The specific zip file for version 10.4.1 is here
  • A few guinea pigs (Windows 7 machines with disk encrypted). Three (3) or Four (4) should do it.


Review the Upgrade Script(s) from Symantec

  1. Unzip the files in the package, then open the “Readme.txt” file.
  2. Look for the “Usage:” line in the readme file. It should have something like “WinRS3-upgrade-SED1041.cmd “
    • “WinRS3-upgrade-SED1041.cmd” would be the name of the upgrade script to examine (CMD file).
  3. Open the CMD file in notepad.
  4. Note the actions being performed; these will be the actions we perform using PowerShell.
    • For PGP 10.4.1 (our version), the CMD file does the following:
      1. Create a temp folder at “C:\PGPTemp”
      2. Stop running PGP processes
      3. Copy PGP Drivers from “C:\Windows\System32\Drivers” to “C:\PGPTemp” if present
      4. Copy support files from script folder to “C:\PGPTemp”
      5. Sets the upgrade command-line options “/ReflectDrivers” and “/PostOOBE”
      6. Initiate the upgrade to Windows 10

Mimic the script actions with PowerShell

Now that we know the steps (from Symantec) to perform our upgrade on an encrypted system, we can create our PowerShell script. Please note that these steps are not in the exact same order as the CMD file from Symantec; the end result is the same though.

  • We’ll start our script with a line to reference the location (path) of the current running script that will help us later on when we add it to the Task Sequence.
  • Then, we’ll stop any running PGP related processes with this bit of code..
  • We need to create the “C:\PGPTemp” folder and copy the encryption drivers next, but only if the drivers exist in the first place. Here’s how we do that…
  • Now we need to copy the support files from the script folder. We’ll add some code to our script to perform that action.
  • Since SCCM uses the “setupcompletetemplate.cmd” (located in ‘C:\Windows\CCM‘)as a template to create the “%WINDIR%\Setup\Scripts\SetupComplete.cmd” file, we will need to add the content from the PGP version of “setupcomplete.cmd” to our template. Yup… more PowerShell…
  • Since our SCCM Upgrade task sequence will set the “/PostOOBE” setup option for us, we only need to set the “/ReflectDrivers” option as our last step of the script… like this.

Here is the whole thing cleaned up as a single PowerShell script. Copy the code below and save it as “Set-PGPUpgradeDrivers.ps1


  • Set up bypass of Symantec BootGuard
    • Enable bypass for up to 4 reboots. Information on how to do this is located here.
  • Create a package in SCCM called “OSD-SetPGPUpgradeDrivers”
  • Add the step to your task sequence

Later on as time allows, I’ll try to add more information to this post about:

  • Accommodating other PGP versions
  • Adding support for upgrading from other Windows Client Operating Systems
    • Window 8, and 8.1
    • Windows 10

UPDATED: Windows Server 2012 – WSUS Post-Install Tasks Fail Immediately

UPDATE:  The Original post was done on May 1, 2014. I’ve added script code at the bottom of the post to accommodate issues that may be encountered with WID conflicts in Server 2012/ 2012R2. The PS Script code also works with Server 2016.

Not long ago, I was trying to re-install WSUS on a server that would not generate the ‘WSUS Administration’ website.

Post-installation tasks would also fail without giving me much to go on. After some time researching, I found several posts on message boards that all said to do different things to resolve the issue. Some of them even said to either reload the OS on the server (not always an option in a production environment), or call Microsoft for help (which as we all know costs $$$).

Here’s what I found…

In the installation log located in the %temp% folder there should be a log file with the .TMP file extension. (EXAMPLE: tmp56B7.tmp)

When looking at this file, it told me that a file it was looking for was not found, or corrupt.

When I ran the WSUS Console I saw the following:


The WSUS administration console has encountered an unexpected error. This may be a transient error; try restarting the administration console. If this error persists,

Try removing the persisted preferences for the console by deleting the wsus file under %appdata%\Microsoft\MMC\.

The WSUS administration console has encountered an unexpected error. This may be a transient error; try restarting the administration console. If this error persists,

Try removing the persisted preferences for the console by deleting the wsus file under %appdata%\Microsoft\MMC\.

System.NullReferenceException — Object reference not set to an instance of an object.



Stack Trace:

at Microsoft.UpdateServices.UI.AdminApiAccess.AdminApiTools.GetLocalInstallDir()

at Microsoft.UpdateServices.UI.AdminApiAccess.Constants..cctor()

** this exception was nested inside of the following exception **

System.TypeInitializationException — The type initializer for ‘Microsoft.UpdateServices.UI.AdminApiAccess.Constants’ threw an exception.



Stack Trace:

at Microsoft.UpdateServices.UI.SnapIn.Scope.RootScopeNode.GetComputerTargetFromCmdLine()

at Microsoft.UpdateServices.UI.SnapIn.Scope.RootScopeNode.AddServerScopeNodeFromCmdLine()

at Microsoft.UpdateServices.UI.SnapIn.Common.SnapInManager.OnLoadCustomData(AsyncStatus status, Byte[] persistenceData)


To resolve the issue, I performed the following steps (in order):

1) Open a PowerShell session as Administrator and uninstall WSUS completely with the following command:

Remove-WindowsFeature –Name UpdateServices,UpdateServices-DB,UpdateServices-RSAT,UpdateServices-API,UpdateServices-UI –IncludeManagementTools

2) Delete the registry key HKLM\SOFTWARE\Microsoft\Update Services

3) Delete the WSUS file from %appdata%\Microsoft\MMC

4) Delete the Folder %ProgramFiles%\Update Services along with all of its subfolders and files.

5) Reboot the server

6) Run the System File Checker to find and repair any inconsistencies by typing the command below into the PowerShell prompt.

SFC /scannow

7) Reboot the server

8) Verify IIS is installed and working without errors

9) Open a Powershell session as Administrator an install WSUS with the following command:

To use a SQL DB:

Install-WindowsFeature –Name UpdateServices,UpdateServices-DB -IncludeManagementTools

To use WID:

Install-WindowsFeature –Name UpdateServices –IncludeManagementTools

10) Once WSUS installation has completed, change the current working directory to %programfiles%\Update Services\Tools and run one of the following post-installation commands:

To use a SQL DB:

.\wsusutil.exe postinstall SQL_INSTANCE_NAME=”SERVER\Instance” CONTENT_DIR=”:\WSUS”

To use WID:

.\wsusutil.exe postinstall CONTENT_DIR=”:\WSUS”

11) Wait for the command to complete successfully.

12) If you are using this WSUS instance as part of a farm, then open the Admin Console and configure your updates.

13) If you are using this instance as part of the roles within an SCCM Implementation, open the SCCM Console and install the Software Update point role.

Here is my PowerShell Script code to perform the WSUS Installation and Post-Installation tasks. Copy the code and save it as a .PS1 script file and run it on the intended Server.

For use with SQL Server:


For use with Windows Internal Database:

Configure WSUS as needed and happy patching!

SCCM 2012 R2 – OS Deployment with PKI (HTTPS)

More and more organizations are implementing Configuration Manager with PKI (HTTPS) enabled. Recently, I worked with a customer who planned to do just that.

Initially we set up the site without any certificates installed because the PKI Implementation within the domain was not yet completed. Once it was complete, we changed the site and client communication to be HTTPS only. This presented us with issues in regard to Operating System Deployment.

Once the mode was changed, none of our boot disks or Task Sequences would work. After we finished scratching our head, reading blogs, and flipping through TechNet doc and articles we were able to get it working again.

Here are the steps that we went through to get OSD back up and running again…assuming that your site is already in HTTPS and you have a healthy/ functional PKI environment.

  1. Create a ConfigMgr Workgroup Client Certificate.
  2. Request the ConfigMgr Workgroup Client Certificate from the Certificate Authority.
  3. Export the ConfigMgr Workgroup Client Certificate.
  4. Modify the MDT Toolkit Package so that our new certificate is available when building the image and deploying it.
    • Alternatively you could create a new package that contains the exported certificate and the answer file created in step 5 below.
  5. Create a new answer file for our OS Installation Package used in our Build task sequence.
  6. Create a package for the new answer file.
  7. Modified our Build task sequence to include the answer file and tell the ConfigMgr Client Package to install for PKI.
  8. Recreate our Boot disk ISO to include the exported certificate.
  9. Build and Capture our new OS Image.

Create the ConfigMgr Workgroup Client Certificate

These are modified steps from TechNet for “Creating and Issuing the Workstation Authentication Certificate Template on the Certification Authority

  1. On the member server that is running the Certification Authority console, right-click Certificate Templates, and then click Manage to load the Certificate Templates management console.
  2. In the results pane, right-click the entry that displays Workstation Authentication in the column Template Display Name, and then click Duplicate Template.
  3. In the Duplicate Template dialog box, ensure that Windows 2003 Server, Enterprise Edition is selected, and then click OK.
  4. In the Properties of New Template dialog box, on the General tab, enter a template name that will be used, such as ConfigMgr Workgroup Client Certificate.
  5. Click the Request Handling tab, ensure that “Allow private key to be exported” is checked.
  6. Click the Subject Name tab, select “Supply in the request” at the top.
  7. Click OK and close Certificate Templates Console.
  8. In the Certification Authority console, right-click Certificate Templates, click New, and then click Certificate Template to Issue.
  9. In the Enable Certificate Templates dialog box, select the new template that you have just created, ConfigMgr Workgroup Client Certificate, and then click OK.
  10. Close Certification Authority.

Request the ConfigMgr Workgroup Client Certificate from the Certificate Authority

These steps can be performed from any domain joined system including the Certificate Authority.

  1. Launch Microsoft Management Console (MMC) by opening a run dialog, type MMC then click OK.
  2. Click FILE -> ADD/REMOVE SNAP-IN to open the “Add or Remove Snap-ins” dialog.
  3. Choose “Certificates” from the list of available snap-ins, then click the button labeled “Add >”.
  4. When prompted, select “Computer Account” and click Next.
  5. Select “Local Computer: (the computer this console is running on)”, then click Finish.
  6. Click OK to close the “Add or Remove Snap-ins” dialog.
  7. Expand “Certificates (Local Computer)” -> Personal, and click on “Certificates”
  8. Right-click on “Certificates” and choose All Tasks -> Request New Certificate from the menu.
  9. In the Certificate Enrollment wizard that opens, click Next.
  10. Select Active Directory Enrollment Policy, then click Next.
  11. Check the box for ConfigMgr Workgroup Client Certificate that was created earlier, then click the link below it that says “More information is required…”
  12. Under Subject name, choose Common name as the type and enter Workgroup PKI as the value, then click the button labeled “Add >” and click OK.
  13. Click Enroll. If done correctly, you should see a “STATUS: Succeeded” in the results dialog.
  14. Click Finish

Export the ConfigMgr Workgroup Client Certificate

  1. The “Workgroup PKI” certificate should now show in the certificate console under Personal -> Certificates.
  2. Right-click on the “Workgroup PKI” certificate and choose “All Tasks” -> “Export…” from the menu.
  3. In the Certificate Export Wizard, click Next on the welcome screen.
  4. Select “Yes, export the private key”, then click Next.
  5. Select Personal Information Exchange – PCKS #12 (.PFX), and ensure that “Include all certificates in the certification path if possible” AND “Export all extended properties” are checked, then click Next.
  6. Type in a password and confirm it in the boxes provided on the Password screen, then click Next. (Save this password for later use)
  7. Browse for a location to export the certificate to. Make sure that it is somewhere accessible from SCCM, give it a name (ex. – WorkgroupPKI.pfx) and click Save.
  8. Click Next on the File to Export dialog.
  9. Click Finish on the completion dialog.

Modify the MDT Toolkit Package

  1. Open windows explorer and locate the certificate file that you just exported.
  2. Copy the file to the Scripts folder within your MDT Toolkit Package.
  3. Open the Configuration Manager Console and locate the MDT Toolkit Package.
  4. Update the Distribution Point(s) for the package.

Create Answer File

  1. Open the Windows System Image Manager on a computer that has the Windows Automated Installation Kit (WAIK) installed.
  2. Create a new answer file by clicking the icon in the upper left corner , clicking “FILE” -> “New Answer File…”, or by pressing CTRL+N on the keyboard.
  3. Under “Windows Image”, right-click on “Select a Windows Image or Catalog File” and choose Select Windows Image.
  4. Browse to your Operating System Installation Media, and choose the catalog file (.clg) for the desired OS you are trying to deploy, then click “Open”. The CLG file is usually located on the installation media in the Sources directory. (EX – for Windows 7 Enterprise the file name is “install_Windows 7 ENTERPRISE.clg”)
  5. Expand Components.
  6. Locate the appropriate Microsoft-Windows-Deployment-<version>-neutral component for the desired architecture. (for Windows 7 Enterprise 64bit, the component is – amd64_Microsoft-Windows-Deployment_6.1.7600.16385_neutral)
  7. Expand Microsoft-Windows-Deployment -> RunSynchronous.
  8. Right-click on RunSynchronousCommand and choose “Add Setting to Pass 4 specialize”
  9. In the Answer File section, click on “RunSynchronousCommand” to highlight it.
  10. For the properties of “RunSynchronousCommand”, enter the following:
    • Description: Import Workgroup Certificate
    • Order: 5
    • Path: cmd.exe /c certutil –f –p <password> -importpfx <drive>:\_SMSTaskSequence\Packages\<PackageID>\Scripts\<nameofcertificate>.pfx
      • <password> = The password set on the certificate when it was exported.
      • <drive> = The system drive where the Operating System will be installed. This is usually drive C.
      • <nameofcertificate> = The name of the certificate file that was exported earlier.
  11. Richt-click “Credentials” below “RunSynchronousCommand” and choose delete.
  12. Click File -> Save Answer File As, then browse to a location easily accessible by the Configuration Manager Server.
  13. Name the answer file “Unattend.xml” and then click Save.

Create Answer File Package

  1. Open the Configuration Manager Console and navigate to Software Library -> Application Management -> Packages.
  2. Create a new Package called “OSD – Windows 7 Enterprise 64bit Answer File”
  3. Check the box for “This package contains source files”.
  4. Browse to the location where the new answer file was saved. (Ensure that you use the UNC path and not a local volume path when creating packages in Configuration Manager)
  5. Click next
  6. For Program Type, select “Do not create a program”, then click next.
  7. Click next on the Summary screen, then click close on the Completion screen.
  8. Right-click on the package you’ve just created and distribute the content.

Modify the Task Sequence

  1. Open the Configuration Manager Console and navigate to Software Library -> Operating Systems -> Task Sequences.
  2. Select the task sequence used for Build and Capture of your operating system image.
  3. Right-click on the task sequence and choose Edit.
  4. Select the step called Partition Disk 0
  5. Add a Use Toolkit Package step by clicking Add -> MDT -> Use Toolkit Package
  6. Browse for and choose your MDT Toolkit package from the available packages.
  7. Select the step called Apply Operating System
  8. Ensure that the box is checked for “Use an unattended or Sysprep answer file for a custom installation”
  9. Browse for the answer file package we just created.
  10. For the File Name, enter the name given to the answer file created earlier. (unattend.xml)
  11. Click on the Apply Device Drivers step, then click Add -> MDT -> Use Toolkit Package
  12. Browse for and choose your MDT Toolkit package from the available packages.
  13. Click on the step called Setup Windows and Configuration Manager
  14. In the area provided for “Installation Properties”, enter the following:
      • <FQDN> = Fully Qualified Domain Name of your Configuration Manager Management Point Server
      • <DOMAIN> = Name of the domain where the SCCM Management Point Server resides. (EX – ADVENTURESINSYSCTR.NET)
  15. Click Apply to save the changes to the Task Sequence.
  16. Click OK to close the Task Sequence.

Recreate Boot ISO

  1. Open the Configuration Manager Console and navigate to Software Library -> Operating Systems -> Task Sequences.
  2. Right-Click on Task Sequences and choose “Create Task Sequence Media” from the menu.
  3. Select “Bootable Media” as the media type and then click next.
  4. On the next screen, choose the option that works best within your environment. For this example, I chose Dynamic Media.
  5. The next screen is the media type screen. If you have access to the local USB ports where you are running the wizard from, you can choose USB Flash Drive. I personally like to use CD/DVD Set, this gives me the option of using the ISO that is created to make several USB boot drives if I need to.
    • For this blog post, I’ve chosen CD/DVD Set. Once selected, browse for a location to place the ISO (CD Image) file to be created, give it a name with the .iso extension and click next.
  6. On the Security Settings screen, set a password if you wish, or you can uncheck the box for “Protect media with a password”.
  7. Ensure that Import PKI Certificate is selected, then browse to the location where the “Workgroup PKI” certificate was exported.
  8. Select the certificate, then type in the password in the space provided and click next.
    • If you’ve already used the certificate on another boot disk, you will get a prompt telling you that the certificate is already in use. Click yes to use the certificate again, or you can go back and request a new one from the CA and export it again.
  9. On the next screen, choose your boot image to use, the distribution point and the desired management point. Then click next.
  10. Do not enter any customizations at this time. If you wish, you can create another boot disk and customize that one. Simply click next here.
  11. Click next on the summary screen to begin creation of the USB or ISO image.
  12. Once completed, you will have a boot disk to use for build and capture (and deployment) of your image. Click Close on the completion screen.

Build and Capture the Image

Using a Virtual Machine, mount the ISO image that we just created and boot from it. If you’ve deployed the Build and Capture task sequence to the “All Unknown Computers” collection, you should have the task sequence available.

Use PowerShell to Create SCCM 2012 Site Boundaries

I needed a script to create IPRange Boundaries within SCCM 2012. One of my coworkers suggested that I use a PowerShell CMDLet  to get this done for me.

So I opened the CM2012 console and ran the PowerShell Session from the menu in the upper left corner. Then I ran ‘get-help boundary’ to see what was available.

One of the Cmdlets returned was ‘new-cmboundary’. The script reads each line of a csv file in and parses it for the needed information to construct the Boundaries.

Here is the script I came up with.

To run this script you will need to do three things.

  • Run the SCCM 2012 Console as administrator
  • Open the PowerShell session from the menu in the upper left corner of the SCCM Console.
  • Run this command: Set-ExecutionPolicy -ExecutionPolicy Unrestricted -Scope Process

CSV File format:

Hyper-V Lab IPRANGE,IPRange,

CreateBoundaries.ps1 <pathtofile>.csv

This script can actually be used to create all of the boundary types in CM2012. To do so, you would need to change the Boundary type and respective value in your CSV file.

Available boundary types are:

  • IPSubnet (Example corresponding value: “”)
  • ADSite (Example corresponding value: “Default-First-Site-Name”)
  • IPv6Prefix (Example corresponding value: “FE80::/64”)
  • IPRange (Example Corresponding value: “”)

For more information about the commands used in the script, open PowerShell from within the SCCM console and type the following commands:

  • Get-Help Import-CSV
  • Get-Help New-CMBoundary