About context in MigXML

If you have written a fair amount of migration MigXML you have probably noticed that there are a number of elements that take a context parameter.  Do you understand what this parameter controls?  Do you understand the impact that it can have on your migration?  We will work through a couple of examples here to address these questions.

Before we get started, lets talk about some background info.  Although context is a parameter in a number of elements, lets focus this discussion on the impact of the context parameter in the <component> element.  This element is commonly used to encapsulate logical units of file or path based <include> and <exclude> rules.  So, as an example, if I stored a bunch of files located on the root of my C drive, I would author a single include rule that would be encapsulated in a <component> tag.

However, the context parameter accepts the following values:

  • User
  • System
  • UserAndSystem

Which one should I use?  Lets try each value and see what the result is.

To setup this experiment I made sure that my Vista SP1 machine had multiple (five) total users and I placed a single MP3 file (PowersCombine.mp3) on the root of my C drive.  So, I wrote the following MigXML to migrate the PowersCombine.mp3:

<component type="Documents" context="System">
<displayName>Component to migrate mp3 file on the c drive</displayName>
<role role="Data">
<rules>
<include>
<objectSet>
<pattern type="File">C:\ [PowersCombine.mp3]</pattern>
</objectSet>
</include>
</rules>
</role>
</component>
</migration>

and ran Scanstate including all users on the machine and the rule outlined above:

ScanState.exe /i:mp3.xml /o /c /all c:\RuleTest /v:13

After Scanstate finished running I opened up the log to take a look at how the migration went.  After a little searching I found the part that references the processing of migration rule that I wrote:

> Processing GATHER for migration unit: <System> \Component to migrate mp3 file on the c drive (CMXEAgent)
> Activity: 'MIGACTIVITY_MIGUNIT_GATHER'
> Argument 1: 'Component to migrate mp3 file on the c drive'

Next, I modified the MigXML rule such that it would operate in User context and ran the migration again.  I found the following in the Scanstate log:

> Processing GATHER for migration unit: <test2> \Component to migrate mp3 file on the c drive (CMXEAgent)
> Activity: 'MIGACTIVITY_MIGUNIT_GATHER'
> Argument 1: 'Component to migrate mp3 file on the c drive'

> Processing GATHER for migration unit: <test1> \Component to migrate mp3 file on the c drive (CMXEAgent)
> Activity: 'MIGACTIVITY_MIGUNIT_GATHER'
> Argument 1: 'Component to migrate mp3 file on the c drive'

> Processing GATHER for migration unit: <tdolan> \Component to migrate mp3 file on the c drive (CMXEAgent)
> Activity: 'MIGACTIVITY_MIGUNIT_GATHER'
> Argument 1: 'Component to migrate mp3 file on the c drive'

> Processing GATHER for migration unit: <Administrator> \Component to migrate mp3 file on the c drive (CMXEAgent)
> Activity: 'MIGACTIVITY_MIGUNIT_GATHER'
> Argument 1: 'Component to migrate mp3 file on the c drive'

> Processing GATHER for migration unit: <tjdolan> \Component to migrate mp3 file on the c drive (CMXEAgent)
> Activity: 'MIGACTIVITY_MIGUNIT_GATHER'
> Argument 1: 'Component to migrate mp3 file on the c drive'

Finally, I modified the MigXML rule such that it would operate in UserAndSystem context and ran the migration again.  I found the following in the Scanstate log:

> Processing GATHER for migration unit: <test2> \Component to migrate mp3 file on the c drive (CMXEAgent)
> Activity: 'MIGACTIVITY_MIGUNIT_GATHER'
> Argument 1: 'Component to migrate mp3 file on the c drive'

> Processing GATHER for migration unit: <test1> \Component to migrate mp3 file on the c drive (CMXEAgent)
> Activity: 'MIGACTIVITY_MIGUNIT_GATHER'
> Argument 1: 'Component to migrate mp3 file on the c drive'

> Processing GATHER for migration unit: <tdolan> \Component to migrate mp3 file on the c drive (CMXEAgent)
> Activity: 'MIGACTIVITY_MIGUNIT_GATHER'
> Argument 1: 'Component to migrate mp3 file on the c drive'

> Processing GATHER for migration unit: <Administrator> \Component to migrate mp3 file on the c drive (CMXEAgent)
> Activity: 'MIGACTIVITY_MIGUNIT_GATHER'
> Argument 1: 'Component to migrate mp3 file on the c drive'

> Processing GATHER for migration unit: <tjdolan> \Component to migrate mp3 file on the c drive (CMXEAgent)
> Activity: 'MIGACTIVITY_MIGUNIT_GATHER'
> Argument 1: 'Component to migrate mp3 file on the c drive'

> Processing GATHER for migration unit: <System> \Component to migrate mp3 file on the c drive (CMXEAgent)
> Activity: 'MIGACTIVITY_MIGUNIT_GATHER'
> Argument 1: 'Component to migrate mp3 file on the c drive'

In comparing the context that the rule ran in, and the number of times the log notes the rule was processed we can understand how the context parameter impacts a migration.  Let's break down the results for each log sample:

  1. In system context the rule was only processed only once, for the system
  2. In user context the rule was processed five times, once for each user on the system
  3. In userandsystem context the rule was processed five times, once for each user on the system and once for the system its self

Now, you may be wondering, why do we need the rule to be processed this many times?  Does the number of times the rule is processed impact the number of times the file is migrated?

To answer the easy question first, no, the number of times the rule is processed has no bearing on the number of times the file is migrated.  When processing a rule multiple times results in the same files being migrated the migration engine ensures that each files only migrates once.  Well, what about the case when processing the rule multiple times results in different files migrating?  The answer to this question actually answers the earlier question on why we might want these rules to be processed multiple times.  Lets take a look at a sample from MigUser.xml:

<!-- This component migrates My Music files -->
<component type="Documents" context="User">
<displayName _locID="miguser.mymusic">My Music</displayName>
<paths>
<path type="File">%CSIDL_MYMUSIC%</path>
</paths>
<role role="Data">
<rules>
<merge script="MigXmlHelper.DestinationPriority()">
<objectSet>
<pattern type="File">%CSIDL_MYMUSIC%\ [desktop.ini]</pattern>
</objectSet>
</merge>
</rules>
</role>
</component>

By operating in user context and using the %CISDL_MYMUSIC% environment variable this single section can migrate the My Music folder for every user on the machine.  Pretty cool, huh?  So, the context that is attached to a component should be chosen such that the component is only processed as many times that it needs to be processed.  In the example we stepped through earlier in the post, the appropriate context to choose would have been System.