New Sample for MDT (Custom Actions)

MDTLTIPSSampleAction

MDT Litetouch Action Property Page Sample

Fancy Example

Background

MDT has several pre-defined pages for common task sequence editing tasks. You’ve seen them in the MDT Litetouch Task Sequence Editor, under General, Disks, Images, Settings, and Roles.

They help abstract the ugly command line and scripting code behind the scenes for the user.

Recently I had an idea for a super-wiz-bang property page type for MDT Litetouch, and asked “are there any MDT LTI samples out there?”. I knew Config Mgr had a SDK Sample and I’ve been using it for a while now to create SCCM Task Sequence Actions pages.

The answer came back “There was an MDT Litetouch SDK, but not anymore.” (Long story for another day)

“Someone should create a sample!” I said!

“Cool Keith, when you figure it out, can you share the results? :)” For those of you who wonder, how does one become a Microsoft MVP? This, so here we go.

The Basics

C#

MDT Task Sequence Action Pages are simply C# Windows Form Control Library, with some standard API interfaces so it can be called from the Litetouch Wizard Host. The MDT team designed the API to closely resemble the System Center Configuration Manager Action Page API.

  • There are entry points for when the control is initialized.
    • Use this opportunity to load the UI elements with the saved data from the PropertyManager (aka TS.xml)
  • There are entry points for when the “OK” and “Apply” buttons are pressed.
    • Use this opportunity to save the UI elements with to the PropertyManager

There are several dependent classes required by the sample, they are contained in the ‘c:\program files\Microsoft Deployment Toolkit\bin\Microsoft.BDD.Workbench.dll’ assembly, so you will need add this reference to your project.

Anything else you want to add in the control, can be done if you know the correct C# code to get the job done.

Registration

Once you have created the DLL Library, we will need to add it so MDT Litetouch console knows about it.

First off, copy the DLL to the ‘c:\program files\Microsoft Deployment Toolkit\bin’ folder.

Secondly, we’ll need to add an element to the actions.xml file.

<action>
	<Category>General</Category>
	<Name>Install PowerShellGet Action</Name>
	<Type>BDD_MDTLTIPSSampleControl</Type>
	<Assembly>MDTLTIPSSampleAction</Assembly>
	<Class>MDTLTIPSSampleAction.MDTLTIPSSampleControl</Class>
	<Action>powershell.exe -Command  Install-Package -Force -ForceBootStrap -Name (New-Object -COMObject Microsoft.SMS.TSEnvironment).Value('Package')</Action>
	<Property type="string" name="Package" />
</action>

For this sample, I included a PowerShell libary module with two functions, one to register the new control, the other to remove the control. Easy!

The Sample

The sample in this case is pretty small.

There is one TextBox (as shown above), that prompts the user for the name of a PowerShell Package.

The package name get’s added to the TS.XML, along with the command, in this case it calls PowerShell.exe with the cmdlet Install-Package. We use COM to connect to the SMS environment space to get the package name and go.

You can use the build.ps1 script to compile the sample, and create PowerShell library to install the control within MDT Litetouch.

Future

Well I created this sample, because I have some ideas for some MDT LiteTouch (and SCCM) Action controls.

  • Fancy UI for installation of applications through Chocolatey
  • Run scripts and modules from PowerShellGallery.com
  • Other ideas, let me know (comments or e-mail)

Keith

New Tool: Get the Latest Windows 10 Cumulative Updates!

TL;DR – Programmatically get the latest Windows 10 Cumulative Updates!

Got a request from someone on an internal e-mail Distribution list recently, asking how to find out the latest Windows 10 (or Windows Server 2016) Cumulative Update.

Normally you can find these updates by going to this Microsoft KB article, then finding the right Operating System Version. Then you use the KB article number to go to Windows Update, and find the correct download link, then download the file.

I wanted to update this for another project, so I took it as a challenge to code in PowerShell.

New Tool

For this tool, I placed the source code up on GitHub.com, in a new gist. A gist is just a file that can be edited, version controlled, and shared out publicly on the GitHub.com site.

Given a Windows Version (build number), and a couple other search strings, will programmatically determine what the correct download links are for this Windows 10 (or Windows Server 2016).Â

The output can also be piped into BITS so you can just download locally.

Example

Get the links for the latest Windows 10 Version 1703 Updates:

getupdates1.PNG

 

Additionally we can also download the files using the BITS command Start-BITSTransfer

