Archive for the ‘Configuration Manager’ Category

WMUG UK Cardinal Place Meeting

User Group meeting yesterday at Cardinal Place, Microsoft’s London Office.

Wally Mead gives us the skinny on R3 for Configuration Manager 2007, now released. Not much has changed here from the presentations we saw this time last year, but good to see this product finally out the door. Also, this is the final release for the 2007 version, no SP3 is planned.

Silect are here to demo their CP Studio product. Orinoko-er Andy Sallabank dramatically wins a copy of the product after consuming his own body weight in beans in under 12 minutes, destroying Cliff Hobbs’ attempts to take the prize with his rendition of “Mammy” on the nose flute.

CP Studio looks pretty neat, but I’m not sure any of the projects we’ve delivered recently that used DCM would warrant it. DCM is a growing field, but I reckon it’ll be vNext before we start to do anything very large-scale. So for now (freebie copy aside) we’re probably stuck with Visual Studio!

Wally gives us the ConfigMgr VNext overview. The top-line features are pretty well known in the community now, but the new stuff is still pretty exciting:

· Hierarchy reduction…

· Role Based Security

· SQL Replication for metadata

· Deployment Types

· Gold Key remote control

· DP Groups – state based distribution (essentially this balances packages across all DPs in a group)

· Client Health auto remediation (hurray) auto-fix of WMI, auto reinstallation of the ConfigMgr agent, etc. etc. Looks cool. XML based checking engine, can be modified to include custom tasks…

· Mobile Device Manager integration

· OSD gets offline image servicing and boot media is now site-wide (this is very handy as your clients can join the wrong site at the moment if you don’t control the media distribution)…

clip_image002

Wally embraces his imaginary friend, Binker. Tragically Binker was later crushed during the User Device Affinity demo.

Inventory Classes editor replaces notepad for editing SMS_DEF.MOF. Import of MOF file supported, and browsing of WMI classes from the editor to enable custom inventory.

Custom client settings being set on a per-collection level is shaping up. The ability to set separate remote control config per-collection, and to modify inventory schedules for workstations vs servers, etc.

Client remediation no longer pings machines to see if they are alive. Now integrated with AD, checks the last time the machine logged into AD.

All-in, a good day, thanks to Cliff et al for organising it once more.

USMT State Capture Failure

We’re part way through a nice little Windows 7 project, and have the New Computer scenario cooking just fine, driver management for some of the AMT stuff has been a real challenge, but once you have all the right driver versions for the right laptop models it all goes in fine. Irritatingly, some of the drivers for the AMT SOL packages are model specific, but just generate an error that your machine doesn’t meet the minimum requirements. Anyway, I digress, we’ve started on Zero Touch, and I came across an error I’ve not seen before:

The task sequence execution engine failed executing the action (Capture User State) in the group (State Capture) with the error code 2147942402
Action output: 0, HRESULT=80070002

If you are seeing this, it’s possibly because you have (again!) forgotten to update your Configuration Manager Client package when you installed SP2. At SP2 the agent should have a ConfigMgr Client Version of 4.00.6487.2000. SP1 is 1000.

Right click your agent package and update distribution points, ConfigMgr will automagically pick up the new client source.

Obviously you’ll also need to upgrade the live client…

Lets… True-Up with Configuration Manager

Using ConfigMgr we can leverage the inventory data gathered by the client agent to report on our license compliance against the MVLS report provided by Microsoft from the MVLS site.

To get your license report do the following:

  1. Log into the MVLS Site, Hover over Microsoft License Statement
  2. Select view Microsoft License Statement
  3. Click the + to bring down the Add Agreements Option and add your agreement and enrolment numbers in the field
  4. Click calculate new statement
  5. Right click on table under License Summary Tab and select Export to Microsoft Excel

Now open this file in Excel. You need to muck about with it a little bit…

Column A will be blank, delete it.

Format the License Version column (C) as TEXT.

Now Save As Excel 2003 XML format.

Copy this into a folder, shared and accessible to the SMS Provider and the user you’re logged in as.

