Notes on Microsoft ADV170012 – TPM Madness.

Hidden within the latest Microsoft Security Advisory is a Whooper: ADV170012

The summary is that some of the Infineon TPM chip implementations have a bug. And appears that someone has produced a Proof of Concept exploit. Wow.

Microsoft and Infineon have arguably done the right thing here and have announced the issue, produced a Hotfix to help customers better identify the issue, and have developed tools to update the issue through firmware.

What’s not clear to me is just what the issue is, and what the hotfix does. Unfortunately, it may be a while before Microsoft releases more information, while they give companies a head start working on application of the hotfixes.

A link in the article above suggest that exploit is not easy:

A successful attack depends on conditions beyond the attacker’s control. That is, a successful attack cannot be accomplished at will, but requires the attacker to invest in some measurable amount of effort in preparation or execution against the vulnerable component before a successful attack can be expected.

Which leads me to believe that any exploit is hard, requiring a highly skilled attacker, not someone who is going to steal my laptop from the local Starbucks in the hopes of getting my Credit Card number, saved somewhere on the machine.

Stay tuned…


In the mean time, I decided to re-write the PowerShell script in the article above. The latest version works great when issuing commands remotely and collecting the data in a centralized location.

For example I could run the command:

icm { iwr '' | iex } -Cred $cred -Computer Pickett1,Pickett2,Pickett3,Pickett4 | ft *

And see the output:


Lucky for me I have Four machines that are affected with the Bad TPM Module.

  • One machine is my work machine (Version 6.41)
  • Two machines don’t have bad Infineon version numbers (Verison 3.19), but may need to be cleared anyways. Easy to do.
  • One machine has the bad Infineon version (Version 4.32), but the TPM Module is on a replacement Riser card, and I can purchase a new one for $50.

Now to figure out how to address this at work.



Don’t recall why I  named it Reimann, I think I saw that as a code word in an article somewhere, and it stuck. Is the name of the researcher who found the issue, or just an arbitrary code name?

Not sure why you need to know when the last Provision Time was on machines *without* the issue. Either the TPM chips works or not!?!?




ZTISelectBootDisk.wsf new with BusType

Several years ago I wrote a script to help select which disk to deploy Windows to during your MDT LiteTouch or ZeroTouch task sequence.

Well, based on a request from my latest client, I have created a similar script that support BusType.


My client is trying to install Windows Server 2016 on a Server with a SAN. When the machine boots to WinPE, one of the SAN drives appears *first* as Disk 0 (Zero). By default MDT Task Sequences will deploy to Disk Zero! My ZTISelectBootDisk.wsf already shows how to override. All we need to do is to find a way to tell MDT which disk to choose based on the correct WMI query.

Turns out it was harder than I thought.

What we wanted was the BusType that appears in the “Type” field when you type “Select Disk X” and then “detail disk” in Diskpart.exe.  When we ran “Detail Disk” in DIskpart.exe we could see the bus type: Fibre as compared to regular disks like SCSI or SAS.

The challenge was that the regular Win32_diskDrive WMI query wasn’t returning the BusType value, and we couldn’t figure out how to get that data through other queries.

I tried running some PowerShell queries like ‘Get-Disk’ and noticed that the output type was MSFT_Disk, from a weird WMI Namespace: root\microsoft\windows\storage. But adding that query to the script works! Yea!!!


What kind of BusTypes are there?

Name Value Meaning
Unknown 0 The bus type is unknown.
1394 4 IEEE 1394
Fibre Channel 6 Fibre Channel
SAS 10 Serial Attached SCSI (SAS)
SATA 11 Serial ATA (SATA)
SD 12 Secure Digital (SD)
MMC 13 Multimedia Card (MMC)
Virtual 14 This value is reserved for system use.
File Backed Virtual  15 File-Backed Virtual
Storage Spaces  16 Storage spaces
NVMe 17 NVMe

For this script we are *excluding* the following devices:

Name Value Meaning
Fibre Channel 6 Fibre Channel
Storage Spaces  16 Storage spaces
NVMe 17 NVMe

Meaning that the *FIRST* fixed device not in this list will become the new *Target* OS Disk. Run this query on your machine to see what disk will become the target:

gwmi -namespace root\microsoft\windows\storage -query 'select Number,Size,BusType,Model from MSFT_Disk where BusType <> 6 and BusTy
pe <> 9 and BusType <> 16 and BusType <> 17' | Select -first 1


Reminder that this script requires MDT (latest), and the script should be placed in the %DeploymentShare%\Scripts folder. Additionally you should install all the Storage packages for WinPE, sorry I don’t recall *which* packages I selected when I did testing.





PowerShell Switch type never $null

Tales from the code review…

How do you test for a switch type in a PowerShell script?

How do you test for the *absence* of a switch in a PowerShell Script?

Came across this recently, and decided to dig into it further.


IN the example above, We have a function with a single switch argument. We then test against that argument, displaying “do something” if it’s set, and “Don’t do it” if not set.

Example Output:

PS C:\Users\Keith> C:\Users\Keith\Source\Example\test-switches.ps1
Don't do it
Don't do it
Do Something
Do Something

Cool!  Um… where did the “Never going to do it!” go? Well turns out that even when we don’t specify -test as an argument to the function, it’s still a switch defined as IsPresent = $false. So testing to see if it’s equal to $null will always fail, because it’s never $null.


Microsoft Groove RIP – Export your Playlist

OK… I’m using Groove. Don’t know why I paid the annual subscription, perhaps I had grand plans to sync up my music lists to a single platform and decided to give it a chance. Oh well… Microsoft just killed it.

Anyways, I’ve been collecting some songs over the past couple of years, and before I forget what they are, I thought I would export the list, only to find out that Groove only supports exporting to Spotify, well I don’t know what music service I’m planning on moving to, but it *might* not be Spotify, so I need to figure out how to export my list now.

I tried getting an Groove Music API, key, but Microsoft shutdown the service, I also tried another online service, but they wanted to charge a monthly fee. I did figure out that I can download my playlist locally to my machine. The files will be DRM protected, but I can use the file names to generate a playlist. How? Powershell to the rescue!

IF you would like to create a list, open up a powershell.exe command prompt and run the following command (Single line):

iwr | % Content | IEX | export-csv -NoTypeInformation -path $env:USERPROFILE\desktop\myGrooveList.csv

This command will download the powershell script from GitHub, execute, and export to a file called MyGrooveList.csv on your desktop. ( or replace desktop with downloads, whatever).


Then you can open the MyGrooveList.csv file in Excel and import later.

Here is the full script:

Download Ignite 2017 videos locally

Thanks to Michel de Rooij on TechNet gallery for posting this slick script where you can download TechNet content locally to your machine.

I wanted to select which videos to download, and wrote this powershell script to use out-gridview to download content. It calls the script above.


You can run the command directly from powershell, just cut and paste this command:

iwr | % Content | Iex 


  • Will download and cache the content locally so you can re-run the script repeatedly without having to wait to parse the website.
  • Will then display all the sessions in the PowerShell Out-GridView. Out-gridview is powerful.

  • Then will ask If you want to save the list to a *.html file for online viewing later.
  • Will also ask if you want to save the offline content to a local file.

The script:


Update CustomSettings.ini file remotely!

Got on a discussion this week with someone how to use PowerShell to update an MDT CustomSettings.ini file over the network. Well a *lot* of CS.ini files.. 🙂

My manager is the Global Ops Manager and now he is asking me to find a way to run [update of customsettings.ini] on about 50 servers worldwide so the other MDT admins don’t have to log onto each server just to add one line.

The example given was to update the AdminPassword in CS.ini. I hope this company is following best practices, and disabling the local Administrator account and/or changing the Password once joined to the domain or connected to SCCM.

Anywho, INI files are a tad bit difficult to modify in Powershell because there are no native PowerShell or .NET functions to perform the action. So instead we need to do some ugly Pinvoke calls to the appropriate Win32 API.


New script – Import Machine Objects from Hyper-V into ConfigMgr

Quick Post, been doing a lot of ConfigMgr OSD Deployments lately, with a lot of Hyper-V test hosts.

For my test hosts, I’ve been creating Machine Objects in ConfigMgr by manually entering them in one at a time (yuck). So I was wondering what the process is for entering in Machine Objects via PowerShell.

Additionally, I was curious how to inject variables into the Machine Object that could be used later on in the deployment Process, in this case a Role.

Up next, how to extract this information from VMWare <meh>.