downloadupates1.PNG

 

Source

 

 

 

Decrypting the HP BIOSConfigUtility64.exe password

First off, for those of you who asked, I did leave 1E last week, off to try new things. Thought I’d take some time off during May, and then look for new opportunities. The future is wide open :^)

In the mean time, I did come across this post today about decrypting passwords with the BIOSConfigUtility64.exe utility.

https://www.serializing.me/2016/10/15/hpqpswd-encrypted-passwords-decryption/

And reminded me of some work I did recently at 1E on their BIOS 2 UEFI toolset. The HP tool did set off some red flags for me, the tool was able to take a plaintext password and put the encrypted value in a *.bin file without asking for an encryption key!?!? How did it do that? I figured it was because the tool stored the encryption key for the password within the executable itself. That’s not optimal (it’s unsecure), but not uncommon.

So I spent some time trying to reverse engineer the process, “link -dump /imports” revealed several cryptographic calls like CryptImportKey(), and with some time using trusty WinDBG.exe, I was able to locate the key. I wondered if HP would try to hide the key, but it was there in plain sight. I wrote a test program, but in my case I didn’t write a tool to decrypt the password, I wrote a tool to perform the encryption.  My thoughts were to provide a centralized password storage mechanism for HP, Dell and Lenovo, and I wondered if the HP toolset was a good starting point. 1E didn’t go down that route but the reverse engineering the HP tool was interesting.

It does bring up an interesting ethical dilemma for Engineers like myself. Something that you see on the news whenever someone discovers a new vulnerability in an OS, or Web Browser: Do you keep the vulnerability secret, or do you tell the public, knowing that some Black Hat could use the vulnerability to write an exploit and expose sensitive data?  In my case, I decided not to reveal the exploit, but Duarte chose to reveal it. Who is right?

I guess the only thing I can say is this is a good learning opportunity to discuss security/encryption of secrets like passwords. If you are an IT administrator, be weary of tools that can encrypt data magically without an encryption key, it’s not magic, they are encrypting the data with *something* and it’s possible the key is stored locally in an unsecure fashion. Better to store the passwords in a more secure location, with a more secure encryption, and then convert to the HP Password at the “Last-Minute” when preforming the actual task sequence.

This is a similar problem with other tools that “appear” to encrypt data, but store the data in a manner that *can* be easily extracted. Like the AdministratorPassword field in the unattend.xml file, and the Password in the SysInternals AutoLogon.exe tool. Both tools store passwords in an easily recoverable fashion. I’ve seen too many administrators fall for the illusion that these are secure, they are not.

-k

Hope to see many of you at MMS MOA in May 2017!!! I’ll be there.

Supermicro vs No_Drv

TL;DR – A NO_DRV driver is a driver package that doesn’t contain a driver binary. It uses the driver from another package (typically an in-box Microsoft driver).

Server Woes

One of my servers, a SuperMicro 5038A-IL has been locking up on me. I’ve been able to use the machine for the most part for the past year, but the upshot is that I can’t upgrade the machine from one Windows version to another. 22% of the way through WinRE (or sometimes WinPE), the machine has a hard Freeze, and won’t respond to mouse movement or keyboard. I’ve tried kernel debugging, hardware swaps, nothing works. My experience tells me this is a hardware problem. Time to escalate to SuperMicro support.

Upgrade your drivers

OK I should have seen this one coming, I call up support, and the first thing they ask me to do is make sure I have the latest Network and System Drivers.

  1. WinRE doesn’t use Network, so this isn’t a problem.
  2. System Drivers sure! Let’s download and check to see I have the latest stuff.

ftp://ftp.supermicro.com/driver/Intel_INF/Skylake_Series_Chipset/Chipset_v10.1.2.80.zip

No_Drv

I open the driver package, and take a look. Wait a minute, I don’t see any *.sys files, only *.inf and *.cat files.

sys – These are the compiled drivers, usually written in c/c++.
inf – These are the install files, typically there is at least one of these.
cat – This is the digial signature, signed by Microsoft to verify the source of the driver.

How can there be no driver in the driver package? Let’s look

[Version]
...
CatalogFile=Skylake.cat
...
[INTEL.NTamd64]
...
%PCI\VEN_8086&DEV_191FDesc%=Needs_NO_DRV,PCI\VEN_8086&DEV_191F