Right click the Asset Intelligence node and select Import Software Licenses

image

image

Note, the Example text is incorrect, you need to provide the name of the xml file too.

Complete the wizard and with a fair wind you will be rewarded with a little tick:

image

In my opinion (having spent all morning getting an import failure) this should also play a little fanfare sound, but it doesn’t.

image

Looks like we need a few more Project licenses!

I Have an Enduring Love for Configuration Manager, but…

…sometimes it tests me…

We have to install SP2 for ConfigMgr before we can start our Windows 7 imaging. The customer we’re working on has SP1 deployed, the site was originally upgraded from SMS 2003. Suffice to say that the SQL database is in a bit of a mess.

Problem 1.

The installation bombs out with an error in the C:\ConfigMgrSetup.log:

The login already has an account under a different user name.

This turns out to be an issue where we have a SQL account with the NetBIOS name of the server but a login id of the full domain machine account. E.g. The SQL User Name is “SERVER” but the login ID is DOMAIN\SERVER$.

ConfigMgr attempts to add its computer account account to SQL (which is also DOMAIN\Server$) and gets the above error. Deleting the existing NetBIOS name account isn’t possible as it owns the “SMS Admins” SQL schema.

The solution is to grant another account (NETWORKSERVICE seems to work) the ownership of the SMS Admins schema, remove ownership for the NetBIOS named account, then you can delete it and once the account is re-added as DOMAIN\SERVER$ you can transfer the ownership of the SMS Admins schema back to this account.

This was, however, just the start of the problems.

Problem 2.

Error in Setup log:

Cannot create a row of size 8065 which is greater than the allowable maximum of 8060.

I still haven’t got to the bottom of this one except that compressing the database seems to make it go away… At the same time as we were having these problems, our DB was also growing by around 200MB per hour, there’s some discussion here that this may be related to a post SP2 hotfix, but I have not been able to confirm this.

Problem 3

Our database is corrupt. And unfortunately it’s in quite an important table…

Error in the setup log:

The Database ID 58, Page (1:140044), slot 20 for LOB data type node does not exist. This is usually caused by transactions that can read uncommitted data on a data page. Run DBCC CHECKTABLE.

Running DBCC Checktable tells us that the data is unrecoverable and that only running DBCC CheckDB with REPAIR_ALLOW_DATA_LOSS is going to fix it. After scrabbling around for a while without joy we ran this and it scrapped around 100 rows from the database. Unfortunately the data is in the CI_ConfigurationItems table. There’s a lot of other tables which depend on this, referential integrity issues await!

Problem 3.

Having “repaired” the database we now essentially have a bunch of orphaned items scattered around the Configuration Manager SQL database. This is a real problem as the SP2 setup routine is going to recreate all of the SQL Foreign Key links and if there’s incompatible data in the linked tables the setup routine will bomb out:

The ALTER TABLE statement conflicted with the FOREIGN KEY constraint "Update_ComplianceStatus_CI_UpdateCIs_FK". The conflict occurred in database "SMS_XXX", table "dbo.CI_UpdateCIs", column ‘CI_ID’.

The table will vary, but essentially what this is telling us is that there are records in the Update_ComplianceStatus table that do not have a corresponding record in the CI_ConfigurationItems table, because they were corrupt and have now been removed.

To identify the offending records I executed the following SQL Query

Select distinct CI_ID
From Update_ComplianceStatus
Where CI_ID not in (select CI_ID from CI_ConfigurationItems)

This results in a few records being returned which represent tens of thousands of status messages, inventory records, whatever… They need to be removed:

Delete from Update_ComplianceStatus where CI_ID = ’9420′
Delete from Update_ComplianceStatus where CI_ID = ’9644′
Delete from Update_ComplianceStatus where CI_ID = ’11666′
Delete from Update_ComplianceStatus where CI_ID = ’25041′
Delete from Update_ComplianceStatus where CI_ID = ’26261′
Delete from Update_ComplianceStatus where CI_ID = ’29627′
Delete from Update_ComplianceStatus where CI_ID = ’31677′
Delete from Update_ComplianceStatus where CI_ID = ’33272′

