USMT 4.0 and Custom Exclusion Troubleshooting

Ned here again. Because Windows XP cannot be in-place upgraded to Windows 7 and because XP has ruled supreme for longer than most IT staffers’ careers, everyone who managed to avoid USMT are now coming out of the woodwork. Perhaps the most asked question is “I am trying to block X from being migrated to the new computer but it always comes over anyway: what step am I missing?

USMT 4.0 is incredibly flexible and powerful, to the point where its complexity can make tasks tricky. Exclusions are a case in point, and today I’ll go through the three common mistakes that prevent exclusions from working.

Consider the case of the frmcache that wouldn’t die. The frmcache.dat file is the part of Microsoft Outlook that stores forms and apparently is rather fragile. One of our customers found that a third party application had modified the frmcache and the cache no longer worked when opened by a later version of Outlook. Since the customer was migrating to new computers running Outlook 2007, they just wanted to block the frmcache.dat from migrating and let Outlook create a fresh one automagically. They created a custom XML file with an exclude rule.

Except that it didn’t work; the file kept migrating. They suspected – correctly – that USMT was still migrating the file because their custom rule was wrong. After a brief dig, they found it being migrated by the migapp.xml. For good reason they didn’t want to modify that included XML file directly. Why wasn’t the custom XML file working and how could you run into the same exact issue?

Common cause 1: Your XML uses exclude and not unconditionalExclude

The rules around USMT conflict and precedence handling are complex and often subtle – read more here if you want a cure for insomnia. Generally speaking, though, if you have some reason to specifically exclude a file or a registry setting there is no circumstance where you ever want it to get included. This means you should use <unconditionalExclude> in your custom XML. This special rule ignores any precedence or inclusion conflicts.

Here is a sample rule that will absolutely not, no matter what, allow any MP3 files to be migrated to a new destination computer.

<?xml version="1.0" encoding="utf-8" ?>
<migration urlid="https://www.microsoft.com/migration/1.0/migxmlext/excludefiles">
<component context="UserAndSystem" type="Documents">
  <displayName>NedSample</displayName>
  <role role="Data">
    <rules>
      <unconditionalExclude>
        <objectSet>
          <script>MigXmlHelper.GenerateDrivePatterns ("* [*.mp3]", "Fixed")</script>
        </objectSet>
      </unconditionalExclude>
    </rules>
  </role>
</component>
</migration>

Obviously, you need to be very careful about unconditional excludes – setting it for .DOC* files will not endear you to users. Exclusions should strive have as specific a path as possible, unless you know without a doubt that a file has no business being migrated. MP3’s are a good example of those to most businesses, if only for liability reasons!

Common cause 2: You have set unconditionalExclude in the wrong context

Within unconditionalExclude there is still a delineation of context for User, System and UserAndSystem. The context tag tells USMT when to care about a section of XML – if gathering a user’s profile it will use the rules for User and UserAndSystem. If gathering the system (aka computer’s) profile, it will use rules for System and UserAndSystem.

Here is a sample custom rule XML file that will prevent a specific file pattern (frmcache.dat) from being migrated from any user's local appdata profile ( %CSIDL_LOCAL_APPDATA% ) where the file exists in a specific path (MicrosoftFORMS).

<?xml version="1.0" encoding="UTF-8"?>
<migration urlid="https://www.microsoft.com/migration/1.0/migxmlext/test">
  <component type="Documents" context="User">
    <displayName>Block migrating frmcache.dat</displayName>
    <role role="Data">
      <rules>
        <unconditionalExclude>
          <objectSet>
            <pattern type="File"> %CSIDL_LOCAL_APPDATA%MicrosoftFORMS [frmcache.dat] </pattern>
          </objectSet>
        </unconditionalExclude>
      </rules>
    </role>
  </component>
</migration>

Common cause 3: You have not correctly provided the case for unconditionalExclude

Finally – and most insidiously - USMT XML tag handling is case-sensitive. This is not just for includes and excludes, so just get in the habit. If you set "unconditionalexclude" it will not work and neither will "Unconditionalexclude" or "UnconditionalExclude". But if you set "unconditionalExclude" your rule will process.

OMGXMLH8U!!!111elevenz

If you want to avoid these sorts of typo problems in the future, take a look at this previous blog post.

Until next time.

- Ned “tweener” Pyle