[Needs_NO_DRV]
Include=machine.inf
Needs=NO_DRV
Oh, NO_DRV, now I recall, this is an old trick. The device above DEV_191F doesn’t actually require a device driver, it’s transparently handled by Windows. But Windows doesn’t give it a descriptive name, just a generic name. So companies like Intel can provide this pack so you can give some devices more descriptive names in the Device Manager. The intel driver above points to an entry in the machine.inf driver already on the machine.
From:   “PCI Standard ISA bridge”
To:   “Intel(R) C226 Series Server Advanced SKU LPC Controller – 8C56”
That’s all it does, It doesn’t affect the operation of the OS or the hardware. Just the name! Sometimes this is helpful if you need to quickly identify a device, but, yes it’s mostly used for vanity, so I never load them on my machines.
So… I responded to SuperMicro, and confirmed I was using the latest drivers from intel. :^)

 

Hackers vs PowerShell!

OK, I have a couple of servers in my home lab. I suppose it has a lot to do with the fact that I work with ConfigMgr and other server tools.

Additionally, I like using Remote Desktop to connect and manage my machines, I suppose it has something to do with the fact that I once work as a Developer on the Terminal Services Client Team.

And yes, I have a couple of ports open to the Internet. <I am now reconsidering this :^(  >

Hack

Anyways, I was looking today at the performance on one of my machines, and noticed one of the remote desktop server processes was being accesses by someone in Germany. Germany?!!? What???

german.JPG

Something running on FastWebServer.de and Your-Server.de.

The network traffic was slow, not as fast as my active Remote Desktop session. What could it be? After some thought, I figured it could be someone attempting to log in using different credentials. Perhaps using a bot to try various credentials. Um… OK

PowerShell

PowerShell to the rescue.

I used the get-eventlog cmdlet to search for the right log (Security) and event entry (4625).

get-eventlog -log Security -InstanceId 4625 | Measure-Object

981 entries!! Youza!

Further analysis shows that entry #6 of the ReplacementStrings property shows the account that was used to logon. A frequency analysis should be in order:

PS E:\> get-eventlog Security -InstanceId 4625 | 
   %{$_.ReplacementStrings[5]} | group | 
   sort Count -Descending | select -first 10 Count,Name

Count Name
----- ----
  152 ADMINISTRATOR
  150 SUPPORT
  150 TEST
  150 ADMIN
  150 DEMO
  150 ROOT
    7 EDDIE
    7 SQLADMIN
    7 CAFE
    7 BILL

The names appear to be random, nothing specific to me, needless to say I have disabled the local administrator account, and begun other security measures.

But I thought the powershell was fun! :).

 

Formatting a removable USB drive with 2 partitions

TL;DR – Starting with Windows 10 Insider Preview Build 14965, you can format any “Removable” USB Flash Drive with more than one partition. Perfect for installation of large (over 4GB) WIM files on UEFI machines!

 

Hey all, back from a week at the Microsoft MVP summit, a Week in the UK, and a week in Arizona.

A few weeks ago at the Microsoft MVP summit, an engineering manager with the Windows Product group made an offhand comment about formatting a removable USB drive with two partitions. This took several of us by surprise, because historically, this hasn’t been supported widely without converting to a Fixed disk or something.

Mike Terrill (and Mike Niehaus) already beat me to the punch with some posts, but I wanted to share my results. :^)

The Background

Why is this important? Well as I mentioned in another blog post, as more and more people are booting to UEFI, on USB flash drives formatted with Fat32, with WIM images over 4GB in size, that causes a problem because Fat32 can’t hold files over 4GB in size.

Another solution would be to use the Rufus tool to split a USB drive into multiple partitions with a hidden fat32 partition. However, the problem here is that the hidden partition uses a special UEFI app that is not signed, so it won’t work on UEFI machines with Secure Boot enabled.

This has become even more interesting since Windows Server 2016 came out, with a base WIM image for standard Server SKU that is over 4GB in size. Hum…

The Hardware

20161126_200856.jpg

I tested on several different USB makes using my Windows 10 (version 1607) laptop. Some would allow me to create a 2nd partition on a removable Flash Drive, others would not giving me an error:

DISKPART> create part pri

No usable free extent could be found. It may be that there is insufficient 
free space to create a partition at the specified size and offset. Specify
different size and offset values or don't specify either to create the maximum 
sized partition. It may be that the disk is partitioned using the MBR disk
partitioning format and the disk contains either 4 primary partitions, (no
more partitions may be created), or 3 primary partitions and one extended
partition, (only logical drives may be created).