I created the above statements in Excel using Concatenate to add the text to the ID, I recognise that you can do the whole thing programmatically, but this way you can run them one at a time in the SQL interface:

image

I like this, as these kind of things make me a little nervous…

Once these tasks are complete I rerun setup and wait for the next failure in the log, then repeat the above. A lot.

It took EIGHT HOURS!!!!! but:

image

Now I need a pint!

Repairing Duplicate GUID issues

On site with a customer who currently have SMS 2003. We’re replacing SMS with ConfigMgr of course, so we deploy the ConfigMgr client with SMS feeding it a parameter for SMS_SLP=NEWSERVER which forces the clients to switch to our new infrastrutcure. So far so good.

Around 50% of the clients show up pretty much immediately, but around 1500 are missing. It eventually turns out that this is because these 1500 machines all had the SMS client duplicated on them in a Ghost image, and now we’ve maintained that ID through the ConfigMgr upgrade.

A bit of a nightmare.

In the past under SMS we would have just deleted the SMSCFG.INI from the Windows folder and restarted the SMS Agent Host service which would have regenerated the GUID, these days the ConfigMgr client certificates don’t much like this, so we have to be a little bit smarter about it. We have our own client installation wrapper, SMSSamurai which we use for the client deployment in the first instance. In a scenario where we know there is going to be difficulty with duplicate GUIDs, we have this wrapper generate a new GUID at install time, but in this instance the duplication was not anticipated.

The main problem now is that the machines need to be powered on to be repaired, so it’s a long slow process. I’ve messed around with trying to script this in Powershell, but there’s no WMI provider for regenerating the GUID, so I’ve fallen back on trusty old Tranguid.exe from the SMS 2003 resource kit and PSexec from Sysinternals.

I’ve created a batch file:

REM Cleaining Up Duplicate GUIDS

REM Firstly we kill off the SMS Agent Host (CCMEXEC) service on the remote machine
TASKKILL /S %1 /IM CCMEXEC.EXE

REM Next we generate a new GUID for the machine
PSEXEC \\%1 -c Tranguid.exe /R

REM Now we start the SMS Agent Service back up
SC \\%1 START CCMEXEC

I save this as DeDupe.bat , then executing dedupe.bat brokenclientmachinename will fix the duplicate GUID.

You can check the fix on the client by checking the ClientIDManagerstartup.log:

image

The batch file above restarts the SMS Agent Host service once the GUID has been renewed. This will result, a couple of minutes later, in a new heartbeat discovery (DDR) being generated. If you are feeling particularly impatient you can kick off a DDR as soon as the batch file completes.

The final piece of the jigsaw is to run the batch file against all clients. To do this we create a “Non Clients” collection (where Client=NULL)

select SMS_R_SYSTEM.ResourceID,SMS_R_SYSTEM.ResourceType,SMS_R_SYSTEM.Name,SMS_R_SYSTEM.SMSUniqueIdentifier,
SMS_R_SYSTEM.ResourceDomainORWorkgroup,SMS_R_SYSTEM.Client from SMS_R_System where SMS_R_System.Client is null

Now use View-  Export list to dump this collection to a NonClients.CSV file.

Finally, logged on as a user with admin rights on all PCs run the following:

for /f “skip=1 delims=,” %L in (NonClients.csv) do Dedupe.bat %L

It is possible to wrap this command in a ping task to check that the machine is powered on before attempting the remote commands which will speed the process up considerably.

Onsite here I’m finding that this is repairing around 200 clients per hour. That’s a little slow, so adding a ping test can improve things a bit.

for /f “skip=1 delims=,” %L in (NonClients.csv) do ping –n 1 %L && Dedupe.bat %L

The double & in this command line allows CMD.exe to process the Dedupe.bat file to execute if the ping command produces an errorcode of 0, which it does if the machine responds.

Windows 7 Reference Task Sequence Creation With ConfigMgr and MDT Integration

