Create Pilot Collection Console Extension for ConfigMgr 2012 R2

I recently started working on my first ConfigMgr Console Extension (aka. Right Click Tool).  For my first foray into this new territory I decided to tackle something that myself and my colleagues deal with on a regular basis, Pilots.  No, not pilots that fly airplanes.  Pilot deployments.  The thing you do before deploying something to Production.

So today I’m releasing my Create Pilot Collection Console Extension for ConfigMgr 2012 R2.  The purpose behind this tool is to support some internal business processes wherein we as packagers are required to deploy larger scale deployments to a smaller “pilot” collection first.  I would imagine that your company has similar requirements as well.

This tool was built using Sapien PowerShell Studio 2015 and was designed to provide a quick and easy way of generating a random sampling of “Pilot Members” for your pilot deployments.

Create Pilot Collection - Main Screen

CREDIT

I’d like to thank Nickolaj Andersen (http://www.scconfigmgr.com) for writing and providing me with the Invoke-ToolInstallation.ps1 script to handle the installation of the Console Extension.  It’s been modified from his original version so I’ll provide a write-up on leveraging this script in a follow-up blog post.

Download

You can download the Console Extension from the TechNet Gallery.

I’ve included the PowerShell Studio Project Files if you would like to tinker and modify for your own use.

Install

To install the Console Extension, extract the .zip file you downloaded to a directory of your choice.  From an Administrative PowerShell Console, run the Invoke-ToolInstallation.PS1 script from the extracted directory.

NOTE: If you currently have the ConfigMgr Console open, you’ll need to close and re-open it.

Usage

To launch the tool, open your ConfigMgr console, and find a collection you wish to use as your “Base” collection.  This would typically be the collection you use for your final (Production) deployment.

The tool can be accessed from the Ribbon or the Right-Click Context Menu as shown below.

Right-Click MenuRibbon Icon

There are only two items you need to fill in.  The Pilot Collection Name and the Percentage of the original (base) collection to use as your pilot members.  The User Interface will update as you type to tell you how many members will be added to your new collection.

Create Pilot Collection - Main Screen

When you are finished, click the button, sit back and relax.  Once your collection is created you can deploy whatever you want to it.

NOTE: Large collections may take several minutes to process and add members.

WMI Module v1.0 Released!

The PowerShell WMI Module was developed to make it easier to create custom WMI Namespaces and Classes.

This module was inspired by Jason Sandys
System Center Universe presentation on WMI Manipulations and Manifestations

The module has been uploaded to TechNet Script Gallery. Get it here!

Module Functions

Get-WMINamespace

This function returns an object containing the Namespace requested.

Example: Get-WMINamespace –Namespace ‘Namespace1’

Get-WMIClass

This function returns an object containing the WMI Class requested.

Example: Get-WMIClass –Namespace ‘Namespace1’ –ClassName ‘Class1’

New-WMINamespace

This function creates a new WMI Namespace and returns the WMI Namespace object using Get-WMINamespace.

Example: New-WMINamespace –Root ‘Root’ –Name ‘Namespace1’

New-WMIClass

This function creates a new WMI Class and returns the WMI Class object using Get-WMIClass.

Example: New-WMIClass –Name ‘Class1’ –Namespace ‘Root\Namespace1’

Add-WMIClassProperty

This function adds a single WMI Class Property to your custom WMI Class. Use this function multiple times to add multiple properties.

Examples:

Add-WMIClassProperty Namespace $namespace
ClassName $className
PropertyName “Default”
PropertyType ‘String’
IsKey

 

Add-WMIClassProperty Namespace $namespace
ClassName $className
PropertyName “IsEnabled”
PropertyType ‘String’

 

ConfigMgr2012 PowerShell Module v1 Released!!!

Today I’d like to announce the v1 release of my own custom PowerShell Module for use with ConfigMgr 2012 R2.  This module was developed over the course of the last year (as I’ve had time) to address some shortcomings in earlier versions of the ConfigMgr PowerShell Cmdlets.  Namely bugs when creating Script-Based Deployment Types.  In addition, I recently demo’d the functionality of this module at the Central Texas Systems Management User Group.

Overview

  • Credits
  • Download the Module
  • Module Functions

Credits

I have to give credit to a few people for some of the functions in this module.  Some of the functions were pulled from other existing modules or derived from blog posts and organized into this module to cut down on the references I needed to have.

 

Download Now

I’ve created a new project in CodePlex to host the installer, source code, documentation etc.  Please head on over to https://configmgr2012module.codeplex.com/ to download the module.  If you’d like to contribute, you may contact me at dustinhedges AT outlook DOT com or sent me a message on the blog.

 

Module Functions

This release of the module contains 20 functions.  All of these functions have been tested on Configuration Manager 2012 R2.  My testing was limited to specific functionality so there may be bugs.  Please submit any feedback or issues via Codeplex.

  • Add-SCCMDependencyGroup
  • Add-SCCMDeploymentType
  • Add-SCCMEnhancedDetectionMethod
  • Add-SCCMRequirementRule
  • Copy-SCCMDependencyGroup
  • Copy-SCCMRequirementRule
  • Get-SCCMApplication
  • Get-SCCMApplicationObject
  • Get-SCCMAuthoringScopeID
  • Get-SCCMDeployment
  • Get-SCCMGlobalCondition
  • Import-SCCMAssemblies
  • New-SCCMApplication
  • New-SCCMApplicationObject
  • New-SCCMDeploymentType
  • New-SCCMDeploymentTypeReturnCode
  • New-SCCMEnhancedDetectionMethod
  • New-SCCMGlobalConditionsRule
  • Save-SCCMApplication
  • Save-SCCMApplicationObject

 

Downloading Dell Driver CAB files automagically with the Driver Pack Catalog

Dell has been hard at work behind the scenes trying to make our lives as IT Pros easier.  From their Enterprise Client Tools such as OMCI and the Client Configuration Toolkit (CCTK) to the more recent (past few years) Driver CAB files.  Well yesterday we got another tool to help us in the fight to manage our drivers and ease the pain of obtaining them.  Yesterday Dell unleashed the Dell Driver Pack Catalog.

What is the Dell Driver Pack Catalog you ask?  Warren Byle (Dell) sums it up nicely:

                The Driver Pack Catalog is an XML file containing metadata about the  new Dell systems and WinPE Driver Packs. This XML file is compressed as a Microsoft Cabinet (.CAB) file and digitally signed for delivering it to the customers over the internet.

Basically, it gives is a structured way of identifying the latest and greatest driver packages (CABs) available from Dell.  And with that, I’m here to introduce a new companion script that should give you a jumpstart.

I call it the Dell Driver CAB Downloader Script Thingy (Ok, I’m still working on a name).  You can get the script from here.

What It Does

It’s pretty simple really. You supply the script with some input parameters such as the Model and/or Operating System you would like to download driver packages for, and it does the rest.

First things first let’s explain the general flow of the script once executed:

  1. The script will connect out to Dell’s HTTP download site and download the latest CAB file. NOTE: You have an option to supply a local file if you wish
  2. After downloading the file (Uses currently logged on users credentials), it extracts it to the Download Folder that you provide
  3. Next we consume the extracted XML file and begin searching thru all listed Driver Packages for a match (Model and/or Operating System)

Examples

Execute the following command to download a single WinPE Driver CAB:

.\Download-DellDriverPacks.ps1 –DownloadFolder “C:\Downloads” –TargetOS 32-Bit_-_WinPE_3.0 –Verbose -DontWaitForDownload

WinPE

Execute the following command to download all Driver CAB’s for a specific model:

.\Download-DellDriverPacks.ps1 -DownloadFolder "C:\Downloads" -TargetModel "Latitude E7240" –Verbose

ModelTarget

Closing Thoughts

The introduction of this new Driver Pack Catalog brings with it a new set of possibilities for Driver Management.  While the script I’ve outlined here only solves a small piece of the puzzle, my hope is that it will lay the groudwork for some great tools to provide an end-to-end solution of Downloading, Importing and Distributing drivers for Dell systems.

WinPE 5.0 x64: Microsoft.SMS.TSEnvironment Unavailable?

Recently I began exploring leveraging Prestart Commands in my Configuration Manager 2012 R2 environment.  I’d previously leveraged them in the form of a “WebService Boot ISO” compliments of Maik Koster.  I figured this would be no big deal, however I found my self running into troubles right out of the gate.

Specifically, the issue I ran into was not being able to load the Microsoft.SMS.TSEnvironment COM Object during the WinPE Prestart phase (before you select a Task Sequence).  Now Technet provides some lovely documentation telling me that this is for sure possible and they even provide a nice little code snippet showing me that it should work.  The only problem, when I try it, I get this ugly error in PowerShell:

Microsoft.SMS.TSEnvironment Error

Strange error so I start doing some searching and come across this forum posting:  WinPE SysNative Forum Post

Ok, easy enough.  I’ve dealt with this before so we’ll just load up the cmd shell in WinPE 5.0 x64 and launch the 32-bit PowerShell.exe.  SysNative Path Not Found

Path not found.  What???  How can this be?  It’s always “just been there”.

Ok, enough whining, just call it from SysWOW64 directly.

No WindowsPowerShell Directory!
No WindowsPowerShell Directory!

Or not.  The WindowsPowerShell directory doesn’t even exist!  No 32-Bit instance of it is here! And for that matter no 32-bit instances of cmd.exe, cscript.exe, etc.  I even confirmed this by mounting the boot image .wim file.

You may now be thinking “Just use DISM to load the 32-bit PowerShell components from the ADK”.  Yeah, doesn’t work.

DISM

Just for good measure I loaded up a stock 64-bit MDT 2013 Boot Image (WinPE 5.0 of course) and same result.

Now here is the kicker.  The Microsoft.SMS.TSEnvironment IS available during the preboot phase, BUT (you knew this was coming) you have a very limited window where this environment is accessible.  If you are just trying to test out some code (before making permanent changes to your Boot Images), you can add a Prestart command to launch cmd.exe /k (The ‘/k’ keeps the command window open so you can test).

PrestartCMD

So long as you are executing your code leveraging this Prestart Method, you can access the Microsoft.SMS.TSenvironment.

I hope this helps someone out there.  Took me a while to track this “limitation” down while testing out new code.

 

SCCM 2012 Migration: Copying Boot Image Drivers

When migrating from an older SCCM 2007 environment to SCCM 2012, one of the things that doesn’t carry over are your boot images and the drivers that go along with them. During a recent migration from SCCM 2007 to 2012 R2, I found myself in a position just like this. I created new WinPE 5.0 Boot Images however I still had the need to support Windows XP and Server 2003 for just a little longer so I needed to create WinPE 3.1 boot images to support those aging operating systems.

Since I wasn’t able to easily migrate this information over from the old environment using the built-in migration tool, I took to PowerShell to make my own.

Here the gist of the script:

  1. Connect to your old SCCM 2007 Site Server and get all the drivers associated with each boot image you want to reference.
  2. Loop thru all the drivers associated with that boot image and copy the driver source to a new source directory for your new boot images in SCCM 2012 (I use a separate file share for this so I don’t accidentally overwrite something).

NOTE: I’m automatically naming the destination driver folder based on the Driver Name (excluding special characters) and Version. I’ll let DISM sort out everything else later when adding drivers to the WIM.

Here’s the script:

[CmdletBinding()]
Param(
	[Parameter(Mandatory=$true,HelpMessage="Root Directory for Drivers to be copied too.",ValueFromPipeline=$True,ValueFromPipelinebyPropertyName=$True)]
	[String]$DriverDestinationRoot,

	[Parameter(Mandatory=$true,HelpMessage="Your SCCM Site Server.",ValueFromPipeline=$True,ValueFromPipelinebyPropertyName=$True)]
	[String]$SCCMServer,

	[Parameter(Mandatory=$true,HelpMessage="Your SCCM Site Code.",ValueFromPipeline=$True,ValueFromPipelinebyPropertyName=$True)]
	[String]$SCCMSiteCode,

	[Parameter(Mandatory=$true,HelpMessage="Boot Image Package ID.",ValueFromPipeline=$True,ValueFromPipelinebyPropertyName=$True)]
	[String]$PackageID
)

$BootImage = Get-WmiObject -ComputerName $SCCMServer -Namespace "Root\SMS\Site_$SCCMSiteCode" -Class "SMS_BootImagePackage" -Filter "PackageID='$PackageID'"
$BootImageDrivers = $([WMI]$BootImage.__PATH).ReferencedDrivers

foreach($Driver in $BootImageDrivers){
    $SourcePath = $Driver.SourcePath
    $DriverID = $Driver.ID

    # Get SMS_Driver Detailed Information
    $SMS_Driver = Get-WmiObject -ComputerName $SCCMServer -Namespace "Root\SMS\Site_$SCCMSiteCode" -Class "SMS_Driver" -Filter "CI_ID='$DriverID'"
    $DriverVersion = $SMS_Driver.DriverVersion
    $DriverName = [System.Text.RegularExpressions.Regex]::Replace($($SMS_Driver.LocalizedDisplayName),"[^1-9a-zA-Z_]","_")

    
    # Create New Driver folder
    $DriverDestinationFolder = New-Item -Path "$DriverDestinationRoot\$DriverName`_$DriverVersion" -ItemType Directory

    Copy-Item -Path $SourcePath -Destination $DriverDestinationFolder -Recurse -Force -Verbose
}

Updating Dell BIOS with PowerShell (Updated)

Some of you may be familiar from my earlier article “Dell BIOS Updates with PowerShell” and hopefully you have gotten some good use out of it.  There have been a few comments on that article and over time I’ve also had some issues with that version of the script brought to my attention.

Some of these issues are:

  1. 1. Dell OptiPlex 745 updates don’t work because of the naming convention
  2. 2. Bios updates are overriding newer versions that come from the factory
  3. Still not updating to the latest available version due to supersedence rules for the BIOS updates (i.e. Needing A05, then A08, then finally A12).

So with that I fired up PowerGUI and started analyzing the entire flow of the script.  And more importantly kept in mind the overall process needed when multiple versions of a BIOS Update may be required (from A01 to Axx).  With this new script, I’ve introduced some new “features”

  1. Added a loop to parse multiple available BIOS update files
  2. Added a switch condition to allow for “oddly-named” BIOS file versions (read: OptiPlex 745)
  3. Added BIOS Release Date information (Universal Time Format) to check for BIOS “Patches” (i.e. P02 on Latitude E6410/E6510)
  4. Added OSD-Specific tasks (separate script)
  5. Embedded function for actually invoking the BIOS Update process itself with custom parameters.
  6. Removed dependency on Dell OMCI for BIOS identification (using Win32_BIOS now)

Dell_BIOSUpdates.zip

Using this with OSD/MDT

I’m not going to go over the script in its entirety here, however I will put out a few things specifically for using the “OSD” version of the script.  This additional script will connect to the Microsoft.SMS.TSEnvironment in order to interact with and create a new Task Sequence Variable.

When using this with OSD/MDT, you’ll want to have the script run multiple times in order to fully update the BIOS to the latest possible revision in the case that multiple executions are necessary.  Below I’ve documented the process that I have implemented to do just this.


Task Sequence Structure:

shot_662012_104220_amAs you can see here, we have multiple nested groups that will run the Dell BIOS Update script and enforce a reboot after the update has been staged.  One thing to point out here is that after the first run (which I’m calling as a regular Package/Program) is the word “Local”.  That’s right, the OSD script is copying the model-specific BIOS Updates locally (if there is more than one) so we don’t re-download the whole package again.

Update BIOS Group Condition:

shot_662012_105011_am

Update Dell BIOS Run Commandline:
powershell.exe -NoProfile -NonInteractive -File
“C:\Temp\Dell_BIOS_Updates\Invoke-DellBIOSUpdate-OSD.ps1”

Dell_BIOSUpdates.zip