Action-Packed CTSMUG meeting on February 5th – Registration is Open!

We have a great meeting planned for February 5th – register now!

Here are 3 days of System Center that you need to attend:

February 4thSystem Center Universe – You can register in person for attending in Dallas, or join us at the Microsoft office (in the arboretum) for the simulcast. We will have two rooms (one for each simulcast stream). Join us for lots of discussion, food, and swag. Take a look at the agenda.

February 5thCTSMUG February meeting, it will also be at the Microsoft office, and sponsored by SoftwareOne. (See our agenda below)

February 6thSAASMUG – Road Trip to San Antonio!  Featuring Wally Mead and Kent Agerlund!

Here’s our February 5th Agenda (we will be at Microsoft Austin Office):

10:00 – Understand the Enterprise mobility challenges today or get left behind – Kent Agerlund
11:15 – Service Management Automation – The path to the future Charles Joy
12:30 – Lunch – Sponsored by Software One
1:30 – OSD Tips and Tricks – Bill Moore
2:30 – Moderated Discussion – Donnie or Warren

Understand the Enterprise mobility challenges today or get left behind – According to a recent Gartner study more than 20% of all Enterprises will fail the attempt to implement a BYOD/CYOD solution. In this session we will cover how you can address the Enterprise Mobility challenges using System Center Configuration Manager and Microsoft Enterprise Mobility Suite. You learn about the new mobile device management features and how to manage Windows/iOS and Android devices via both System Center Configuration Manager and Microsoft Intune. You will learn how to setup the infrastructure needed, the new features, how to work with identity management, corporate data, and how to enroll and manage devices.

OSD Tips and Tricks – I/T professionals spend substantial time automating processes so that they have time to direct their attention to more important things. There are some processes however that will always be time consuming, like system imaging for example. In this session we will discuss an often overlooked Configuration Manager feature, prestaged media. Used not for OEM media, but as part of the daily support function. You will learn how to create and deploy multi-wim task sequences and standalone media, create generic PowerShell forms for managing OS deployment in a multi-wim configuration, and configure your images for rapid deployment. We will also discuss tips and tricks for using standalone media as a single mechanism to fine tuning your operating system deployment scripts.

Service Management Automation – The Path to the Future – Charles will discuss System Center Orchestrator, but focus on moving toward SMA, and give examples of how SMA should be used. SMA is a pretty new topic/app to most of us, and we all know we need to dive into it a bit further. This first session with Charles will help you understand better for where SMA will fit in your environment, and will demonstrate several scenarios and runbooks.

Book Exchange! – We introduced the concept at our December meeting. Do you have some old tech books that you no longer need, that may benefit someone else? Bring them to our next meeting, to give others the opportunity to take your old books (for free), and maybe you’ll find one in the pile that will help you too! (Please, if no one takes your book, take it home with you. Also, let’s keep it to tech–no romance novels please. .)




How to: Extract Status Message Information from ConfigMgr 2012 R2

During MMS 2014, Wally Mead and I presented a session about state and status messages. This post describes one of the scripts that I demonstrated, which uses PowerShell to display status messages in a human-readable-friendly manner. This is similar to using the ConfigMgr status message viewer or SSRS reports, in that it displays the full sentence and description of the status message information. The value that this script adds, is that you can generate the information outside of the ConfigMgr Console (and outside of the SSRS reports).

First, the code (viewed best with Chrome browser): download GetStatusMessages.ps1

$StatMsgs = @()
$cnstring='Provider=SQLOLEDB;Integrated Security=SSPI;Persist Security Info=False;' + `
 'Initial Catalog=CM_LAB;Data;User ID=;Password='
Add-Type -Path `
 "D:\MSRS10_50.MSSQLSERVER\Reporting Services\ReportServer\bin\srsresources.dll"

$cmdtext = @"
select top 1000 smsgs.RecordID,
CASE smsgs.Severity
WHEN -1073741824 THEN 'Error'
WHEN 1073741824 THEN 'Informational'
WHEN -2147483648 THEN 'Warning'
ELSE 'Unknown'
END As 'SeverityName',
smsgs.MessageID, smsgs.Severity, modNames.MsgDLLName, smsgs.Component,
smsgs.MachineName, smsgs.Time, smsgs.SiteCode, smwis.InsString1,
smwis.InsString2, smwis.InsString3, smwis.InsString4, smwis.InsString5,
smwis.InsString6, smwis.InsString7, smwis.InsString8, smwis.InsString9,
from v_StatusMessage smsgs
join v_StatMsgWithInsStrings smwis on smsgs.RecordID = smwis.RecordID
join v_StatMsgModuleNames modNames on smsgs.ModuleName = modNames.ModuleName
--where smsgs.MessageID = 10803 and smsgs.MachineName in
-- (select name from _res_coll_CEN00018)
--where smsgs.MachineName = 'mycomputername'
Order by smsgs.Time DESC


