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>.

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.

https://github.com/keithga/MDTLTIPSSampleAction

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

 

 

 

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! :).

 

Display WPF XAML code in PowerShell

Last week I went to the Minnesota Management Summit at the Mall of America #MMSMOA, and I got inspired to work on a few projects in my backlog.

One of the presentations I went to was with Ryan Ephgrave (@EphingPosh on Twitter.com), and his talk on “Better Know a PowerShell UI“.

Overall it was a great presentation, and I learned a lot. And got me thinking about some of the things I could do with a framework I started earlier in the year but never got around to finishing.

WPF4PS

Without further adieu, I present Windows Presentation Framework for PowerShell (WPF4PS). It is also the first project I’ve released as source code on GitHub:

https://github.com/keithga/WPF4PS

Background

Most WPF + PowerShell examples are created with a lot of custom code to add in event handlers for the User Interface elements. The goal is to find all control elements on the page and if there is a pre-defined function created, then use it. Which means minimal code for overhead.

Example

Here is a fully functional example:

  • Load the WPF4PS module
  • Import a XAML defined in Visual Studio
  • Create a scriptBlock to handle the button Click
  • Create a HashTable to pass data between our script that the XAML Window
  • Call the Show-XAMLWindow function
  • Get the value of the TextBox from the Hash

wpf4ps

<#
.SYNOPSIS
WPF4PS framework Examples

.DESCRIPTION
Simple Example

.NOTES
Copyright Keith Garner, All rights reserved.

#>

[cmdletbinding()]
param()

import-module $PSScriptRoot\wpf4ps -force

$MyXAML = @"
<Window x:Class="WpfApplication1.MainWindow"
 xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
 xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
 xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
 xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
 xmlns:local="clr-namespace:WpfApplication1"
 mc:Ignorable="d"
 Title="MainWindow" FontFamily="Segoe WP Semibold" Width="400" Height="300" Name="WindowMain" >
 <Grid>
 <Label>Hello World</Label>
 <Button x:Name="Button1" Content="Big Red Button" Width="125" Height="25" Background="#FFDD0000" Margin="0,60,0,0"/>
 <TextBox x:Name="textBox1" Height="23" Width="200" />
 </Grid>
</Window>
"@

$MyControl = [scriptBlock]{

    function global:button1_click()
    {
        "Click the Big Red Button`n" + $TextBox1.TExt  | show-MessageBox 
        $WindowMain.Close()
    }

}

$MyHash = [Hashtable]::Synchronized(@{ textBox1 = "Hello World" })

Show-XAMLWindow -XAML $MyXAML -ControlScripts $MyControl -SyncHash $MyHash

$MyHash.TextBox1 | Write-Host

Next

My goal is to work out the kinks and eventually upload/share this on PowerShellGallery.com.

For example:

  • I created two Show-XAMLWindow() functions in the library, one inline and another Async. I still don’t know what the usage case of Async is.
  • Ryan Ephgrave did some XAML + Powershell examples in his “Better Know a PowerShell UI” blog series with XAML “Binding” elements, something I have not used in the past, so I excluded them from this package.
  • I had to do some weirdness with the declaring the functions above as “global” to make them visible to the Module

If you have feedback on the layout or usage, please let me know.

-k

Fix for Windows 1511 ADK bug

First off, yes, I have a new job working for 1e! I’m super excited, and I should have posted something about it, but I’ve been super busy. My first day on the job was at a customer site in Dallas, and I’ve been on the go ever since, working on this and that (stay tuned :^).

As many of you may have known, there has been a pretty big bug in the Windows 10 Version 1511 ADK, it’s caused all kinds of interop problems with Configuration Manager. Well Microsoft released a fix today! KB3143760. Yea!

Well I opened up KB3143760, and yikes! The instructions are a bit dry. Mount this, patch that, watch out for the data streams!

I needed to patch my local Windows 1511 ADK installation because I’m working on a SCCM+MDT Refresh scenario, and I don’t want to uninstall the 1511 ADK. Perfect timing, if only there was a way to automate this..

Repair-1511ADK.ps1

Here is a link to a PowerShell script I wrote to auto-magically patch your WinPE files!

https://onedrive.live.com/redir?resid=5407B03614346A99!158500&authkey=!AHWArN5C7FyRPIY&ithint=file%2cps1

This script will:

  • Download the patch (no need to go through the E-Mail process)
  • Take care of all the stream issues (really I don’t use IE/Edge, so no security streams)
  • Auto extract the patch contents
  • Mount the wim file
  • Patch the appropriate dat files
  • Fix the permissions
  • Dismounts the WIM
  • Cleans up all left over files

So, for example, if you wanted to patch all of the WinPE Wim files in the ADK directory (before importing them into SCCM), you can run the following command:

get-childitem 'C:\Program Files (x86)\Windows Kits\10\Assessment and Deployment Kit\*.wim' -recurse | .\Repair-1511ADK.ps1 -verbose

