image It is pretty well known how to add custom extensions to the Configuration  Manager hardware inventory using sms_def.mof and configuration.mof. What isn’t well-known or documented (at least not that I could find), was how to check-up on or remove a custom extension from ConfigMgr manually. There are two tools that can help you with deleting the extension: delgrp.exe (available from the SMS 2003 resource kit) and SiteSweeper from SCCMExperts. But what do you do if these tools aren’t working for you or you simply want to check up on your extension?

First, it is important to note that a best practice for custom inventory extensions is to always test them on a test ConfigMgr site; however, most folks don’t have test installations of ConfigMgr and even if they do, the data isn’t necessarily representative of the data in their production site.

The following is of course completely unsupported – by Microsoft or me – so tinker with the DB at your own risk (or peril). Make sure that you have a good DB backup as a simple restore should get you back to where you were if you foobar something.

The following database objects are involved with HW extensions (where Extension_GroupID is the name of the group as specified in sms_def.mof by the SMS_GROUP_NAME qualifier).

Tables:

  • InventoryClass – Lists extension classes
  • InventoryClassProperty – Lists properties of extension classes, references rows in the InventoryClass by InventoryClass.ClassID
  • DataItem – References rows in the InventoryClass by InventoryClass.ClassID
  • DataItemProperty – References rows in the InventoryClass by InventoryClass.ClassID and rows in InventoryClassProperty by InventoryClassProperty.PropertyID
  • GroupMap – Maps the class ID to the tables in the database
  • Extension_GroupID_DATA – Contains data for the extension
  • Extension_GroupID_HIST – Contains history data for the extension

Views:

  • v_GS_Extension_GroupID0 – View used for actual data retrieval/reporting
  • v_HS_Extension_GroupID0 – View used for historical data retrieval/reporting
  • vex_GS_Extension_GroupID0 – ?

Stored Procedures:

  • pExtension_GroupID_DATA
  • dExtension_GroupID_DATA

The WMI repository on the site server also contains information about HW extensions in the root\SMS\Site_XYZ namespace (where XYZ is the site code). The following classes will exist:

  • SMS_G_SYSTEM_Extension_GroupID
  • SMS_GH_SYTEM_Extension_GroupID
  • SMS GEH_SYSTEM_Extension_GroupID

Removing the rows referencing the extension from the first five tables listed above, deleting the other DB objects, and deleting the WMI classes listed, should remove a hw extension from ConfigMgr. Note that deleting WMI classes also deletes all instances of the class. You can also simply monitor the tables if you just want to verify the data or creation of the proper objects. It is of course possible and likely that the above list is not all inclusive, but in my (limited) testing, this is what turned up.

fireworks

Microsoft_MVP_logo

Today, I was honored with the Microsoft Most Valuable Professional award for System Center Configuration Manager. I am humbled, excited, encouraged, enthusiastic, and truly honored. A big thank you to anyone and everyone who has supported me over the past years and enabled me to achieve this level of recognition from the company whose products my career revolves around.

 

Anyone who’s dealt with ConfigMgr knows that the log files are invaluable for spelunker troubleshooting issues and day-to-day monitoring. One of ConfigMgr’s strengths (IMO) is that nearly everything, in detail, is in a log file – somewhere.

The “problem” that often crops up is knowing which log file to look in; although the main purpose of each log file is documented on TechNet, it’s often difficult to narrow down exactly which log file to dig through. Log files also roll (by default) every 2MB: for some log files this is a lot, for others, like ccm.log, this might only last a couple of hours especially during a large client push.

Wouldn’t it be nice to have a single, searchable repository for all of your log files?

splunk Enter Splunk. Splunk is a free tool (up to 500MB a day of logs) that will suck in and index all of the specified log files on a system. It does more than just text log files, but for ConfigMgr, that’s all we’re really concerned with. Splunk then provides a web based search page for all of the indexed data so we can search for all occurrences of a string. Splunk also creates fields based on name=value pairs, has an event definition mechanism, and provides data tagging.

Splunk allows you to forward the data from one system to another. The obvious application here is to forward all of the collected logs from all of the  site servers to a central Splunk server, perhaps your primary site server. You could forward everything from secondary site servers and child site servers also giving you a single, central, searchable repository for all of your logs from all of your sites.

There is an Enterprise version of Splunk that costs money, so it may be worth looking into if you have a large installation or require some extra security, but I think the standard free version would suffice for most installations.

I’m not a Splunk expert, but I see a lot value in using Splunk for ConfigMgr logs.

SystemCenter The following is a list of significant post SP1 updates for ConfigMgr. Most of these updates are by request only; all you have to click the link at the top of the KB and complete the quick request.

bulletOperating system deployment fails in a System Center Configuration Manager 2007 SP1 environment if you deploy a different operating system to a client within one hour of a previous deployment
http://support.microsoft.com/kb/969113

bulletRecurring advertisements or maintenance windows start to run an hour later or earlier than expected when the time is changed because of DST in System Center Configuration Manager 2007
http://support.microsoft.com/kb/956259

bulletYou receive an error message when you click and then update the Drivers node in the Configuration Manager console of a Configuration Manager 2007 Service Pack 1 site that uses SQL Server 2008 for the site database
http://support.microsoft.com/kb/955262

bulletError message when you try to import OSD drivers in System Center Configuration Manager 2007 Service Pack 1 systems: "The selected driver is not applicable to any supported platforms"
http://support.microsoft.com/kb/961105

bulletA task sequence that contains many packages may take longer to run after you install System Center Configuration Manager 2007 Service Pack 1 or hotfix 949225
http://support.microsoft.com/kb/955955

bulletWhen you use System Center Configuration Manager 2007 Service Pack 1 to capture an image of Windows Vista SP2 or of Windows Server 2008 SP2, the image capture process fails during the "Prepare Windows for Capture" stage:
http://support.microsoft.com/kb/970093

Hardware Inventory isn’t a huge topic, but there are a lot of details – far more than I could cover in a single post. The intent of this post is to cover a significant change from SMS 2003 to ConfigMgr 2007: the separation of reporting classes and data classes into two files.

The first thing I usually tell folks is that hardware inventory isn’t really hardware inventory, it’s inventory from the WMI repository. WMI is most often associated with hardware and most of the default information stored in WMI is hardware related, but not all of it. This is of course significant when you look at the Resource Explorer and see Add/Remove Programs under it or when you want to extend inventory in Config to collect registry values and are told that it is handled by the hardware inventory process. Definitely a potential cause for confusion also.