Mostly the older and/or cheaper drives didn’t work, but most of the newer and/or name brand drives did work.

Finally I narrowed it down to two different models, both my favorites:

Then I tested against three Operating Systems: Windows 10 Version 1607, Windows 10 Preview, and Windwos 7.0 SP1. All using Diskpart to create multiple partitions.

The script

Diskpart.exe –>

sel disk 1
clean
create part pri size=450
format quick fs=fat32
assign
create part pri
format quick fs=ntfs
assign
exit

The Results:

                                 SanDisk           Transcend
Windows 7 SP1 Build 7601           Pass               Fail
Windows 10  Version 1607           Pass               Fail
Windows 10 Preview 14965           Pass               Pass   

I was able to format my SanDisk into multiple partitions using Windows 7 and beyond.

But I was not able to format the Transcend drive into multiple partitions using Windows 7 or Windows 10 Version 1607, but I was able to partition into multiple partitions on the new Windows 10 Insider Preview 14965.

That’s new!

I haven’t done enough testing using the removable flash drives on older machines, to see if the partitions are still visible, but the results look promising for a start.

Update #1 – 11/28/16:

Found out today that the reason that my SanDisk Extreme disk worked on Windows 7 and Windows 10 1607 may be because the removable Flash disk is reported as “Fixed” rather than “Removable” to the OS. Link.

Update #2 – 11/28/16:

I noticed that when taking the “removable” disk formatted with 2 partitions from Windows 10 Preview 14965 over to Windows 10 Version 1607, only the first partition was visible. As a work around I tried moving the main NTFS partition first and the Fat32 partition second.

sel disk 1
clean
create part pri
shrink desired=450
format quick fs=ntfs
assign
create part pri
format quick fs=fat32
assign
exit

Field Notes – Dell Command PowerShell Provider

Working today with Mike Terrill on some advanced queries using the Dell Command – PowerShell Provider with Configuration Manager.

Dell Command – PowerShell Provider

Dell provides a PowerShell provider to query and manage various system level components on Dell machines. This is great if you are using PowerShell to process the output, and perform complex tasks, more complex than a simple static command line.

Configuration Manager Compliance Settings

My friend Mike Terrill called me up today and wanted to use Configuration Manager “Compliance and Setting Management” to push out a PowerShell script, with the Dell Command PowerShell Provider” to query the hardware state of a machine.

OK, cool. That’s when we came across some challenges.

We can add a PowerShell script, cool. But we need a test defined in Configuration Manager to determine if the test passed or failed.

Say our PowerShell script ran, with the following output.

Ready to run test[1]...
Test Result: Success

We could program ConfigMgr to see if the output “contains” the value “success”.

Except, in this case the script would fail because ALL lines in the output must contain the value “Success”. The first line didn’t contain the string “success”!?!? That’s what ConfigMgr is looking for. <sigh>

So we just need to make sure that *ALL* lines on the script are written by our script, and that we output *only* what’s necessary…

Dell and console output

Now the challenge is that the Dell Command – PowerShell provider is writing something extra to the console, and messing up our test in ConfigMgr. Recall that *all* lines in the output need to contain our test, the “To get more help…” command was messing with our tests.

capture

I decided to dig a little deeper and see if the output could be disabled or redirected ( say redirect in powershell to out-null), but no! So I broke out my favorite C# decompile, but alas, no of all the crazy things, the code is writing to the C# Console, and no way to bypass.

capture-2

Work Arround

Eventually we came across a horrible, no good, low down, dirty work around. Here is an example of the script:

import-module DellBIOSProvider

$DidTestPass = <# Perform a query here!#>  
 
if ( $DidTestPass ) 
{
    write-host "To get more help about the Dell Command PowerShell provider"
}
else
{
    write-host "Machine did not pass this test. Output more info here!"
}

Yes, in this case we output the dell string “To get more help…”  Then we can set Configuration manager Compliance Settings to look for the value to contain “To get more help about the Dell Command PowerShell Provider”. Anything else in this case is an error and will be written to the log for analysis later.

Bugs

There are two bugs here:

  1. The Dell PowerShell provider should not be outputting the “to get more help” string, or at least provide a way to disable, via registry key or something.
  2. The Microsoft Configuration Manager Compliance Settings should be able to look for a substring within the *entire* output, rather than looking for a substring in every line.

Keith