A customer earlier in the week had implemented ConfigMgr for their builds and was getting good results with it. They hadn’t implemented MDT as they couldn’t see the benefit, so with this series of posts I’m going to highlight why we mostly do it this way, and what benefits using MDT Task Sequences brings.

Now that SP2 for ConfigMgr is in Release Candidate (and due for RTM at the end of October according to Mr Niehaus) we can use this stuff for Windows 7 deployment.

First up, install SQL, ConfigMgr, its dependencies, and MDT 2010 RTM.

Now, integrate MDT with ConfigMgr by clicking

image

Now open the ConfigMgr console. nothing much has changed, but you have a couple of new options when you right click in the OS Deployment node. You can create MDT Boot Media clicking in boot images and you can create an MDT Task Sequence clicking in Task Sequences, let’s do that now!

image

When we do this we are prompted to pick a template. So, here’s the first benefit with MDT. More pre-configured templates:

image

The standard ConfigMgr task sequence only gives three options:

image

Further to that, the ConfigMgr standard Task Sequence expects you to have set up all of the dependent packages, boot images, etc. yourself before running through the wizard. MDT will create them for you if required…

Ok, so we pick to deploy the MDT Client Task Sequence, I can already tell that this is going to be a rambling post, but the first thing of note is that you no longer have to provide a capture destination if you’re not going to be doing a capture. Hurray, a minor irritant squashed (it’s the little things…)!

image

That said, I need to capture this build, so I fill in the box.

With the standard ConfigMgr task sequence, I’d need to select one of the pre-built boot images, but I want the goodness of ADO and other brilliant, so I get MDT to make a special one just for me:

image

The MDT asks if you want other languages, a custom wallpaper (I always make mine in PowerPoint, some of the templates make for pretty wallpapers, when there’s all this technology around there’s still no getting away from the fact that the customers like their logos on things, and why not.). On the same screen as the wallpaper, language, ADO options etc. you can also provide an extra directory to add. I put my diag tools in here (Trace32.exe etc.) they make life easier if you have problems in PE).

image

I create a Deployment Toolkit File Package. This holds all the scripts and bits that the MDT task sequence needs. Those of you still with us may notice that I put everything in a sub-folder of a root folder called OSImaging. This keeps things nice and tidy as far as I’m concerned, and is something I recommend.

image

Now MDT wants to create our OS package for us. Again under the standard ConfigMgr task sequence you’d have to do this outside of the wizard.

It also creates the ConfigMgr client package for you. Again, it’s not hard to do yourself, but why bother when the wizard can sort you out…

image

and USMT package:

image

Last thing is the MDT Settings Package. This handles the unattend.xml and customsettings.ini files.image

We don’t need Sysprep, so can skip the final screen and then we’re ready. The wizard goes off and creates all the objects listed above.

image

Once it’s finished we just need to add the packages created to distribution points (this includes the OS install, so it can take a little while). I’ve got a PXE Service Point, so I add my new boot image to that DP too.

Next we’ll deploy and capture this and then start to look at the clever stuff we can do with the MDT integration to streamline deployment and support advanced deployment scenarios.

Package Mapping in the Replace Computer Scenario

The MDT Package Mapping approach is a great bit of OS deployment technology and can help to provide an excellent deployment rate when it comes to large-scale zero touch deployment projects. One limitation that currently exists is that package mapping only works in the refresh computer scenario, i.e. I’m moving from XP to Vista, when I install my Vista image, put back the applications which I used to have.

For the Replace Computer scenario, where we’re deploying new hardware, out of the box, package mapping does nothing for us.

In the ConfigMgr Replace Computer scenario we use ConfigMgr Computer Associations to provide the capability to recover the user state (via a state migration point) from the OLDCOMPUTER to the NEWCOMPUTER during the build process. We run the Replace Computer Scenario task sequence on the OLDCOMPUTER, this captures the user state, then the NEWCOMPUTER state restore phase magically recovers this. All good stuff, but it doesn’t help us with the apps…

But it can. A small change to the PackageMapping stored procedure can use the same Computer Association record to migrate the applications across machines in the same way as we migrate the user state. It’s a shame that this isn’t integrated in the ConfigMgr console as elegantly as the Computer Associations are, but it works…