Also, ConfigMgr does not pull everything available from WMI, it pulls a selected subset as defined in the sms_def.mof file (located in <Installation Dir>\inboxes\clifiles.src\hinv). SMS_DEF.mof is a plain text file that you can edit with notepad or any text editor. It is in a special format called Managed Object Format (MOF); MOF files are part of the WBEM/CIM standard and not Microsoft proprietary. The MOF file format is fully documented on MSDN: http://msdn.microsoft.com/en-us/library/aa823192%28VS.85%29.aspx.

Unless you are extending a MOF file, you don’t need to be intimately familiar with the format details. The main thing to know is that MOF files define classes of information, similar to classes in object-oriented programming. Each class can have properties and methods, although for data collection we don’t really care about methods.

This bring us to our two files: SMS_DEF.mof and Configuration.mof.

SMS_DEF.mof defines “reporting” classes. These classes exist (or are created by ConfigMgr) in the WMI namespace root\CIMV2\SMS and specify where the actual data we are interested in is stored. It does this by creating classes in this namespace that are (nearly) identical in definition to the class that holds or provides the real data; a.k.a., the data classes. Here’s an example snippet of a reporting class from SMS_DEF.mof:

[ SMS_Report     (TRUE),
  SMS_Group_Name ("Computer System"),
  SMS_Class_ID   ("MICROSOFT|COMPUTER_SYSTEM|1.0") ]