Lately, when programming in PowerShell, I have taken the “write-host considered harmful” rule to heart, so by default, there is *NO* std console output. Instead, I redirect most information output to “verbose”, so if you want to see what is happening in the background, use the -verbose switch.

-k

Hopefully, moving forwards, this will be the *last* time I place a new script up on OneDrive, really I should be moving towards something more… modern… like GitHub.

MDT package now on Chocolatey.org ready for Windows 10!

Been a while since I posted, I’ve been busy with Surface, Windows 10, and other Kits. But my chocolatey package just got approved, so I thought I would share.

I’ve been following the progress of PowerShell’s OneGet, and http://Chocolatey.org for a while now, and thought it was time to stick my toes in and create a package for public use. MDT seemed like a great start.

As you may already know OneGet is a new feature of PowerShell, included in Windows 10 and available through WMF 5.0 that allows for the installation of packages over the internet. Chocolatey is one of the back-end providers, with a great collection of apps ready for installation.

With the recent release of MDT 2013 Update 2, it seemed like a great opportunity to practice my packaging skills. Eventually I created a PowerShell script to auto generate the chocolatey package (not shown here), it would download the MSI files, and extract out the MSI Product Code and Checksum values. You can see the code generated on the Chocolatey MDT page.

Now to install MDT on Windows 10 (or Windows Server 2016), we can run the commands:

set-executionpolicy RemoteSigned; 
Install-Package -Name MDT -ProviderName Chocolatey `
-ForceBootstrap -Force -Verbose

How it works

First step we need to do on clean machine is to set the execution policy:

set-executionpolicy RemoteSigned

Chocolatey has some PowerShell scripts that run in the background, so we need to allow PowerShell to run these commands with the Set-ExecutionPolicy command. Most Powershell users run this command anyways, so it’s not that uncommon.

Then we install the package using the PowerShell 5.0 “Install-Package” cmdlet built into Windows 10:

Install-Package -Name MDT -ProviderName Chocolatey

We must specify the “-ProviderName Chocolatey” parameter the fist time we call Install-Package so the chocolatey Provider is installed, MDT is only known to Chocolatey at this time.

Install-Package will prompt us to confirm installation of the chocolatey provider, we can skip this with the -ForceBootStrap parameter. Additionally, Install-Package will also ask for confirmation before installing MDT, and we can sip the confirmation with the -Force Paramater.

I like to see what is going on the background, so I add the -verbose parameter, and my screen fills with yellow:

Capture

We can see Install-Package downloading MicrosoftDeploymentToolkit2013_x64.msi from the Microsoft web servers.

ADK

The Windows 10 ADK package has also been uploaded to Chocolatey, but hasn’t been officially approved yet, so when you try to run the “windows-ADK” package it will install the older Windows 8.1 version. We can force the Windows 10 ADK to install with a version parameter. Additionally, the default version of the “Windows-ADK” package does not install USMT, so to install everything we will need the “windows-adk-all” package (which is a lot of stuff, sorry).

install-package -ProviderName Chocolatey -Name Windows-ADK-All `
-force -Verbose -MinimumVersion 10.1.10586.0

More information:

https://chocolatey.org/packages/MDT

-k

Deployment Gotcha – Get Windows 10 App doesn’t work with MDT

Did you know that you can download *.iso images of Windows 10 using the Get Windows 10 app?

http://www.microsoft.com/en-us/software-download/windows10

It’s a tool that will allow you to download *.iso images for deployment.

The only problem is that it doesn’t actually download *.iso images, instead, it downloads *.esd images, which are highly compressed *.wim files, that are encrypted/encoded. The tool then decrypts/decodes the *.esd file into *.wim files, and constructs a *.iso image for use.

Additionally, the *.wim file is still a highly compressed *.esd file, so legacy tools that leverage the WIMGAPI library like imagex.exe don’t understand it.  Dism works fine.

C:\>"c:\Program Files (x86)\Windows Kits\10\Assessment and Deployment Kit\Deployment Tools\amd64\DISM\imagex.exe" /info g:\getwin10\Windows\sources\install.wim
ImageX Tool for Windows
 Copyright (C) Microsoft Corp. All rights reserved.
 Version: 10.0.10011.16384

Error opening file [g:\getwin10\Windows\sources\install.wim].

An attempt was made to load a program with an incorrect format.
C:\>dism /get-wiminfo /wimfile:g:\getwin10\Windows\sources\install.wim

Deployment Image Servicing and Management tool
 Version: 6.3.9600.17031

Details for image : g:\getwin10\Windows\sources\install.wim
 Index : 1
 Name : Windows 10 Pro
 Description : Windows 10 Pro
 Size : 9,343,966,034 bytes

The operation completed successfully.

That means that you can’t import the images into MDT, because MDT uses the WIMGAPI libarary, and powershell commands might not work either.