First we need to import the NEWCOMPUTER into ConfigMgr using the Import Computer Information wizard. Select the OLDCOMPUTER as the Source for the NEWCOMPUTER (obviously this can be done on a large-scale by populating a CSV file with these entries).

Next we need to modify the PackageMapping process so that it runs against the MACAddress of the OLDCOMPUTER rather than the NEWCOMPUTER.

In SQL Management Studio, browse to the PackageMapping stored procedure and select to modify it. Replace the entry shown with this text (replace SMS_JON with the name of your SMS database)

set ANSI_NULLS ON

set QUOTED_IDENTIFIER ON

go

ALTER PROCEDURE [dbo].[RetrievePackages] @MacAddress CHAR(17) AS SET NOCOUNT ON /* Select and return all the appropriate records based on OLDCOMPUTER inventory */ SELECT * FROM PackageMapping WHERE ARPName IN ( SELECT ProdID0 FROM SMS_JON.dbo.v_GS_ADD_REMOVE_PROGRAMS a, SMS_JON.dbo.v_GS_NETWORK_ADAPTER n WHERE a.ResourceID = n.ResourceID AND MACAddress0 = (select sourceMACAddresses from SMS_JON.dbo.v_statemigration where restoreMACAddresses=@MacAddress) AND n.ResourceID IN (Select ResourceID from SMS_JON.dbo.v_R_System_Valid))

A little explanation of what is happening here:

With a thorough PackageMapping database and thorough User State Migration profile and very good planning in terms of assigning the OLDCOMPUTER and NEWCOMPUTERs through Computer Associations we can achieve a near seamless and very high performance desktop replacement approach.

Package Mapping v2

The MDT Package Mapping functionality (Scenario 5: Dynamic Computer-Specific Application Installation to give it its MDT name)
provides for the automatic re-installation of ConfigMgr applications during OS re-imaging. This is done via interrogation of the ADD_REMOVE_PROGRAMS SQL view. The deployment database contains a PackageMapping database. This is used to pair an Add/Remove Program inventory entry (ARP) with a ConfigMgr package and program in this way:

The database supplied with the deployment database does not contain the Comment and ID tables shown above, but I’m finding these are pretty useful. Comments are handy as the database gets larger and the ID field is used as a primary key on the table so that we can update the database from a Microsoft Access front end.

Populating the database with new mapping entries is somewhat error-prone… The ARP entries are often GUIDs, and the Packages entry requires the package ID and exact program name. Any of these entered incorrectly results in a failed build which can be awkward to troubleshoot. The only minor complexity on this is that the ID table should be configured as IsIdentity (AutoNumber) in SQL:

To reduce the risk of incorrect entries being added I have knocked up a quick MS Access form to allow selection of the ARP name and Install Package entry. To build this all we need are a couple of ODBC entries one "PackageMapping" connected to the DEPLOYMENT database and another "ARPData" connected to the ConfigMgr database.

Now we just need some linked tables in Access.

The PackageMapping table is from the DEPLOYMENT database.

The others are SQL views from ConfigMgr

The field highlighted in red builds the MappingEntry field to
automatically populate the SQL database with the ConfigMgr Package
in the correct format (this prevents the inevitable typos when entering
packageIDs and exact program names).

This structure allows us to select the PackageID from a list of all Packages, but displays the friendly package name.

Some Minor Package Mapping Improvements

The MDT Package Mapping functionality is an excellent way of providing application migration during zero touch OS deployment. Coupled with a decent USMT configuration you can get some really good results to provide a seamless OS refresh.

We’re using Package Mapping extensively on a current Zero-Touch project and have come across some minor issues related to obsolete resource records.

For example, machine PC001 has ten applications which are in-scope for package mapping (i.e. the Add/Remove Program (ARP) entries they have are mapped to ConfigMgr packages in the MDT PackageMapping table). PC001 has a problem and is rebuilt using the legacy Ghost approach by IS support. Of the ten applications which were installed previously, only three are actually required by the user, so only these three are replaced.