class Win32_ComputerSystem : SMS_Class_Template
{
    [SMS_Report (FALSE)     ]
        uint16     AdminPasswordStatus;
    [SMS_Report (FALSE)     ]
        boolean    AutomaticResetBootOption;
    [SMS_Report (FALSE)     ]
        boolean    AutomaticResetCapability;
    [SMS_Report (FALSE)     ]
        uint16     BootOptionOnLimit;
    [SMS_Report (FALSE)     ]
        uint16     BootOptionOnWatchDog;
    [SMS_Report (FALSE)     ]
        boolean    BootROMSupported;
    [SMS_Report (FALSE)     ]
        string     BootupState;
    [SMS_Report (FALSE)     ]
        string     Caption;
    [SMS_Report (FALSE)     ]
        uint16     ChassisBootupState;
    [SMS_Report (TRUE)      ]
        sint16     CurrentTimeZone;

ConfigMgr matches up the names of the reporting classes to the names of data classes and then sucks out the data from the data classes. The above snippet instructs ConfigMgr to pull data from the Win32_ComputerSystem data class. The boolean value of a special qualifier, SMS_REPORT, on a reporting class and its properties tells ConfigMgr which classes and properties to actually inventory. SMS_DEF.mof by default, defines a large number of reporting classes and their properties that ConfigMgr takes no action on. If you decide that you want that information, just flip the SMS_REPORT qualifier from FALSE to TRUE. That change will go out during the next policy interval and the clients will report the info during their next hardware inventory cycle.

The SMS_DEF.mof file is converted into policies by the site and distributed to clients as part of the policy distribution process. The SMS_DEF.mof file is not distributed to clients in its raw form. Also note that no data is normally stored using the reporting classes. These classes are simply “road-signs” telling ConfigMgr which data classes to pull data from.

Configuration.mof is new to ConfigMgr and splits out the definition of data classes from the reporting classes.  Data classes are usually located in root\CIMV2. Most data classes used by ConfigMgr by default already exist in the repository because they are just default Windows WMI classes. Thus, there is no definition for the majority of data classes in Configuration.mof – they already exist. It is also worth noting that “data class” is a ConfigMgr only term that refers to the WMI classes that ConfigMgr pulls data from. There’s nothing inherently special or particular to ConfigMgr about these classes; they are normal WMI classes available to anyone or thing that queries WMI.

In contrast to SMS_DEF.mof, the Configuration.mof is delivered in its entirety, embedded in the policy, to each client . The Configuration.mof file is then automatically compiled and added to the WMI repository using mofcomp.exe. Although Configuration.mof file is specific to ConfigMgr, as I said above, the classes it creates are not special in any way nor is the process used to create them – this is all just standard WMI configuration.

Data can be statically populated in the data classes or populated using a dynamic process – similar to object-oriented programming or database design, the classes themselves do not actually store data, rather instances of the classes store the data. The classes just define how to store the data and what it looks like. There are many dynamic methods to populate data including WMI providers, like the registry provider, or VBScripts. All of the default WMI classes (and presumably those provided by other applications) populate their own classes automatically through their own processes.

One of the takeaways from this is that if you want to extend the hardware inventory in ConfigMgr you must add a reporting class and a data class. The reporting class is always defined in SMS_DEF.mof and, to reiterate, tells ConfigMgr where the data lives that it should retrieve. The data class on the other hand, can either be defined in Configuration.mof or through any WMI extension process. Why the difference? Because remember that data classes are not in any specific to ConfigMgr, they are just WMI classes so you can create these any way that you like – ConfigMgr just sucks the data out of them as defined by the SMS_DEF.mof file.

In addition to defining the data class (either via Configuration.mof or some other process) you must also populate these classes with data – this can be done on the fly with a dynamic provider like the registry provide, a VBScript, a custom WMI provider, or any other way you want to write data into WMI.

To sum up quickly, SMS_DEF.mof defines where to collect data from in WMI via the use of reporting classes and Configuration.mof defines how the actual data is stored in WMI using data classes.

image

icontexto-webdev-social-bookmark-09  Well, I’m not sure what to make of Twitter, but I’ve finally jumped on the bandwagon anyway. You can follow me by clicking on the link in the news section or here

What I intend to do is tweet one or two links every weekday about technology that I think others would also either enjoy or find interesting or informative. I promise not to bore anyone with personal activities like taking my daughters to ballet or going to church.

With that said, let the tweeting commence.

If you try the technique below on an install of Windows Server 2003 with Service Pack 2 (sp2), it fails. I don’t remember the exact error, but it translates to the wrong required sp level. It’s simple fix though as detailed here: http://blog.stealthpuppy.com/windows/windows-2003-r2-and-integrated-service-pack-2.

Windows-Restart-128x128 I just stumbled on this today; i.e., I can’t take credit for all of it (http://develnet.blogspot.com/2008_09_01_archive.html).

It is a great way to restart a task sequence from within Windows PE preventing the lengthy hardware reboots particularly on servers. Simply kill TsmBootstrap.exe and start a new instance of TsBootShell.exe. You can kill TsmBootstrap.exe by starting the command prompt and then starting task manager by typing “taskmgr” (unfortunately, taskkill is not available by default in PE). You can then launch a new instance of TsBootShell.exe from the command prompt or the run line of task manager – do not kill the existing instance of TsBootShell as this is the main shell used by PE during OSD and killing it will cause all other processes to be closed and the system to reboot.

This mainly works if you forgot to advertise the TS properly or the TS never really kicks off properly but you are still in PE. If the TS bombed part way through, it leaves files behind that prevent a new TS from properly starting. The one time I had a chance to test this on a failure half-way through the process, it gave an error about not being able to properly read the TS environment (or something like that). In hindsight, we should have formatted the C drive from the command-prompt and tried again, but it was late on Friday we we weren’t thinking straight anymore.

The entire scenario is difficult to test as a whole, so your mileage may vary but what do you have to lose if the TS bombed anyway.

Just thought I’d document the steps taken at a recent customer engagement for deploying Windows Server 2003 with the R2 bits in the image.

 

1. Copy the entire R2 CD to your package source repository.

2. Create a standard software distribution package for the R2 source directory.

3. Create a program with the following command-line:

CMPNENTS\R2\setup2.exe /q /a /sr

The command line options are documented at http://technet.microsoft.com/en-us/library/cc756937(WS.10).aspx.

4. In your build and capture task sequence, create an Install Software task for this new program at the beginning of your other software install tasks. Make sure you add a reboot somewhere after this task and before the capture.

5. To suppress the “Windows Server Post-Setup Security Updates” window, add a command line task near the end of the deployment TS with the following command:

reg addHKLM\SOFTWARE\Microsoft\Windows\Current Version\ServerOOBE\SecurityOOBE” /v DontLaunchSecurityOOBE /t REG_DWORD /d 1 /f

This registry key is documented at http://technet.microsoft.com/en-us/library/cc757061(WS.10).aspx.

That’s it.

An oft troublesome “feature” of WDS is the PXE cache. This feature rears its head during OSD troubleshooting and testing and results in PXE boot aborted messages. Essentially, WDS lookups of systems in ConfigMgr are cached by WDS so that it doesn’t have to repeatedly query the database; items persist in the cache for 60 minutes by default. The known way to work around this issue is to adjust the timeout value of the cache in the registry at HKLM\Software\Microsoft\SMS\PXE\CacheExpire. By default, this value is 3600 seconds and reducing this value to something much lower, like 300 seconds should help during testing and troubleshooting scenarios.

Microsoft just release a new patch to address this issue: Operating system deployment fails in a System Center Configuration Manager 2007 SP1 environment if you deploy a different operating system to a client within one hour of a previous deployment (969113). Its not clear from the KB how the patch addresses this issue though, so I suggest downloading it to a test system and testing it out. When I do, I’ll post a follow-up.

A couple of minor fixes and the new release is ready: http://osdappchooser.codeplex.com.

 

2.0.0.3b

· Added graceful handling of comments in the XML configuration file

· Removed dependence on oledlg.dll

· Made the window appear on top of all others including the TS progress bar

 

OSDAppChooser2

hyper-v-logo At a client recently installing Virtual Machine Manager (VMM) we ran into a small annoyance. Because of the many Hyper-V patches available, not all of the Hyper-V systems that we wanted to manage with VMM matched in patch level and thus version level; the complete list of patches is available at: http://technet.microsoft.com/en-us/library/dd430893.aspx. The real annoyance wasn’t the patches themselves, it was figuring out the version each Hyper-V instance was at. I couldn’t find a good place in the Hyper-V GUI to tell me so it was off to my favorite search engine. From there I determined that the authoritative version number for Hyper-V is the file version of vmms.exe located in %systemroot%\system32. With that and a little WMI “magic”, I came up with thissinle command to run from the command-line:

 

wmic /node:"vmh-c01", "vmh-c02", "vmh-c03", "vmh-c04" datafile where name="c:\\windows\\system32\\vmms.exe" get CSName, version

 

This single line queried the file version of the vmms.exe executable on all four Hyper-V nodes using WMI and quickly returned the result. One gotcha was the syntax of the /node option for WMIC; it took me several minutes to get that perfect because initially, without each system name individually quoted, WMIC saw the dashes in the system names as additional, non-valid parameters resulting in an “Invalid Global Switch” error. Lumping them all together in a single set of quotes resulted in the same error.

with no comments
Filed under:

After many hours, the completely rewritten OSDAppChooser is ready for beta release. There have been a lot of changes but the purpose remains the same: to provide an interactive way to choose applications for installation during an OSD task sequence. Everything is posted on CodePlex: http://osdappchooser.codeplex.com. Please post any comments, requests, feedback, etc. on the discussion page there. Also, make sure you read through the documentation: there are quite a few new things to be aware of.

OSDAppChooser2

image001

As I've described in the previous two installments, the KMS is a pretty simple and straight-forward service. When you think about, this makes sense because the only thing that it does is activate clients.

So how do you track what the KMS is doing and identify any issues? The first way is a vbscript located in %systemroot%\system32 named slmgr.vbs. This little script is the main way to interact with the KMS and the activation client. Running this script with –dli as an option will list the activation information for the local system; if the local system is a KMS, then will also list KMS related data including the number of clients that it has activated in total. Remember that this number is important because Vista clients won’t activate unless the KMS has already activated at least 25 clients and Server 2008 clients won’t activate unless 5 other systems have already been activated. The following screenshot shows the output of slmgr –dli on a KMS:

image

Of note are the following:

VOLUME_KMS_C_channel – The type of license key that was used to activate the system. For a KMS, this also indicates what type of clients it can activate, see Windows Activation – The KMS for details.

License Status – Indicates whether the local system has been activate or not.

Current Count – The number of client systems already activated.

DNS publishing enabled – Indicates whether this KMS system is publishing its SRV record in DNS.

slmgr –dlv displays the same basic information with some extra thrown in. This in shown in the next screenshot:

image

The two above commands also work on clients and show the same information minus the KMS specific items.

Both the KMS server and client add event log entries to track activations and activation requests. For the KMS server, there is a dedicated log view called Key Management Service located under Application and Services LOGs in the Event Viewer:

image

The KMS will add an entry to this log every time it receives a request for activation. They will look like the following:

image

The first field in the info section (marked by the red arrow), is the success/failure code; 0x0 is success.

For clients, two events will be placed into the standard Application Event Log with EventIDs of 12288 and 12289 and provider name of Microsoft-Windows-Security-Licensing-SLC. 12288 indicates a client request and which KMS server the request is being sent to (blacked out):

image

12289 indicates a reply from the KMS, the success/failure code (marked by the red arrow below) is the first field in the info section and is the same code listed by the event entry on the server side:

image

There are a handful of common error codes, the full list is available in the Volume Activation 2.0 Operations Guide in Appendix 2.

That’s the bulk of it. Like I said at the start, its a simple service that does only one thing: activate clients.

with no comments
Filed under: ,

A Key Management Server system is any system in your environment that you installed using a KMS key. That’s right, any system, Vista included. I have been to customers large and small who had five, ten, and more KMSs running their environment. Yikes. As I stated in part one (Windows Activation: The Basics), don’t use a KMS key unless you know what you’re doing.

KMSs respond to requests by Windows Vista and 2008 systems for activation (Windows 7 in the near future also). Unlike previous versions of Windows, all Vista and 2008 systems must be activated. Volume licensed systems have the option to be activated by an in-house KMS. These volume licensed systems locate a KMS using DNS and SRV records as described in part one of this post.

Each KMS maintains an internal counter of how many clients it has activated. The value of this counter is returned to each client when it tries to activate against a KMS. Vista clients will only activate if this value is 25 or over. Server 2008 systems will only activate if this value is five or over. The KMS does not increment the counter over 50. KMSs do not coordinate with each other, they are stand-alone systems. Thus, it is important that you design your KMS activation scheme carefully. Having multiple KMSes in an environment could prevent systems from being properly activated.

Each client that attempts activation is assigned a unique value that is tracked by both the client and the KMS. Activated clients, by default, attempt to contact the KMS every seven days; if an activated client cannot contact the KMS within 180 days, it will deactivate. Similarly, the KMS server will remove the record of an activated system if it has not heard from that system within 180 days; this may drop the number of activated systems below the five or 25 threshold causing other systems to deactivate when they next contact the KMS because the minimum activation number has not been met.

When a system contacts a KMS for activation, it also passes its product key to the KMS. The KMS validates the product key before it generates a client ID and successfully adds the client to its list of systems. The product key passed must be a valid KMS client key. Don’t confuse KMS client keys with KMS keys. KMS client keys are the generic keys that I referred to in the first part of this post. These keys will not activate against the Redmond servers and are automatically installed on volume license products. KMS client keys are freely distributable and available from Microsoft in the Volume Activation 2.0 Deployment Guide: there is only one client KMS per product for use by everyone; i.e., each organization does not get their own KMS client keys. Thus, if you’ve installed any other key on a system that you want to activate against a KMS, you must first remove the other key and install a KMS client key.

There are also four different levels of KMS server keys: client, A, B, and C. Each level dictates which editions of Windows that the KMS can activate. There is no limitation on which edition can host a KMS regardless of which key group the key is from. You should install the KMS key for the highest level of product that you are licensed for. The key groups are detailed in the following table:

Volume Product Key Group

KMS Key Type

Windows Editions

Client VOLUME_KMSCLIENT

Windows Vista Business

Windows Vista Enterprise

A VOLUME_KMS_A

Windows Web Server 2008

Editions listed in the Client Key Group

B VOLUME_KMS_B

Windows Server 2008 Standard

Windows Server 2008 Standard without Hyper-V

Windows Server 2008 Enterprise

Windows Server 2008 Enterprise without Hyper-V

Editions listed in the A Key Group

C VOLUME_KMS_C

Windows Server 2008 Datacenter

Windows Server 2008 Datacenter without Hyper-V

Windows Server 2008 for Itanium-Based Systems

Editions listed in the B Key Group

KMS is a very low overhead service that is hosted by the Software Licensing service. The general recommendation is to use a core services system such as a domain controller to also be your KMS system. Because systems do not immediately deactivate if they cannot contact a KMS, high-availability and redundancy are almost non-existant concerns. In the event of a failure of the KMS system, simply set up a new one.

That’s it; it really is that simple. There are always more details, but that covers most of it.

Drawing1

Windows Activation, to some, has become confusing and a source of constant trouble. Why? Because they didn’t read the documentation. Gone are the days of simply inserting a CD or DVD and installing a Microsoft product. The single biggest source of confusion is the existence of two types of activation keys: KMS and MAK.

KMS stands for Key Management Service and is used to install a system hosting the KMS. A system hosting KMS activates other systems in your environment that have not yet been activated. These un-activated systems find the KMS system by looking for an SRV DNS record named _VLMCS._TCP.

KMS keys can be used on either Vista or Server 2008 systems. Once you activate a system with a KMS key, it becomes a KMS server. You do not have to install any additional roles or features to accomplish this, it is all built-in. The system will, by default, automatically register the proper DNS record automatically. The bottom line here is that if the system is not supposed to be a KMS, do not use a KMS key to activate it.

Once, the KMS is itself activated using a KMS key, it will in turn activate other systems without any further communication with Microsoft. Systems that activate against a KMS do not need to have a product key explicitly installed; a generic key is used during Windows installation. This key is stored in a file called pid.txt in the source folder on the installation media and can only be used to activate a system against a KMS. You can also get these keys for Windows editions eligible to be activated by a KMS from the Volume Activation 2.0 Deployment Guide if necessary. Note that only Vista Business and Vista Enterprise can activate against a KMS in addition to all versions and editions of Server 2008.

KMS systems do not relay their database or specific activation details to Redmond. This is not a way for Microsoft to spy on you and your organization. KMS is designed to prevent piracy of corporate keys which was very rampant with Windows XP and Server 2003. KMS is also designed  to make it very easy to activate Windows in a corporate environment: you never actually have to distribute any keys anymore once you have a KMS up and running. If you are worried about rogue installations of Windows, simply disable the automatic publishing of the DNS record. You will have to point each system manually at the KMS system for activation, but this is far simpler than having to give out and maintain keys.

MAK stands for Multiple Activation Key and is used to activate individual systems when a KMS is not feasible or accessible. Systems where an MAK is used for activation contact Redmond to activate. Each MAK can only be used a set number of times before it will not allow any more systems to be activated with it. The number of times an MAK can be used is set by the licensing folks at Microsoft and can be extended with a phone call to them.

In general, in corporate environments, MAK keys should only be used by systems that are not directly attached to the corporate network regularly; e.g., remote user’s laptops.

If you are using a KMS key on every one of your systems, stop the insanity now. KMS keys, like MAK keys, can only be activated a set number of times. You will eventually max this number out and be left in the cold. Of course you will be able to call the licensing folks at Microsoft to try to extend this, but they will probably laugh at you and ask why you didn’t read the documentation.

The following diagram shows the activation paths for the various key types used.

image Part 2 of this post will cover how a KMS works and its limitations and Part 3 will cover troubleshooting KMS.

imageNo, I am not anti-Configuration Manager, quite the opposite in fact. I am against the use of the acronym SCCM for Configuration Manager. If you do a web search on SCCM you will see that although Configuration Manager does come up, it does not come up first. This is mainly because SCCM is not a registered trademark of Microsoft’s and in no official documentation does Microsoft ever refer to Configuration Manager as SCCM – the official acronym is ConfigMgr.  Yes, you will see a lot of blogs from Microsofties and others alike throwing this acronym around willy-nilly, but their use of it is just that: willy-nilly.

Note that Operations Manager is not SCOM for similar reasons. Check out this post for all the official acronyms: http://blogs.technet.com/configmgr/archive/2008/06/01/sccm-is-not-the-official-acronym-for-configuration-manager.aspx.

If you have mistakenly used this acronym in the past, repent now, never use it again, and be redeemed. You have been warned!

A problem that crops up on the forums every now and then in addition to causing me to pull out some hair is deploying updates during a Build and Capture Task Sequence (TS). There are actually two problems that manifest themselves during a Build and Capture that don’t normally occur and both are caused because the client system is not part of the domain during the TS. The first problem is that the client cannot find the MP to initiate policy download to figure out which deployments are applicable to it. The second problem is that the client isn’t part of any boundaries and so can’t find a DP to download the updates from – I think this second problem only happens if you are using AD sites for boundaries, but I haven’t done any testing to confirm this. The first problem results in timeout errors with the error code 0x800705b4. The second problem results in no content found errors with a seemingly unrelated 0x80040669 error code.

The solution to both of these problems is not to join the system to the domain during the TS, this would cause other issues.

For the first problem, simply add SMSMP=<ConfigMgr MP FQDN> and SMSLP=<ConfigMgr SLP FQDN> (this of course assumes that you have an SLP set up) to the client Installation properties in the Setup windows and ConfigMgr task.

image

For the second problem, change the Download Settings for the applicable deployment to Download software updates from distribution point and install for When a client is connected within a slow or unreliable network boundary.

image

lazy_drooler Well, I’m not actually that old, but I did learn a new trick today. I’ve been fighting the drivers is an OSD XP deployment task sequence for an HP dc5800. The drivers just wouldn’t load. The TS copied them down to the system properly, the DriverPaths registry value was updated properly, but the drivers wouldn’t load. After the TS completed, I could go into device manager and point the unknown devices to the folders on the C drive (C:\Drivers) and the drivers would load without any issue, they just weren’t getting automatically installed during mini-setup.

Checking the setupapi.log didn’t reveal anything except that the OS tried to find drivers for the devices but just didn’t load the ones in C:\Drivers. I tried everything that I could think of including deleting all the drivers and re-adding them to ConfigMgr, rebuilding the image, using different drivers, creating new TSes, and still nothing. I’ve implemented OSD in production environments more than a handful of times and in test environments at least as many times but had not seen this at all before: this had me really scratching my head. The problem did not appear to be with ConfigMgr though as it was definitely copying the drivers to destination system; XP mini-setup just refused to reference them, or see them, or I have no idea.

A quick web search turned up this older post: SCCM 2007 OSD Drivers Show as New Hardware Found when you Login by Brian Tucker. It was worth a shot as I was at a complete loss. Basically, I added a new command-line task near the end of the TS that runs the following command: rundll32.exe Syssetup.dll,UpdatePnpDeviceDrivers. This command reruns the PNP device setup and, from what I’ve read, is also executed during XP mini-setup.

This did fix the issue, but I still don’t really know what’s causing it. I don’t know of anything different in the image or the process as a whole. I haven’t done XP using OSD on a dc5800 before so this is the only thing I can think of that is different; I’ve done Vista on a dc5800 without any issues though. I still think ConfigMgr rocks!

One of my few non-technical posts (ever). I’ve just wrapped up my contribution (3 chapters) to Configuration Manager Unleashed by SAMS publishing; look for it soon. I’ll be presenting a quick presentation at the upcoming System Center Virtual User Group scheduled for 19 March on Desired Configuration Management. I’ll also be presenting at MMS 2009 and TechEd and 2009 in LA. If I survive all of that, I’ll be one happy camper.

Now that my book writing is done (for now), I’ll also be posting a lot more technical content on this blog.

While answering a forum post I was reminded that SQL Reporting Services 2008 no longer requires IIS (see http://blogs.technet.com/andrew/archive/2007/12/04/sql-server-2008-reporting-services-no-longer-depends-on-iis.aspx for a good post on this). Thus, when rebuilding my ConfigMgr lab recently, I decided to use SQL 08 and SSRS 08 on Windows Server 08. The only notable thing, IMO, is that the configuration tool for SSRS 08 is a little more straight-forward and gives better explanations than the one in SSRS 05. They are actually very similar, so maybe it’s just because I’m used to the one in 05 now, but the first time I opened the one in 05, I had no idea what to do.

In the end, everything went as expected. SSRS installed fine (no IIS), the SRS Reporting Point installed without a hitch, the reports transferred quickly, and most importantly, all the reports worked – at least the ones I tested. Now granted, this is my home lab, but I didn’t see anything that should cause anyone any issues. Also note that the Windows firewall is enabled on all of my systems – SQL Server, ConfigMgr Site Server, Domain Controller, and clients; I actually force it to be on using a GPO. So, anyone who thinks that they need to turn it off, needs to reevaluate (maybe another post on that is in order).

As a discovery exercise, I created a small, stand-alone app using AutoIT that displays a dialog box with the current value of the environment variables USERNAME and USERDOMAIN, and then waits for the OK button to be pushed. I then added this app to a ConfigMgr package and called it using a command-line task in various places in a task sequence. Here are the results using just a basic deployment task sequence:

Before PE

Launching the application via a TS advertisement before the initial reboot into PE stopped the whole TS flat. The message box was launched as the local SYSTEM on a different window station and thus wasn’t shown on the current users desktop. My only option was to kill it using Task Manager which caused the whole TS to fail because a failure code is sent back to the TS.

image image 

After PE, Before Image deployment

In this one, the app launched as the local SYSTEM and showed up on the PE desktop fine. The TS waited for me to click OK before going on.

image  image

After Image Copy, Before Mini-setup/OOBE

Not surprisingly, this step resulted in the same thing as the last one as we are are still in PE and nothing has changed.

image image

After Mini-setup/OOBE

This is the last one I tested and gave weird results. At this point in the TS, we’re actually in the OS deployed and not PE. The message box appeared just fine, but the environment variables I was keying on didn’t exist (I confirmed this by pressing F8 and reviewing the output of the set command). I’m assuming this is still the local SYSTEM account, but my current method doesn’t prove that one way or another; I need to find a new way to check for the user context and re-run this step of the test.

image image

Next Step

The next step is to test these same variables when running the app using a Software Install task and maybe to find a better way to report the current user context. All that in a future post.

I’ve updated my OSDAppChooser app to include a requested feature. Basically, someone requested the ability to have all applications chosen to be installed by default instead of no applications chosen. Thus below are the changes. Installation and usage instructions have not changed so please refer to the original post for those: OSD Application Chooser.

Added features:

  • Global Applications: These applications are added to the list of every application set. Use a GlobalApps tag to enclose them in the XML configuration file.
  • Select All Applications: Select all applications in a chosen Application Set. A new property of the OSDAppChooser top tag was added to configure this option: selectAll.
  • Select Specific Applications: A new property was added to each App tag: select. This controls whether or not it is selected for installation by default or not.

The example configuration file included in the new zip has examples of all of these.

I’m going to add the ability to have mandatory applications also but I can;t find a good way to represent them in the GUI. The best way would be to add the items to the list view but disable them, alas, the Windows built-in list view control does not have this ability so I need to explore other ways to show them. This isn’t a critical feature because it can be accomplished directly in a TS, but I think it does add value and have some benefits over putting it directly in a TS.

Today, I visited a customer that I had installed an evaluation version of Configuration Manager at. 120 days passed a couple of weeks ago and now it was time to convert the evaluation into a full version.

Simple process really, insert CD, run upgrade … watch LUN on iSCSI storage array hosting the dynamically expanding VHDs fill up and cause the VM to stop cold. Hyper-V saves the state of the VM and marks it as critical, so no big deal, we just expanded the LUN. Unfortunately, in the process, the VM got powered off.

So, after expanding the LUN, we restarted the upgrade. Everything looked good -- i stress “looked”. I created a new package, pushed it out to a test machine, and went to lunch. When we came back, the package deployed successfully, but I didn’t have any status for the new advertisement. Something was definitely wrong.

The compmon.log had the following over and over:

Can not get the current execution state for component SMS_SOFTWARE_INVENTORY_PROCESSOR since it is not installed or completed installing.

Can not get the current execution state for component SMS_INBOX_MONITOR since it is not installed or completed installing.

Can not get the current execution state for component SMS_DISCOVERY_DATA_MANAGER since it is not installed or completed installing.

Can not get the current execution state for component SMS_STATE_SYSTEM since it is not installed or completed installing.

Can not get the current execution state for component SMS_LAN_SENDER since it is not installed or completed installing.

Can not get the current execution state for component SMS_INVENTORY_DATA_LOADER since it is not installed or completed installing.

Can not get the current execution state for component SMS_WSUS_SYNC_MANAGER since it is not installed or completed installing.

Can not get the current execution state for component SMS_MP_FILE_DISPATCH_MANAGER since it is not installed or completed installing.

Can not get the current execution state for component SMS_SOFTWARE_METERING_PROCESSOR since it is not installed or completed installing.

Can not get the current execution state for component SMS_SCHEDULER since it is not installed or completed installing.  

Can not get the current execution state for component SMS_STATUS_MANAGER since it is not installed or completed installing.

Not good. First, I tried a site reset, no change. Then I tried the upgrade again, same thing. Time for more log spelunking.

The sitecomp.log had the following message for each of the above components:

Installed service SMS_SERVER_BOOTSTRAP_SPFM-CM-01.

Starting service SMS_SERVER_BOOTSTRAP_SPFM-CM-01 with command-line arguments "SPF C:\Program Files (x86)\Microsoft Configuration Manager /deinstall C:\Program Files (x86)\Microsoft Configuration Manager\bin\i386\perfsetup.exe SMS_WSUS_SYNC_MANAGER"...

Execution of "C:\Program Files (x86)\Microsoft Configuration Manager\bin\i386\perfsetup.exe /deinstall /siteserver:SPFM-CM-01" on server SPFM-CM-01 failed: Child process exited with non-zero code 1000.

Bootstrap operation failed.

Deinstalled service SMS_SERVER_BOOTSTRAP_SPFM-CM-01.

Bootstrap operations aborted.

Reinstallation failed and will be retried in the next polling cycle.

Web searches at this point turned up nothing in particular. I did find a KB with a hotfix that was a stab in the dark: 954214. No change after installation.

I had looked through the Windows Application event log a few times before but didn’t act on anything there. I tried running the command line given in the sitecomp.log file manually and noticed that it created errors in the App log, so now it was time to look at them. The errors cam in pairs:

LoadPerf 3011: Unloading the performance counter strings for service SMS_LAN_SENDER (SMS_LAN_SENDER) failed. The first DWORD in the Data section contains the error code.

LoadPerf 3012: The performance strings in the Performance registry value is corrupted when process Performance extension counter provider. The BaseIndex value from the Performance registry is the first DWORD in the Data section, LastCounter value is the second DWORD in the Data section, and LastHelp value is the third DWORD in the Data section.

Aside from the confusing English of these messages, I might have my culprit, corrupt performance data. Why this would cause the issue, I have no idea. I also checked PerfSetup.log and noticed the following, similar, errors.

Error: UnloadPerfCounterTextStrings failed with command line 'Application SMS_LAN_SENDER' to unload performance counters; error = 1010 (0x3f2).

After a couple of web searches on LoadPerf 3011, i found the following command that resets performance counter data:

lodctr /r: c:\windows\system32\perfstringbackup.ini

Amazingly, this worked and now all is good and right with Configuration Manager (again). I have no idea why corrupt performance counter data should cause such issues, but it did.

Microsoft just released a new hotfix that allows you to suppress the plug and play UI in Windows XP and Server 2003: http://support.microsoft.com/kb/938596. I haven’t played with it yet, but it sounds like it has potential when deploying new systems using ConfigMgr or MDT. Sometimes, there’s that one device you either don’t care about or can’t find a driver for that just pops up over and over again but doesn't change anything on the system. Or, if your users don’t have local admin privileges (which they shouldn’t), if a new device is available on the system, you can now hide the UI. Not sure of all the useful scenarios, but definitely some potential.

with no comments
Filed under: ,

A new feature of Configuration Manager 2007 R2 is the ability to define a Task Sequence Variable on a Collection or individual resource without a value. Then when the Task Sequence initiates on a system, a dialog box is presented where you can set the value of the variable. A quick example is in order to demonstrate this:

  1. Create a TS. Use the intended variable in a conditional or in any other way that variables can be used. For this example, I simply set a condition on the install of XML Notepad: it will only be installed if the TS variable InstallXMLNotepad is set to Yes.

    image image
  2. Advertise it to a collection.
  3. Set the InstallXMLNotepad variable on the targeted collection but do not defined a value; i.e., leave it blank. To set a variable on a collection, right-click it and choose Modify Collection Settings. The second tab, named Collection Variables, allows you to manage the variables for the collection.

    image
  4. Launch the Task Sequence on a resource in that collection.
  5. Before any tasks are launched, you will be presented with the following dialog box:

    image 
  6. Double-click on the variable whose value you want to set (if you have more than one variable with a blank value, they will all be shown in the list box).

    image
  7. Type in the value and press OK.

That’s it. The variable is now set and will be used in the conditional we set in step 1. The major shortcoming is in plain user friendliness: the raw variable name is presented to the user without any type of prompt and you cannot constrain or validate the value entered in any way. But, if your process is well defined and documented, these shortcomings are relatively small.

Note that if you truly want the user running your task sequence to choose software to install, as the above simplistic example shows, check out my OSD Application Chooser. For more complex tasks, using blank task sequence variables may be just the trick though.

At the last three Configuration Manager Deployments that I’ve done, the customers have each asked the same question about OSD: is there a way to interactively choose applications to install at deployment time. Tired of saying no, I built the following small, yet hopefully flexible application appropriately titled the “OSD Application Chooser”.

What is it:

A small application that allows applications to be interactively chosen at deployment time during an OSD Task Sequence.

How to:

  1. Create an XML configuration file based on the supplied sample. The configuration file defines the following items:
    - A Timeout value. This specifies how long to wait for user input before moving on. The value is specified in number of seconds. If you specify 0, the GUI will not timeout.
    - A Task Sequence Variable. This specifies the base variable name to use for the Install Software task. This can be any valid task sequence variable name. This variable gets populated with the application choices that the user makes.
    - Application Sets. These are sets of applications that the user can choose from. Each AppSet is displayed in the combo-box at the top of the GUI. When the user changes the AppSet the set of applications shown in the list box changes. Users may only choose applications from one AppSet. If you set the task sequence variable OSDAppSet to one of the defined AppSets, only that AppSet is displayed to the user and the combo box is disabled.
    -Applications. These are the actual applications that you select during the deployment. Each Application is part of an AppSet. You must specify the package ID and program name for each Application. Make sure that the programs specified have the Allow this program to be installed from the Install Software task sequence without being advertised check box on.

    image
  2. Put OSDAppChooser.exe and OSDAppChooser.xml into a software distribution package and install it onto the appropriate distribution points; no programs are necessary.

    image
  3. Insert a command-line task in your task sequence with OSDAppChooser.exe specified as the command-line. If your task sequence is configured to download all source files first, this task must come after the partition and format task if you are deploying to a bare-metal system. Otherwise, you can place the task anywhere.

     image
  4. Insert an Install Software task into the Task Sequence after the command-line task that you just created, preferably near the end; follow the example of the built-in task sequence types. Set the base variable name to the one you configured in the configuration file.

    image
  5. Deploy your Task Sequence.

    image

Troubleshooting:

A log file named OSDAppChooser.log is placed in the same directory as the SMSTS.log file and is formatted the same as other ConfigMgr log files. You can also run OSDAppChooser.exe outside of ConfigMgr to test your configuration file. In this case, a log file will be created in %temp%.

Download:

This zip file contains the executable (OSDAppChooser.exe), a sample xml configuration file (OSDAppChooser.xml), and the two AutoIt v3 source files.

The ConfigMgr Prerequisite checker typically does a good job of making sure that everything is in place for an installation of ConfigMgr. It also usually does a good job of telling why a check failed. Unfortunately, this week I started an implementation at a client and ran into the following results:

image

The double whammy, both “SQL Server sysadmin rights” and “SMS Provider Communication”.

I chased after just about everything including SPNs, kerberos, name resolution, account permissions, UAC, and more. I ended up creating a near replica of the environment in my home lab to experiment and test a working theory.  Here’s a quick run-down of the environment:

  • Windows 2003 Active Directory Domain
  • Windows 2003, 4 node, SQL Server 2005 Cluster
    • Non-default Instance of SQL
  • Windows 2008 Primary Site Server

After trying endless permutations with varying, seemingly inconsistent results, I finally realized that the prerequisite checker was being blocked by the Windows 2008 firewall. Once I realized that, and was able to consistently reproduce the behavior, it was easy to figure out why:

  • By default, SQL Server listens on TCP port 1433. The non-default instance of SQL Server was not listening on 1433.
  • In order for SQL client applications to discover non-default instances of SQL or instances not listening on TCP port 1433, the SQL Browser is contacted by the SQL client.
  • The SQL Browser listens and responds on UDP port 1434.
  • Thus, the prerequisite checker (or any SQL client) contacts the SQL Browser to find the TCP port number of the non-default instance of SQL.
  • The reply, being UDP, is blocked by the Windows firewall and thus the instance is never actually found by the checker and a ripple effect occurred causing error messages that really had nothing to do with the issue at hand.

The solution is to allow UDP traffic on port 1434 from all nodes of the cluster through the Windows firewall. One interesting thing is that once a SQL client finds the port number for an instance of SQL, it caches this and no longer needs to rely on the SQL Browser to find the instance.

One big take away for me is to always temporarily disable the firewall when troubleshooting any type of potential communication issue. I stress temporarily because the firewall is a good thing. If you determine that the firewall is indeed blocking traffic, the next step is to figure out what holes to create in the firewall, re-enable it, and test again.

I recently implemented a new external DNS solution for a financial customer of mine.  They had some issues lately and wanted to replace their old external DNS servers that were running on Windows Server 2000.  Server 2008 Core was the perfect solution for this task because of its small attack surface and minimal overhead.  The trick with Core of course is getting all of the configuration done without a GUI.  I had a couple of challenges that we overcame and so I've outlined most of the steps here.  Note that all these command along with more information is documented in various places on the web, I just wanted to put it all together for this particular implementation.  Also, every command below can actually be run on non-Core installations of Windows (except for scregedit.wsf).

  1. Load Windows.  First step was of course to load Windows Server 2008 Standard in core mode.
  2. Change Name.  Changed the name of each system.

    netdom renamecomputer %computername% /NewName:NS1
  3. Add Key.  Added the customer's Multiple Activation Key (MAK).

    C:\Windows\system32>cscript slmgr.vbs -ipk <product key>
  4. Activate Windows.  Here was the first challenge.  We were building the systems inside the customer's network; however, they use a firewall based authentication process to allow or disallow all Internet bound traffic.  Authentication is usually handled by Internet Explorer (and other browsers) by prompting the user with a dialog box.  This isn't directly possible with Windows Core.  I could've load Firefox or some other Internet access software that would prompt for credentials, but given the use of these boxes, that's wasn't a good plan.  Telnet isn't loaded and I didn't want to have to load it either.  FTP was the ticket.  We simply telneted to ftp.microsoft.com and the FTP client prompted us for the credentials.

    C:\Windows\system32>cscript slmgr.vbs -ato
  5. Disable IPv6.  Not strictly necessary, but given that these were going to be IPv4 DNS only (for the time being) and in the spirit of removing or disabling things not necessary to reduce the attack surface, this makes sense.

    Using regedit (yes regedit exists in Core), added the following registry value (DWORD type) set to 0xFF:
  6. HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\Tcpip6\Parameters\DisabledComponents

  7. Disable NIC.  As with most servers these days, the system had two on-board NICs, so we disabled the one not in use.

    netsh interface set interface name="Local Area Connection 2" admin=DISABLED
  8. Enable RDP.  For remote access and configuration.

    c:\windows\system32\scregedit.wsf /CS 0
  9. Disable hibernation.  When looking around at available drive space, I noticed some missing.  Upon investigation, I found hiberfil.sys.  Not sure why hibernation would be enabled by default in core, but given that these are always on systems, this file and functionality was not needed.

    powercfg.exe /hibernate off
  10. Disable NetBIOS over TCP/IP.  Definitely no reason to leave this on.

    wmic nicconfig get caption,index,TcpipNetbiosOptions
  11. wmic nicconfig where index=1 call SetTcpipNetbios 2

  12. Create volume.  I decided to put all DNS files on a separate volume from the OS files.

    diskpart
    show disk
    select disk 1
    create partition primary
    show volume
    select volume 2
    format quick
    assign letter=E
  13. Set timezone.  Set the current timezone.

    timedate.cpl
  14. NTP.  Set the authoritative NTP time source.

    w32tm /config /update manualpeerlist:x.x.x.x /syncfromflags:MANUAL
  15. Open firewall.  Opened the Windows firewall for a few groups of rules to allow remote administration.

    netsh advfirewall firewall set rule group=”Windows Firewall Remote Management” new enable=yes
    netsh advfirewall firewall set rule group=”Windows Remote Desktop” new enable=yes
    netsh advfirewall firewall set rule group=”Windows Administration” new enable=yes
    netsh advfirewall firewall add rule name=”ICMP Allow incoming V4 echo request” protocol=icmpv4:8,any dir=in action=allow

  16. Install DNS

    OCSetup DNS-Server-Core-Role
  17. Configure DNS.  Configured the default directory for DNS to store zone files and the the default DNS log file.

    dnscmd.exe /config /logfilepath E:\DNS\Logs\Dns.log

    Used regedit to update HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\DNS\Parameters\DatabaseDirectory to E:\DNS\Zones
  18. Windows Updates.  Here's a another little challenge.  Fortunately, Windows Updates can be initiated using WMI and a handy little script from Microsoft: WUA_SearchDownloadInstall.vbs (found at http://msdn.microsoft.com/en-us/library/aa387102(VS.85).aspx)
  19. Static IP Address.  We then moved the servers into the DMZ for final preparation.  This meant assigning the final DMZ static IP addresses.

    netsh interface ipv4 set address "Local Area Connection" static x.x.x.x 255.255.255.0 x.x.x.x
    netsh interface ipv4 set dnsserver "Local Area Connection" static 127.0.0.1

  20. Create Primary Zones.  Because this was a clean swap from the current DNS servers to the new, we simply had to copy all of the zones files, about 25 of them, from the old primary to the new.  Then, using a simple batch file with a for loop, executed the following command for each zone file.  The same batch file was used to enable zone transfers on each zone.  Because of NETing, the NS records listed in the zone do not match the actual IP addresses of the secondary servers, so zone transfers had to be locked to IP addresses instead of the NS records.

    dnscmd.exe /zoneadd <zonename> /primary /file <zonename>.dns /load
    dnscmd.exe /zoneresetsecondaries <zonename> /securelist x.x.x.x z.z.z.z

  21. Create Secondary Zone.  For the secondary zones, a similar batch script was used with the following command.

    dnscmd.exe /zoneadd <zonename> /secondary y.y.y.y
with no comments
Filed under:
More Posts Next page »