Forcing Installation of the MDT ConfigMgr Integration WMI Classes

Today I encountered an unexpected issue installing the ConfigMgr Integration for MDT. The scenario was an environment with several SMS providers and 2 site servers in a high availability configuration (active / passive). The MDT ConfigMgr Integrations ran successfully on each of the SMS Provider servers, but on the passive site server the BDD_* WMI classes were not created under ROOT\sms\site_XYZ, even though the ConfigMgr Integration wizard completed successfully and reported no error. I ran the wizard with the option to install the task sequence actions to the local server in each case.

Without the WMI classes in place, you get the error “Failed to load class properties and qualifiers for class BDD_*** in task sequence.” when viewing or editing a task sequence containing MDT steps:

The solution was simply to manually compile the MOF file that comes with MDT, which is called Microsoft.BDD.CM12Actions.mof. After the Integration wizard has run, the MOF file be found in Program Files\Microsoft Configuration Manager\AdminConsole\bin. It can also be found in the MDT installation directory Program Files\Microsoft Deployment Toolkit\SCCM.

You need to edit the first line of the MOF file so that it is pointing to the local server, and contains the correct WMI location to install the classes to, eg:

#pragma namespace("\\SCCM001.CONTOSO.COM\root\sms\site_XYZ")

Then compile the MOF file from an admin CMD:

mofcomp <path>\Microsoft.BDD.CM12Actions.mof
BDD_* classes in WMI

Retrieving Local Logon Events from the SCCM Client WMI

Usually when querying the logon history of a Windows system you might query the Security event log or a domain controller. But if you’re using SCCM, the SCCM client also logs user logon events and stores them in WMI. Here’s a quick PowerShell script to retrieve those events and translate them into meaningful values.

You can run it against the local or a remote computer and optionally specify the maximum number of events to retrieve.

Note that for remote computers the date/time values will be displayed in your local time zone, not necessarily the timezone of the remote system.

Get-CMUserLogonEvents | Sort LogonTime -Descending | Out-GridView

Just for Fun – Send a Remote Toast Notification

Did you know you can send a custom toast notification to a remote computer? Call it poor man’s IM, but if you’re using Windows 10 with PowerShell remoting enabled it might be a good way to annoy your colleagues if you can’t find a more constructive use!

Try the following code, which creates a notification like this on your mate’s computer:

HTML Report for SCCM Site Component Warnings and Errors

Just a quick one 🙂

If you’re like me you are too lazy busy to regularly check the component status of an SCCM Site Server for any issues, so why not get PowerShell to do it for you?

The code below will email an html-formatted report of any site components that are currently in an error or warning status, together with the last few error or warning status messages for each component. Run it as a scheduled task or with your favorite automation tool to keep your eye on any current issues. Whether you get annoyed because you now created more work for yourself, or get happy because you can stay on top of issues in your SCCM environment, I leave to you!

The report will display the components that are marked as either critical or warning with the current number of messages:

It will then display the last x status messages for each component for a quick view of what the current issue/s are:

Run the script either on the site server or somewhere where the SCCM console is installed, and set the required parameters in the script.

ConfigMgr Client TCP Port Tester

This is a little tool I created for testing the required TCP ports on SCCM client systems. It will check that the required inbound ports are open and that the client can communicate to its management point, distribution point and software update point on the required ports. It also includes a custom port checker for testing any inbound or outbound port.

The default ports are taken from the Microsoft documentation, but these can be edited in the case that non-default ports are being used, or additional ports need to be tested.

The tool does not currently test UDP ports.

Requirements

  • Windows 8.1 + / Windows Server 2012 R2 +
  • PowerShell 5
  • .Net Framework 4.6.2 minimum

Download

Download from the Technet Gallery.

Usage

To use the tool, extract the ZIP file, right-click the ‘ConfigMgr Client TCP Port Tester.ps1′ and run with PowerShell.

Checking Inbound Ports

Select Local Ports in the drop-down box and click GO to test the required inbound ports.

Checking Outbound Ports

Select the destination in the drop-down box (ie management point, distribution point, software update point).

Enter the destination server name if not populated by the defaults and click GO. The tool will test ICMP connectivity first, then port connectivity.

Custom Port Checking

To test a custom port, select Custom Port Test from the drop-down box. Enter the port number, direction (ie Inbound or Outbound) and destination (Outbound only). Click Add to add the test to the grid. You can add several tests. Click GO.

Adding Default Servers

You can pre-populate server names by editing the Defaults.xml file found in the defaults directory. For example, to add a default management point:

<ConfigMgr_Port_Tester>
  <ServerDefaults>
    <ManagementPoint>
      <Value>SCCMMP01</Value>
    </ManagementPoint>

Editing / Adding Default Ports

You can also edit, add or remove the default ports in the Defaults.xml file. For example, to add port 5985 in the default local port list:

<PortDefaults>
  <LocalPorts>
    <Port Name="80" Purpose="HTTP Communication"/>
    <Port Name="443" Purpose="HTTPS Communication"/>
    <Port Name="445" Purpose="SMB"/>
    <Port Name="135" Purpose="Remote Assistance / Remote Desktop"/>
    <Port Name="2701" Purpose="Remote Control"/>
    <Port Name="3389" Purpose="Remote Assistance / Remote Desktop"/>
    <Port Name="5985" Purpose="WinRM"/>
  </LocalPorts>

Source Code

Source code can be found in my GitHub repo.

Create Collections for SCCM Software Update Installation Failures by Error Code

Recently I published a blog about creating collections for SCCM client installation failures by error code. In this post, I will do the same for Software Update installation failures.

If you’re lucky enough not to have any errors installing software updates with SCCM, then this post isn’t for you, but if you do experience installation failures it can be helpful to collate machines with the same error into collections so you can easily target them for remediation using the SCCM Scripts feature for example, or just for visibility and reporting.

To find which software update installation errors you are experiencing in your environment, you can run the following SQL query against the SCCM database. This will find systems in the “Error” or “Unknown” enforcement states for software update deployments and group them by the enforcement error code.

Select Count(ResourceID),LastEnforcementErrorCode
from vSMS_SUMDeploymentStatusPerAsset 
where StatusType in (4,5)
and LastEnforcementErrorCode is not null
Group by LastEnforcementErrorCode

Next is a PowerShell script that will create collections for each error code. You need to specify the error codes in the Error Code translation table in the script. I’ve included some common error codes for software updates and their friendly descriptions – add or remove error codes according to your own environment. To translate error codes to friendly descriptions, see here. Run the script on a site server or anywhere with the SCCM console installed.

I’ve split the collections between those with an “error” enforcement state and those with “unknown” as you may wish to handle them separately, and placed the collections for each state in different sub-folders.

You may wish to be more targeted in the WQL query for the collection rule, targeting only certain collections or deployments etc. For example, you can add a ‘where’ clause for SUM.CollectionName to target particular collections, or SUM.AssignmentName to target specific SUG deployments.

Here’s what the end result will look like. The error description is added to the Comment field, so just add that in the console view.

Create Collections for SCCM Client Installation Failures by Error Code

Ok, so in a perfect SCCM world you would never have any SCCM client installation failures and this post would be totally unnecessary. But in the real world, you are very likely to have a number of systems that fail to install the SCCM client and the reasons can be many.

To identify such systems, it can be helpful to create collections for some of the common client installation failure codes so you can easily see and report on which type of installation failures you are experiencing and the number of systems affected.

To identify the installation failure error codes you have in your environment for Windows systems, run the following SQL query against the SCCM database:

select 
	Count(cdr.Name) as 'Count',
	cdr.CP_LastInstallationError as 'Last Installation Error Code'
from v_CombinedDeviceResources cdr
where
	cdr.CP_LastInstallationError is not null
	and cdr.IsClient = 0
	and cdr.DeviceOS like '%Windows%'
group by cdr.CP_LastInstallationError
order by 'Count' desc
Client installation error counts

Next simply create a collection for each error code using the following WQL query, changing the LastInstallationError value to the relevant error code:

select 
    SYS.ResourceID,
    SYS.ResourceType,
    SYS.Name,
    SYS.SMSUniqueIdentifier,
    SYS.ResourceDomainORWorkgroup,
    SYS.Client 
from SMS_R_System as SYS 
Inner Join SMS_CM_RES_COLL_SMS00001 as COL on SYS.ResourceID = COL.ResourceID  
Where COL.LastInstallationError = 53 
And (SYS.Client = 0  Or SYS.Client is null)

Error codes are all fine and dandy, but unless you have an error code database in your head you’ll want to translate those codes to friendly descriptions. To do that, I use a PowerShell function I created that pulls the description from the SrsResources.dll which you can find in any SCCM console installation. There’s more than one way to translate error codes though – see my blog post here. Better yet, create yourself an error code SQL database which you can join to in your SQL queries and is super useful for reporting purposes – see my post here.

Anyway, once you’ve translated the error codes, you can name your collections with them for easy reference:

Client installation failure collections

Now comes the hard part – figuring out how to fix those errors and working through all the affected systems 😬