A couple of months go by… We’re finally in a position to deploy our new ZTI image to PC001, the install goes fine, but ten apps are re-installed to the machine when the image is installed. Checking the ARP record in Resource Explorer for the machine previously revealed only three in-scope apps, so what’s happened?

Pretty straightforward stuff, the stored procedure used to populate the PackageMapping entries (PACKAGESxxx) in the image installation task sequence does a lookup for the ConfigMgr ResourceID using the host machine’s MAC Address; this ResourceID is then used to interrogate the ARP entries table for all apps at last hardware inventory cycle. The problem is that when the query for the ResourceID is executed, it gets two results, the one from before the machine was re-Ghosted and the new record created when the machine re-joined the infrastructure. The old record will ultimately be aged out of the database (after 90 days) but in the mean time it’s hanging around, even though the old resource has been removed from the Admin Console.

The consequence of this is that the obsolete ResourceID is used by the PackageMapping process and thus the wrong apps are re-installed to the client. The same problem occurs in the lab when re-imaging test machines; even when the test machine’s record is deleted from the admin console, its inventory data remains and will be used by the PackageMapping process.

The fix for this is to modify the MDT RetrievePackages stored procedure to validate the ResourceID against the new ConfigMgr R_System_Valid view.

To do this using SQL Server Management Studio browse to the stored procedure, right click – modify, then add the following to the end of the supplied code:

AND n.ResourceID IN (Select ResourceID from SMS_xxx.dbo.v_R_System_Valid )

Alternatively, replace the provided stored procedure by executing:

use [Deployment]

go

if exists (select * from dbo.sysobjects where id = object_id(N’[dbo].[RetrievePackages]‘) and OBJECTPROPERTY(id, N’IsProcedure’) = 1)

drop procedure [dbo].[RetrievePackages]

go

CREATE PROCEDURE [dbo].[RetrievePackages]

@MacAddress CHAR(17)

AS

SET NOCOUNT ON

/* Select and return all the appropriate records based on current inventory */

SELECT * FROM PackageMapping

WHERE ARPName IN

(

SELECT ProdID0 FROM SMS_xxx.dbo.v_GS_ADD_REMOVE_PROGRAMS a, SMS_xxx.dbo.v_GS_NETWORK_ADAPTER n

WHERE a.ResourceID = n.ResourceID AND

MACAddress0 = @MacAddress

AND n.ResourceID IN (Select ResourceID from SMS_xxx.dbo.v_R_System_Valid ))

go

Now when Package Mapping is called, only non-obsolete data will be used and everything will function as expected. This has the added advantage in a lab of allowing you to delete the resource record of a test PC from the console and have that machine return no results from Package Mapping.

Thanks to John Nelson for his help with this on MyITForum.

Modify Package Source

We’re using Kim Oppalfens’ rather wonderful approach for migrating to ConfigMgr from a large SMS 2003 implementation. We don’t want to take the SMS hardware, but we do want the investment we’ve made in the development in the console (hundreds of packages, collections and advertisements which would take us a long time to set up again).

Kim’s approach implements a new child Primary SMS 2003 server. The package, collection and advertisement content is replicated to the child. We copy the package source across to the new server, detach from the parent and the packages etc become ‘owned’ by the new SMS site. This site can then be upgraded to ConfigMgr. This is great, one slight fly in the ointment is that on the old server the packages are stored in G:\DIST_Source\Vendor\Appname and on the new server they’ll be in D:\packages\Vendor\Appname.

Once the child site has been detached, the package source must be modified. This can be done using Transact-SQL and the most efficient (in terms of code) way of doing this in SQL 2005 is using REPLACE command.

USE SMS_XXX

UPDATE SMSPackages

SET Source = REPLACE(CAST(Source AS NVARCHAR(MAX)),

‘G:\DIST_source’,

‘D:\Packages’)

Note it’s important to cast ‘Source’ as NAVCHAR as REPLACE won’t work on STRING types.

Follow

Get every new post delivered to your Inbox.