$cn = New-Object System.Data.OleDb.OleDbConnection $cnstring

$cmd = New-Object System.Data.OleDb.OleDbCommand $cmdtext, $cn
$cmd.CommandTimeout = 0
$reader = $cmd.ExecuteReader()
while ($
$FullMsgString = `
 [int]$reader["Severity"], $reader["MsgDllName"].ToString(), "en-US",
 $reader["InsString1"].ToString(), $reader["InsString2"].ToString(),
 $reader["InsString3"].ToString(), $reader["InsString4"].ToString(),
 $reader["InsString5"].ToString(), $reader["InsString6"].ToString(),
 $reader["InsString7"].ToString(), $reader["InsString8"].ToString(),
 $reader["InsString9"].ToString(), $reader["InsString10"].ToString())
$FullMsgString = $FullMsgString -replace '([\.][\r])[\n]','.'
$FullMsgString = $FullMsgString -replace '([\.][\r])[\n]','.'
$obj = @{
SeverityName = $reader["SeverityName"].ToString()
MessageID = $reader["MessageID"].ToString()
Severity = $reader["Severity"].ToString()
MsgDLLName = $reader["MsgDLLName"].ToString()
Component = $reader["Component"].ToString()
MachineName = $reader["MachineName"].ToString()
Time = $reader["Time"].ToString()
SiteCode = $reader["SiteCode"].ToString()
InsString1 = $reader["InsString1"].ToString()
InsString2 = $reader["InsString2"].ToString()
InsString3 = $reader["InsString3"].ToString()
InsString4 = $reader["InsString4"].ToString()
InsString5 = $reader["InsString5"].ToString()
InsString6 = $reader["InsString6"].ToString()
InsString7 = $reader["InsString7"].ToString()
InsString8 = $reader["InsString8"].ToString()
InsString9 = $reader["InsString9"].ToString()
InsString10 = $reader["InsString10"].ToString()
FullMsgString = $FullMsgString

$statmsgs += new-object psobject -Property $obj

$wmidate = new-object -com Wbemscripting.swbemdatetime
$date = get-date -format g
$csv = "C:\logs\Statmsgs_" + $wmidate.value.substring(0,12) + ".csv"

$statmsgs | select-object SeverityName, MessageID, Component,
 MachineName, Time, SiteCode, FullMsgString `
 | export-csv $csv -notypeinformation
$statmsgs | select-object SeverityName, MessageID, Component, MachineName,
 Time, SiteCode, FullMsgString `
 | out-gridview
$statmsgs | group-object component | sort count -descending | out-gridview

To run this code in your environment, update the following:

  • Line 4 – modify CM_LAB and to your server database and database server name.
  • Line 6 – modify path to your SSRS server dll.
  • Create c:\logs directory, or modify line 78.

The easiest location to run this code is on an active ConfigMgr Reporting Point (otherwise, you may have to copy/register some .dlls from your reporting point).

Here’s a breakdown of some of the code, and some ideas on how to customize it for your environment.

  • Lines 8-28 – this is the SQL code that’s run against your ConfigMgr database – you should be able to run it manually as well. Notice that as written, we are querying the last 1000 status messages. Modify the query to filter by machine name, systems in a collection, or specific status message IDs.
  • After executing the SQL query, (lines 32-37), we iterate through each result, create a custom object, and add it to an array (line 72). By creating the custom object for this data, we can perform other cool actions (as described next).
  • Lines 76-83 are used to easily create a .csv file (with a dynamic filename, based on the current date in wmi date-time format.
  • Lines 84-86 are used to display the information into a gridview – I find this view very handy, in that I can quickly look at data, filter, sort, etc. without much effort.
  • Line 87 also generates a gridview – but this time, I used it with the group-object cmdlet  to easily show how many times a specific message is received, grouped by component name.

Happy Scripting!


This post first appeared on