I tried to export the *.wim file to another *.wim file, but DISM.exe doesn’t like doing that either.

As a work around you might be able to export the *.wim file to a *.vhd container, and re-capture back to *.wim file with normal compression.

Johan has been documenting esd to wim techniques on his blog.

http://deploymentresearch.com/Research/Post/399/How-to-REALLY-create-a-Windows-10-ISO-no-3rd-party-tools-needed

Otherwise, I hope the DISM team fixes this for TH2 :^) <hint> <hint>

 

 

MDT 2013 UberBug01 – MDAC and the Fast Machine

Well MDT 2013 Update 1 is out. Yea!

Time to test and evaluate to see if there are any regressions in my test and environment.

Wait… Something went wrong…

dism

Fast System

As I mentioned in an earlier blog post, I recently purchased a super fast Intel 750 SSD to make my MDT Build machine run faster. Blazing Fast

WP_20150507_19_51_57_Pro

You might think: “Wow, that’s super cool, everything would be so much better with a faster machine”

Essentially, yes, except when it’s faster than the Operating System can handle.  :^(

The Bug

When updating a deployment share you may get the following error message:

Deployment Image Servicing and Management tool
Version: 10.0.10240.16384
 
Image Version: 10.0.10240.16384
 
Processing 1 of 1 - Adding package WinPE-MDAC-Package~31bf3856ad364e35~amd64~~10.0.10240.16384
 
Error: 1726
 
The remote procedure call failed.
An error occurred closing a servicing component in the image.
Wait a few minutes and try running the command again.
 

Dism.log shows nothing interesting:

 
2015-07-15 13:55:00, Error                 DISM   DISM.EXE: DISM Package Manager processed the command line but failed. HRESULT=800706BE
2015-07-15 13:55:00, Error                 DISM   DISM Manager: PID=2364 TID=2424 Failed to get the IDismImage instance from the image session - CDISMManager::CloseImageSession(hr:0x800706ba)
2015-07-15 13:55:00, Error                 DISM   DISM.EXE:  - CDismWrapper::CloseSession(hr:0x800706ba)

I asked someone knowledgeable at Microsoft (MNiehaus), and he mentioned that he saw it a couple of times, but couldn’t repro it consistently. However, I could easily reproduce the problem on demand with my hydration/buildout scripts.

Turns out that there is a narrow case where this bug manifests:

  • If you add any optional components to WinPE within MDT
  • If you have a fast hard disk (like my Intel 750 SSD)
  • If you have <UseBootWim> defined in you settings.xml, it may get worse.

The fast disk is most likely why the Windows Product Group teams never saw this bug in testing.

Well, I provided a repro environment to the Windows Product Groups involved in this component, even letting them log into my machine to reproduce the issue.

Good news is that they were able to determine what the root cause is ( timing related during unload of various components ), and even provided me with a private fix for testing! The private passed!

Now the real fun begins, there is a legitimate challenge here, because the error exists in the Windows 10 Servicing Stack, and that stack is embedded *into* WinPE.wim on the ADK and Boot.wim on the OS Install disk.

How do you update these files with the updated servicing stack, it’s not a trivial matter. They could send out a KB QFE Fix, and let customers manually update the files manually with dism.exe, they could also repackage/rerelease the ADK Itself, or worst case wait till the next release of the Windows OS ISO images.

I have been monitoring status, and there are several team members working on the release issues, and even someone from Customer Support acting as a customer advocate. My work is done.

Work Around

In the mean time, you can work around the issue:

  • Removing optional components from MDT. :^(
  • Of course, you move to a machine with a slower disk.
  • I had some luck getting optional components added when I set <UseBootWim> to false in the settings.xml file.
  • Additionally, Johan has mentioned that he can get it to pass if the OS running MDT is Windows 10 ( I was running Windows Server 2012 R2 ).

For me, it was easy, I don’t use the MDAC components in my environment, so I just removed them from the settings.xml file. Lame, I know.

-k

More Deployment bugs to follow!

Updated Dell Driver Catalog Script for Windows 10

Woot!

Schema

Dell has updated the Schema on their DriverPackageCatalog.xml to include full SMBIOS Make and Model information for their systems!

I updated the Install-DellDriverCatalog.ps1 script to take advantage of the new metadata and tried importing drivers for my trusty Dell Venue 8 Pro.  As you may recall, in previous versions of the DriverPackageCatalog.xml file, the Dell Venue 8 Pro had a weird 5830 number for the Model, which didn’t match what was in the Firmware.

Anyways, I tried importing into MDT, and got the following…

DellModelVenue

Looks Great!!

WinPE

Additionally, with the addition of the Windows 10 ADK, I have updated the script to support this platform, and other changes

mdt selection profiles

Scripts:

Install-DellDriverCatalog.ps1

Install-DellWinPEDriverCatalog.ps1

 

Thanks to @WarrenByle for putting up with my pestering :^) Great stuff from dell.