<?xml version="1.0"?><?xml-stylesheet type="text/xsl" href="/rss.xsl"?><rss version="2.0"><channel><title>MOSSProfileReplicate Wiki &amp; Documentation Rss Feed</title><link>http://www.codeplex.com/MOSSProfileReplicate/Wiki/View.aspx?title=Home</link><description>MOSSProfileReplicate Wiki Rss Description</description><item><title>UPDATED WIKI: Home</title><link>http://www.codeplex.com/MOSSProfileReplicate/Wiki/View.aspx?title=Home&amp;version=18</link><description>&lt;div class="wikidoc"&gt;
&lt;b&gt;What is this utility?&lt;/b&gt;&lt;br /&gt;The &amp;#34;SharePoint 2007 Shared Services Provider User Profile Property Replicator&amp;#34; was designed to take custom user profile properties and export&amp;#47;import them into another MOSS 2007 server.&amp;#13;&amp;#10;During most development cycles you will create custom user profile properties and currently the only way to move these from DEV&amp;#47;TEST&amp;#47;PROD is to backup&amp;#47;restore the Shared Services Provider.&amp;#13;&amp;#10;This tool will now reduce the amount of manual interaction required.
&lt;br /&gt; &lt;br /&gt;It saves you from manually creating the profile properties during deployment.&lt;br /&gt; &lt;br /&gt;&lt;img src="http://www.codeplex.com/MOSSProfileReplicate/Project/FileDownload.aspx?DownloadId=5661" alt="audienceuv5.gif" /&gt;&lt;br /&gt; &lt;br /&gt;&lt;b&gt;How to use this utility?&lt;/b&gt;&lt;br /&gt;The utility comes with online help. Just type in &amp;quot;ProfilePropertyMgr -help&amp;quot; at commandline to get the help screen.&lt;br /&gt; &lt;br /&gt;&lt;b&gt;Want the code?&lt;/b&gt;&lt;br /&gt;&lt;a href="http://www.codeplex.com/MOSSProfileReplicate/SourceControl/ListDownloadableCommits.aspx" class="externalLink"&gt;http://www.codeplex.com/MOSSProfileReplicate/SourceControl/ListDownloadableCommits.aspx&lt;/a&gt;&lt;br /&gt; &lt;br /&gt;&lt;b&gt;Want the build?&lt;/b&gt;&lt;br /&gt;&lt;a href="http://www.codeplex.com/MOSSProfileReplicate/Release/ProjectReleases.aspx" class="externalLink"&gt;http://www.codeplex.com/MOSSProfileReplicate/Release/ProjectReleases.aspx&lt;/a&gt;&lt;br /&gt; &lt;br /&gt;&lt;b&gt;Want more information?&lt;/b&gt;&lt;br /&gt;&lt;a href="http://blah.winsmarts.com/2007-1-SharePoint_2007_Utility_-1_-_ProfilePropertyMgr_-_Utility_to_Import-Export_profile_properties.aspx" class="externalLink"&gt;http://blah.winsmarts.com/2007-1-SharePoint_2007_Utility_-1_-_ProfilePropertyMgr_-_Utility_to_Import-Export_profile_properties.aspx&lt;/a&gt;&lt;br /&gt; &lt;br /&gt;&lt;b&gt;Want Membership?&lt;/b&gt;&lt;br /&gt;&lt;a href="mailto:ssiadmin@microsoft.com?subject=Membership Request - SharePoint 2007 Shared Services Provider User Profile Property Replicator" class="externalLink"&gt;mailto:ssiadmin@microsoft.com?subject=Membership Request - SharePoint 2007 Shared Services Provider User Profile Property Replicator&lt;/a&gt;&lt;br /&gt;
&lt;/div&gt;</description><author>alogan</author><pubDate>Sun, 01 Apr 2007 09:58:06 GMT</pubDate><guid isPermaLink="false">UPDATED WIKI: Home 20070401095806A</guid></item><item><title>UPDATED WIKI: Home</title><link>http://www.codeplex.com/MOSSProfileReplicate/Wiki/View.aspx?title=Home&amp;version=17</link><description>&lt;div class="wikidoc"&gt;
&lt;b&gt;What is this utility?&lt;/b&gt;&lt;br /&gt;The &amp;#34;SharePoint 2007 Shared Services Provider User Profile Property Replicator&amp;#34; was designed to take custom user profile properties and export&amp;#47;import them into another MOSS 2007 server.&amp;#13;&amp;#10;During most development cycles you will create custom user profile properties and currently the only way to move these from DEV&amp;#47;TEST&amp;#47;PROD is to backup&amp;#47;restore the Shared Services Provider.&amp;#13;&amp;#10;This tool will now reduce the amount of manual interaction required.
&lt;br /&gt; &lt;br /&gt;It saves you from manually creating the profile properties during deployment.&lt;br /&gt; &lt;br /&gt;&lt;img src="http://www.codeplex.com/MOSSProfileReplicate/Project/FileDownload.aspx?CountDownload=false&amp;amp;DownloadId=5661" alt="audienceuv5.gif" /&gt;&lt;br /&gt; &lt;br /&gt;&lt;b&gt;How to use this utility?&lt;/b&gt;&lt;br /&gt;The utility comes with online help. Just type in &amp;quot;ProfilePropertyMgr -help&amp;quot; at commandline to get the help screen.&lt;br /&gt; &lt;br /&gt;&lt;b&gt;Want the code?&lt;/b&gt;&lt;br /&gt;&lt;a href="http://www.codeplex.com/MOSSProfileReplicate/SourceControl/ListDownloadableCommits.aspx" class="externalLink"&gt;http://www.codeplex.com/MOSSProfileReplicate/SourceControl/ListDownloadableCommits.aspx&lt;/a&gt;&lt;br /&gt; &lt;br /&gt;&lt;b&gt;Want the build?&lt;/b&gt;&lt;br /&gt;&lt;a href="http://www.codeplex.com/MOSSProfileReplicate/Release/ProjectReleases.aspx" class="externalLink"&gt;http://www.codeplex.com/MOSSProfileReplicate/Release/ProjectReleases.aspx&lt;/a&gt;&lt;br /&gt; &lt;br /&gt;&lt;b&gt;Want more information?&lt;/b&gt;&lt;br /&gt;&lt;a href="http://blah.winsmarts.com/2007-1-SharePoint_2007_Utility_-1_-_ProfilePropertyMgr_-_Utility_to_Import-Export_profile_properties.aspx" class="externalLink"&gt;http://blah.winsmarts.com/2007-1-SharePoint_2007_Utility_-1_-_ProfilePropertyMgr_-_Utility_to_Import-Export_profile_properties.aspx&lt;/a&gt;&lt;br /&gt;
&lt;/div&gt;</description><author>alogan</author><pubDate>Tue, 16 Jan 2007 12:55:55 GMT</pubDate><guid isPermaLink="false">UPDATED WIKI: Home 20070116125555P</guid></item><item><title>UPDATED WIKI: Home</title><link>http://www.codeplex.com/MOSSProfileReplicate/Wiki/View.aspx?title=Home&amp;version=16</link><description>&lt;div class="wikidoc"&gt;
The &amp;#34;SharePoint 2007 Shared Services Provider User Profile Property Replicator&amp;#34; was designed to take custom user profile properties and export&amp;#47;import them into another MOSS 2007 server.&amp;#13;&amp;#10;During most development cycles you will create custom user profile properties and currently the only way to move these from DEV&amp;#47;TEST&amp;#47;PROD is to backup&amp;#47;restore the Shared Services Provider.&amp;#13;&amp;#10;This tool will now reduce the amount of manual interaction required.
&lt;br /&gt; &lt;br /&gt;&lt;b&gt;What is this utility?&lt;/b&gt;&lt;br /&gt;This is a command line utility that will allow you to manage profile properties setup on a SharePoint web's SharedService provider. It allows you to export properties from an SSP to XML, and vice versa.&lt;br /&gt; &lt;br /&gt;It saves you from manually creating the profile properties during deployment.&lt;br /&gt; &lt;br /&gt;&lt;img src="http://www.codeplex.com/MOSSProfileReplicate/Project/FileDownload.aspx?CountDownload=false&amp;amp;DownloadId=5661" alt="audienceuv5.gif" /&gt;&lt;br /&gt; &lt;br /&gt;&lt;b&gt;How to use this utility?&lt;/b&gt;&lt;br /&gt;The utility comes with online help. Just type in &amp;quot;ProfilePropertyMgr -help&amp;quot; at commandline to get the help screen.&lt;br /&gt; &lt;br /&gt;&lt;b&gt;Want the code?&lt;/b&gt;&lt;br /&gt;&lt;a href="http://www.codeplex.com/MOSSProfileReplicate/SourceControl/ListDownloadableCommits.aspx" class="externalLink"&gt;http://www.codeplex.com/MOSSProfileReplicate/SourceControl/ListDownloadableCommits.aspx&lt;/a&gt;&lt;br /&gt; &lt;br /&gt;&lt;b&gt;Want the build?&lt;/b&gt;&lt;br /&gt;&lt;a href="http://www.codeplex.com/MOSSProfileReplicate/Release/ProjectReleases.aspx" class="externalLink"&gt;http://www.codeplex.com/MOSSProfileReplicate/Release/ProjectReleases.aspx&lt;/a&gt;&lt;br /&gt; &lt;br /&gt;&lt;b&gt;Want more information?&lt;/b&gt;&lt;br /&gt;&lt;a href="http://blah.winsmarts.com/2007-1-SharePoint_2007_Utility_-1_-_ProfilePropertyMgr_-_Utility_to_Import-Export_profile_properties.aspx" class="externalLink"&gt;http://blah.winsmarts.com/2007-1-SharePoint_2007_Utility_-1_-_ProfilePropertyMgr_-_Utility_to_Import-Export_profile_properties.aspx&lt;/a&gt;&lt;br /&gt;
&lt;/div&gt;</description><author>alogan</author><pubDate>Mon, 15 Jan 2007 09:16:46 GMT</pubDate><guid isPermaLink="false">UPDATED WIKI: Home 20070115091646A</guid></item><item><title>UPDATED WIKI: Home</title><link>http://www.codeplex.com/MOSSProfileReplicate/Wiki/View.aspx?title=Home&amp;version=15</link><description>&lt;div class="wikidoc"&gt;
The &amp;#34;SharePoint 2007 Shared Services Provider User Profile Property Replicator&amp;#34; was designed to take custom user profile properties and export&amp;#47;import them into another MOSS 2007 server.&amp;#13;&amp;#10;During most development cycles you will create custom user profile properties and currently the only way to move these from DEV&amp;#47;TEST&amp;#47;PROD is to backup&amp;#47;restore the Shared Services Provider.&amp;#13;&amp;#10;This tool will now reduce the amount of manual interaction required.
&lt;br /&gt; &lt;br /&gt;&lt;b&gt;What is this utility?&lt;/b&gt;&lt;br /&gt;This is a command line utility that will allow you to manage profile properties setup on a SharePoint web's SharedService provider. It allows you to export properties from an SSP to XML, and vice versa.&lt;br /&gt; &lt;br /&gt;It saves you from manually creating the profile properties during deployment.&lt;br /&gt; &lt;br /&gt;&lt;span class="unresolved"&gt;Cannot resolve link: &lt;/span&gt;[image:http://img77.imageshack.us/img77/3103/audienceuv5.gif]&lt;br /&gt; &lt;br /&gt;&lt;b&gt;How to use this utility?&lt;/b&gt;&lt;br /&gt;The utility comes with online help. Just type in &amp;quot;ProfilePropertyMgr -help&amp;quot; at commandline to get the help screen.&lt;br /&gt; &lt;br /&gt;&lt;b&gt;Want the code?&lt;/b&gt;&lt;br /&gt;&lt;a href="http://www.codeplex.com/MOSSProfileReplicate/SourceControl/ListDownloadableCommits.aspx" class="externalLink"&gt;http://www.codeplex.com/MOSSProfileReplicate/SourceControl/ListDownloadableCommits.aspx&lt;/a&gt;&lt;br /&gt; &lt;br /&gt;&lt;b&gt;Want the build?&lt;/b&gt;&lt;br /&gt;&lt;a href="http://www.codeplex.com/MOSSProfileReplicate/Release/ProjectReleases.aspx" class="externalLink"&gt;http://www.codeplex.com/MOSSProfileReplicate/Release/ProjectReleases.aspx&lt;/a&gt;&lt;br /&gt; &lt;br /&gt;&lt;b&gt;Want more information?&lt;/b&gt;&lt;br /&gt;&lt;a href="http://blah.winsmarts.com/2007-1-SharePoint_2007_Utility_-1_-_ProfilePropertyMgr_-_Utility_to_Import-Export_profile_properties.aspx" class="externalLink"&gt;http://blah.winsmarts.com/2007-1-SharePoint_2007_Utility_-1_-_ProfilePropertyMgr_-_Utility_to_Import-Export_profile_properties.aspx&lt;/a&gt;&lt;br /&gt;
&lt;/div&gt;</description><author>alogan</author><pubDate>Mon, 15 Jan 2007 09:16:03 GMT</pubDate><guid isPermaLink="false">UPDATED WIKI: Home 20070115091603A</guid></item><item><title>UPDATED WIKI: Home</title><link>http://www.codeplex.com/MOSSProfileReplicate/Wiki/View.aspx?title=Home&amp;version=14</link><description>&lt;div class="wikidoc"&gt;
The &amp;#34;SharePoint 2007 Shared Services Provider User Profile Property Replicator&amp;#34; was designed to take custom user profile properties and export&amp;#47;import them into another MOSS 2007 server.&amp;#13;&amp;#10;During most development cycles you will create custom user profile properties and currently the only way to move these from DEV&amp;#47;TEST&amp;#47;PROD is to backup&amp;#47;restore the Shared Services Provider.&amp;#13;&amp;#10;This tool will now reduce the amount of manual interaction required.
&lt;br /&gt;    &lt;br /&gt;Recommended Reading/Basics before you dive into this blog post: &lt;a href="http://blah.winsmarts.com/2007-1-User_Profiles_and_Audience_Targeting.aspx" class="externalLink"&gt;http://blah.winsmarts.com/2007-1-User_Profiles_and_Audience_Targeting.aspx&lt;/a&gt;.&lt;br /&gt; &lt;br /&gt;&lt;b&gt;What is this utility?&lt;/b&gt;&lt;br /&gt;This is a command line utility that will allow you to manage profile properties setup on a SharePoint web's SharedService provider. It allows you to export properties from an SSP to XML, and vice versa.&lt;br /&gt; &lt;br /&gt;&lt;b&gt;How to use this utility?&lt;/b&gt;&lt;br /&gt;The utility comes with online help. Just type in &amp;quot;ProfilePropertyMgr -help&amp;quot; at commandline to get the help screen. The help screen reproduced below for your pleasure -&lt;br /&gt; &lt;br /&gt;For additional brochure ware on this utility see &lt;a href="http://blah.winsmarts.com/2007-1-SharePoint_2007_Utility_-1_-_ProfilePropertyMgr_-_Utility_to_Import-Export_profile_properties.aspx" class="externalLink"&gt;http://blah.winsmarts.com/2007-1-SharePoint_2007_Utility_-1_-_ProfilePropertyMgr_-_Utility_to_Import-Export_profile_properties.aspx&lt;/a&gt;&lt;br /&gt;
&lt;/div&gt;</description><author>alogan</author><pubDate>Mon, 15 Jan 2007 08:54:09 GMT</pubDate><guid isPermaLink="false">UPDATED WIKI: Home 20070115085409A</guid></item><item><title>UPDATED WIKI: Home</title><link>http://www.codeplex.com/MOSSProfileReplicate/Wiki/View.aspx?title=Home&amp;version=13</link><description>&lt;div class="wikidoc"&gt;
The &amp;#34;SharePoint 2007 Shared Services Provider User Profile Property Replicator&amp;#34; was designed to take custom user profile properties and export&amp;#47;import them into another MOSS 2007 server.&amp;#13;&amp;#10;During most development cycles you will create custom user profile properties and currently the only way to move these from DEV&amp;#47;TEST&amp;#47;PROD is to backup&amp;#47;restore the Shared Services Provider.&amp;#13;&amp;#10;This tool will now reduce the amount of manual interaction required.
&lt;br /&gt;    &lt;br /&gt;Recommended Reading/Basics before you dive into this blog post: &lt;a href="http://blah.winsmarts.com/2007-1-User_Profiles_and_Audience_Targeting.aspx" class="externalLink"&gt;http://blah.winsmarts.com/2007-1-User_Profiles_and_Audience_Targeting.aspx&lt;/a&gt;.&lt;br /&gt; &lt;br /&gt;&lt;b&gt;What is this utility?&lt;/b&gt;&lt;br /&gt;This is a command line utility that will allow you to manage profile properties setup on a SharePoint web's SharedService provider. It allows you to export properties from an SSP to XML, and vice versa.&lt;br /&gt; &lt;br /&gt;&lt;b&gt;How to use this utility?&lt;/b&gt;&lt;br /&gt;The utility comes with online help. Just type in &amp;quot;ProfilePropertyMgr -help&amp;quot; at commandline to get the help screen. The help screen reproduced below for your pleasure -&lt;br /&gt; &lt;br /&gt;=================================================&lt;br /&gt;&lt;b&gt;Profile Property Manager - Help&lt;/b&gt;&lt;br /&gt;================================================= &lt;br /&gt; &lt;br /&gt;&lt;b&gt;Usage:&lt;/b&gt; ProfilePropertyMgr -url &amp;lt;UrlToWeb&amp;gt; -filename &amp;lt;FileName&amp;gt; -import&lt;br /&gt;ProfilePropertyMgr -url &amp;lt;UrlToWeb&amp;gt; -filename &amp;lt;FileName&amp;gt; -export &lt;br /&gt; &lt;br /&gt;or &lt;br /&gt; &lt;br /&gt;ProfilePropertyMgr -help &lt;br /&gt; &lt;br /&gt;&lt;b&gt;Used For&lt;/b&gt;&lt;br /&gt;Export Profile properties from SharePoint to an XML file.&lt;br /&gt;Import Profile properties from an XML file to SharePoint. &lt;br /&gt; &lt;br /&gt;&lt;b&gt;Required Parameters are:&lt;/b&gt;&lt;br /&gt;-url &amp;lt;UrlToWeb&amp;gt;&lt;br /&gt;-file &amp;lt;FileName.xml&amp;gt; &lt;br /&gt; &lt;br /&gt;&lt;b&gt;XML File structure:&lt;/b&gt;&lt;br /&gt;*&amp;lt;Properties&amp;gt;&lt;br /&gt;&lt;ul&gt;
&lt;ul&gt;
&lt;li&gt; &amp;lt;Property&amp;gt;&lt;/li&gt;&lt;ul&gt;
&lt;ul&gt;
&lt;li&gt;   &amp;lt;PropertyInfo Name=&amp;quot; Type=&amp;quot; Data=&amp;quot;/&amp;gt;&lt;/li&gt;&lt;li&gt;   &amp;lt;PropertyInfo ..&amp;gt;&lt;/li&gt;&lt;ul&gt;
&lt;li&gt;   ...&lt;/li&gt;
&lt;/ul&gt;&lt;li&gt;&amp;lt;/Property&amp;gt;&lt;/li&gt;
&lt;/ul&gt;&lt;li&gt;&amp;lt;Property&amp;gt;...&amp;lt;/Property&amp;gt;&lt;/li&gt;
&lt;/ul&gt;&lt;li&gt;...&lt;/li&gt;
&lt;/ul&gt;
&lt;/ul&gt;*&amp;lt;/Properties&amp;gt; &lt;br /&gt; &lt;br /&gt;&lt;b&gt;Sample usage:&lt;/b&gt;&lt;br /&gt;&lt;ul&gt;
&lt;li&gt;ProfilePropertyMgr -url http://moss2007 -filename output.xml -export&lt;/li&gt;&lt;li&gt;ProfilePropertyMgr -url http://moss2007 -filename input.xml -import &lt;/li&gt;
&lt;/ul&gt; &lt;br /&gt;&lt;b&gt;Code Explanation&lt;/b&gt;&lt;br /&gt;The code accepts input as command line parameters, and passes them to a business object called ProgramInputs as shown below: &lt;br /&gt; &lt;br /&gt;static void Main(string[] args)&lt;br /&gt;{&lt;br /&gt;    ProgramInputs inputs = new ProgramInputs(args);&lt;br /&gt; &lt;br /&gt;&lt;i&gt;The ProgramInputs business object has 3 properties - Boolean &amp;quot;IsValid&amp;quot;, String &amp;quot;URL&amp;quot;, and &amp;quot;CurrentOperation&amp;quot;. CurrentOperation is a custom enum with 3 possible valies - Unspecified, Import and Export. ProgramInputs encapsulates the functionality to validate inputs, and tell the end user if the inputs are accepted, or what was missing.&lt;/i&gt;&lt;br /&gt; &lt;br /&gt;&lt;i&gt;Once we know that the inputs are valid, we can act upon them. This is done using the following code&lt;/i&gt;&lt;br /&gt; &lt;br /&gt;    if (inputs.IsValid)&lt;br /&gt;    {&lt;br /&gt;      ...&lt;br /&gt;    }&lt;br /&gt;    else&lt;br /&gt;    {&lt;br /&gt;        Trace.WriteLine(&amp;quot;Invalid inputs specified&amp;quot;, true);&lt;br /&gt;        Trace.PrintHelp();&lt;br /&gt;    }&lt;br /&gt; &lt;br /&gt;&lt;i&gt;And the actual code looks like this -&lt;/i&gt;&lt;br /&gt; &lt;br /&gt;    using (SPSite site = new SPSite(inputs.Url))&lt;br /&gt;    {&lt;br /&gt;        ServerContext context = ServerContext.GetContext(site);&lt;br /&gt;        UserProfileManager profileManager = new UserProfileManager(context);&lt;br /&gt;    &lt;br /&gt;        switch (inputs.CurrentOperation)&lt;br /&gt;        {&lt;br /&gt;            case Operation.Unspecified:&lt;br /&gt;                throw new InvalidOperationException(&amp;quot;Invalid input operation specified, or input operation omitted, cannot continue&amp;quot;);&lt;br /&gt;            case Operation.Import:&lt;br /&gt;                WorkerBee.ImportProfiles(inputs, profileManager);&lt;br /&gt;                break;&lt;br /&gt;            case Operation.Export:&lt;br /&gt;                WorkerBee.ExportProfiles(inputs, profileManager);&lt;br /&gt;                break;&lt;br /&gt;            default: // This will never happen, so safely ignored.&lt;br /&gt;                break;&lt;br /&gt;        }&lt;br /&gt;    }&lt;br /&gt; &lt;br /&gt;&lt;i&gt;As you would note from the above, the work is delegated to a class called WorkerBee. It has two methods, one to export, and one to import. I first get a hold of all the SharePoint properties using ProfileManager.Properties, and then I use reflection to sniff out which properties are exportable. Basically, anything that can be succesfully imported on the other end, is exportable on this end (duh!). So what is importable/exportable? Anything that is Read/Write, is value-type (or string), and doesn't start with &amp;quot;SSP-&amp;quot; (reserved for SharePoint), or isn't the reserved UserProfile&lt;/i&gt;GUID property column. This in C#, is described as below -_&lt;br /&gt; &lt;br /&gt;    private static bool ShouldExport(PropertyInfo typeProperty, Property profileProperty, bool entireProperty)&lt;br /&gt;    {&lt;br /&gt;        bool toReturn = false;&lt;br /&gt;    &lt;br /&gt;        toReturn = typeProperty.CanRead &amp;amp; typeProperty.CanWrite &amp;amp;&lt;br /&gt;                   (&lt;br /&gt;                        typeProperty.PropertyType.IsValueType |&lt;br /&gt;                        typeProperty.PropertyType.FullName.Equals(&amp;quot;System.String&amp;quot;)&lt;br /&gt;                    );&lt;br /&gt; &lt;br /&gt;        // Proceed only if toReturn is still true ;&lt;br /&gt;        // Also, the following applies to only entire properties&lt;br /&gt;        if (toReturn &amp;amp; entireProperty)&lt;br /&gt;        {&lt;br /&gt;            object reflectedValue = typeProperty.GetValue(profileProperty, null);&lt;br /&gt;            string strReflectedValue = (reflectedValue == null) ? String.Empty : reflectedValue.ToString();&lt;br /&gt;            toReturn &amp;amp;= !strReflectedValue.Equals(&amp;quot;UserProfile_GUID&amp;quot;);&lt;br /&gt;            toReturn &amp;amp;= !strReflectedValue.StartsWith(&amp;quot;SPS-&amp;quot;);&lt;br /&gt;        }&lt;br /&gt;        return toReturn;&lt;br /&gt;    }&lt;br /&gt; &lt;br /&gt;&lt;i&gt;The full Export Profiles method looks like this -&lt;/i&gt;&lt;br /&gt; &lt;br /&gt;    internal static void ExportProfiles(ProgramInputs inputs, UserProfileManager profileManager)&lt;br /&gt;    {&lt;br /&gt;        // Variable Naming convention: &amp;lt;objectinConcern&amp;gt;&amp;lt;Property/Properties&amp;gt;&lt;br /&gt;    &lt;br /&gt;        PropertyCollection profileProperties = profileManager.Properties;&lt;br /&gt;    &lt;br /&gt;        XmlDocument exportProperties = new XmlDocument();&lt;br /&gt;        XmlNode nodeProperties = exportProperties.CreateNode(XmlNodeType.Element, &amp;quot;Properties&amp;quot;, &amp;quot;&amp;quot;);&lt;br /&gt;        exportProperties.AppendChild(nodeProperties);&lt;br /&gt;    &lt;br /&gt;        PropertyInfo[] allProps = typeof(Property).GetProperties();&lt;br /&gt;        Dictionary&amp;lt;string, PropertyInfo&amp;gt; typeProperties = new Dictionary&amp;lt;string, PropertyInfo&amp;gt;();&lt;br /&gt;        foreach (PropertyInfo typeProperty in allProps)&lt;br /&gt;        {&lt;br /&gt;            typeProperties.Add(typeProperty.Name, typeProperty);&lt;br /&gt;        }&lt;br /&gt;    &lt;br /&gt;        foreach (Property profileProperty in profileProperties)&lt;br /&gt;        {&lt;br /&gt;            // Should I be even exporting this property?&lt;br /&gt;            bool isExportable = ShouldExport(typeProperties&lt;a href="http://www.codeplex.com/MOSSProfileReplicate/Wiki/View.aspx?title=%22Name%22"&gt;&amp;quot;Name&amp;quot;&lt;/a&gt;, profileProperty, true);&lt;br /&gt;    &lt;br /&gt;            if (isExportable)&lt;br /&gt;            {&lt;br /&gt;                XmlNode nodeProperty = exportProperties.CreateNode(XmlNodeType.Element, &amp;quot;Property&amp;quot;, &amp;quot;&amp;quot;);&lt;br /&gt;                nodeProperties.AppendChild(nodeProperty);&lt;br /&gt;    &lt;br /&gt;                foreach (PropertyInfo typeProperty in typeProperties.Values)&lt;br /&gt;                {&lt;br /&gt;                    if (ShouldExport(typeProperty, profileProperty, false))&lt;br /&gt;                    {&lt;br /&gt;                        XmlNode nodePropertyInfo = exportProperties.CreateNode(XmlNodeType.Element, &amp;quot;PropertyInfo&amp;quot;, &amp;quot;&amp;quot;);&lt;br /&gt;    &lt;br /&gt;                        XmlAttribute attribProfilePropInfo;&lt;br /&gt;                        object reflectedValue;&lt;br /&gt;    &lt;br /&gt;                        //Name&lt;br /&gt;                        attribProfilePropInfo = exportProperties.CreateNode(XmlNodeType.Attribute, &amp;quot;Name&amp;quot;, &amp;quot;&amp;quot;) as XmlAttribute;&lt;br /&gt;                        attribProfilePropInfo.Value = typeProperty.Name;&lt;br /&gt;                        nodePropertyInfo.Attributes.Append(attribProfilePropInfo);&lt;br /&gt;    &lt;br /&gt;                        // Data Type&lt;br /&gt;                        attribProfilePropInfo = exportProperties.CreateNode(XmlNodeType.Attribute, &amp;quot;Type&amp;quot;, &amp;quot;&amp;quot;) as XmlAttribute;&lt;br /&gt;                        attribProfilePropInfo.Value = typeProperty.PropertyType.AssemblyQualifiedName;&lt;br /&gt;                        nodePropertyInfo.Attributes.Append(attribProfilePropInfo);&lt;br /&gt;    &lt;br /&gt;                        // Value&lt;br /&gt;                        attribProfilePropInfo = exportProperties.CreateNode(XmlNodeType.Attribute, &amp;quot;Data&amp;quot;, &amp;quot;&amp;quot;) as XmlAttribute;&lt;br /&gt;                        reflectedValue = typeProperty.GetValue(profileProperty, null);&lt;br /&gt;                        attribProfilePropInfo.Value = (reflectedValue == null) ? String.Empty : reflectedValue.ToString();&lt;br /&gt;                        nodePropertyInfo.Attributes.Append(attribProfilePropInfo);&lt;br /&gt;    &lt;br /&gt;                        nodeProperty.AppendChild(nodePropertyInfo);&lt;br /&gt;                    }&lt;br /&gt;                }&lt;br /&gt;            }&lt;br /&gt;        }&lt;br /&gt;    &lt;br /&gt;        exportProperties.Save(inputs.FileName);&lt;br /&gt;    }&lt;br /&gt; &lt;br /&gt;&lt;i&gt;The ImportProfiles method is the exact anti-thesis of the above, so I am not going to bother copy pasting that here.&lt;/i&gt;&lt;br /&gt;
&lt;/div&gt;</description><author>alogan</author><pubDate>Mon, 15 Jan 2007 08:52:49 GMT</pubDate><guid isPermaLink="false">UPDATED WIKI: Home 20070115085249A</guid></item><item><title>UPDATED WIKI: Home</title><link>http://www.codeplex.com/MOSSProfileReplicate/Wiki/View.aspx?title=Home&amp;version=12</link><description>&lt;div class="wikidoc"&gt;
The &amp;#34;SharePoint 2007 Shared Services Provider User Profile Property Replicator&amp;#34; was designed to take custom user profile properties and export&amp;#47;import them into another MOSS 2007 server.&amp;#13;&amp;#10;During most development cycles you will create custom user profile properties and currently the only way to move these from DEV&amp;#47;TEST&amp;#47;PROD is to backup&amp;#47;restore the Shared Services Provider.&amp;#13;&amp;#10;This tool will now reduce the amount of manual interaction required.
&lt;br /&gt;    &lt;br /&gt;Recommended Reading/Basics before you dive into this blog post: &lt;a href="http://blah.winsmarts.com/2007-1-User_Profiles_and_Audience_Targeting.aspx" class="externalLink"&gt;http://blah.winsmarts.com/2007-1-User_Profiles_and_Audience_Targeting.aspx&lt;/a&gt;.&lt;br /&gt; &lt;br /&gt;&lt;b&gt;What is this utility?&lt;/b&gt;&lt;br /&gt;This is a command line utility that will allow you to manage profile properties setup on a SharePoint web's SharedService provider. It allows you to export properties from an SSP to XML, and vice versa.&lt;br /&gt; &lt;br /&gt;&lt;b&gt;How to use this utility?&lt;/b&gt;&lt;br /&gt;The utility comes with online help. Just type in &amp;quot;ProfilePropertyMgr -help&amp;quot; at commandline to get the help screen. The help screen reproduced below for your pleasure -&lt;br /&gt; &lt;br /&gt;=================================================&lt;br /&gt;&lt;b&gt;Profile Property Manager - Help&lt;/b&gt;&lt;br /&gt;================================================= &lt;br /&gt; &lt;br /&gt;&lt;b&gt;Usage:&lt;/b&gt; ProfilePropertyMgr -url &amp;lt;UrlToWeb&amp;gt; -filename &amp;lt;FileName&amp;gt; -import&lt;br /&gt;ProfilePropertyMgr -url &amp;lt;UrlToWeb&amp;gt; -filename &amp;lt;FileName&amp;gt; -export &lt;br /&gt; &lt;br /&gt;or &lt;br /&gt; &lt;br /&gt;ProfilePropertyMgr -help &lt;br /&gt; &lt;br /&gt;&lt;b&gt;Used For&lt;/b&gt;&lt;br /&gt;Export Profile properties from SharePoint to an XML file.&lt;br /&gt;Import Profile properties from an XML file to SharePoint. &lt;br /&gt; &lt;br /&gt;&lt;b&gt;Required Parameters are:&lt;/b&gt;&lt;br /&gt;-url &amp;lt;UrlToWeb&amp;gt;&lt;br /&gt;-file &amp;lt;FileName.xml&amp;gt; &lt;br /&gt; &lt;br /&gt;&lt;b&gt;XML File structure:&lt;/b&gt;&lt;br /&gt;&amp;lt;Properties&amp;gt;&lt;br /&gt;  &amp;lt;Property&amp;gt;&lt;br /&gt;    &amp;lt;PropertyInfo Name=&amp;quot; Type=&amp;quot; Data=&amp;quot;/&amp;gt;&lt;br /&gt;    &amp;lt;PropertyInfo ..&amp;gt;&lt;br /&gt;    ...&lt;br /&gt;  &amp;lt;/Property&amp;gt;&lt;br /&gt;  &amp;lt;Property&amp;gt;...&amp;lt;/Property&amp;gt;&lt;br /&gt;  ...&lt;br /&gt;&amp;lt;/Properties&amp;gt; &lt;br /&gt; &lt;br /&gt;&lt;b&gt;Sample usage:&lt;/b&gt;&lt;br /&gt;&lt;ul&gt;
&lt;li&gt;ProfilePropertyMgr -url http://moss2007 -filename output.xml -export&lt;/li&gt;&lt;li&gt;ProfilePropertyMgr -url http://moss2007 -filename input.xml -import &lt;/li&gt;
&lt;/ul&gt; &lt;br /&gt;&lt;b&gt;Code Explanation&lt;/b&gt;&lt;br /&gt;The code accepts input as command line parameters, and passes them to a business object called ProgramInputs as shown below: &lt;br /&gt; &lt;br /&gt;static void Main(string[] args)&lt;br /&gt;{&lt;br /&gt;    ProgramInputs inputs = new ProgramInputs(args);&lt;br /&gt; &lt;br /&gt;&lt;i&gt;The ProgramInputs business object has 3 properties - Boolean &amp;quot;IsValid&amp;quot;, String &amp;quot;URL&amp;quot;, and &amp;quot;CurrentOperation&amp;quot;. CurrentOperation is a custom enum with 3 possible valies - Unspecified, Import and Export. ProgramInputs encapsulates the functionality to validate inputs, and tell the end user if the inputs are accepted, or what was missing.&lt;/i&gt;&lt;br /&gt; &lt;br /&gt;&lt;i&gt;Once we know that the inputs are valid, we can act upon them. This is done using the following code&lt;/i&gt;&lt;br /&gt; &lt;br /&gt;    if (inputs.IsValid)&lt;br /&gt;    {&lt;br /&gt;      ...&lt;br /&gt;    }&lt;br /&gt;    else&lt;br /&gt;    {&lt;br /&gt;        Trace.WriteLine(&amp;quot;Invalid inputs specified&amp;quot;, true);&lt;br /&gt;        Trace.PrintHelp();&lt;br /&gt;    }&lt;br /&gt; &lt;br /&gt;&lt;i&gt;And the actual code looks like this -&lt;/i&gt;&lt;br /&gt; &lt;br /&gt;    using (SPSite site = new SPSite(inputs.Url))&lt;br /&gt;    {&lt;br /&gt;        ServerContext context = ServerContext.GetContext(site);&lt;br /&gt;        UserProfileManager profileManager = new UserProfileManager(context);&lt;br /&gt;    &lt;br /&gt;        switch (inputs.CurrentOperation)&lt;br /&gt;        {&lt;br /&gt;            case Operation.Unspecified:&lt;br /&gt;                throw new InvalidOperationException(&amp;quot;Invalid input operation specified, or input operation omitted, cannot continue&amp;quot;);&lt;br /&gt;            case Operation.Import:&lt;br /&gt;                WorkerBee.ImportProfiles(inputs, profileManager);&lt;br /&gt;                break;&lt;br /&gt;            case Operation.Export:&lt;br /&gt;                WorkerBee.ExportProfiles(inputs, profileManager);&lt;br /&gt;                break;&lt;br /&gt;            default: // This will never happen, so safely ignored.&lt;br /&gt;                break;&lt;br /&gt;        }&lt;br /&gt;    }&lt;br /&gt; &lt;br /&gt;&lt;i&gt;As you would note from the above, the work is delegated to a class called WorkerBee. It has two methods, one to export, and one to import. I first get a hold of all the SharePoint properties using ProfileManager.Properties, and then I use reflection to sniff out which properties are exportable. Basically, anything that can be succesfully imported on the other end, is exportable on this end (duh!). So what is importable/exportable? Anything that is Read/Write, is value-type (or string), and doesn't start with &amp;quot;SSP-&amp;quot; (reserved for SharePoint), or isn't the reserved UserProfile&lt;/i&gt;GUID property column. This in C#, is described as below -_&lt;br /&gt; &lt;br /&gt;    private static bool ShouldExport(PropertyInfo typeProperty, Property profileProperty, bool entireProperty)&lt;br /&gt;    {&lt;br /&gt;        bool toReturn = false;&lt;br /&gt;    &lt;br /&gt;        toReturn = typeProperty.CanRead &amp;amp; typeProperty.CanWrite &amp;amp;&lt;br /&gt;                   (&lt;br /&gt;                        typeProperty.PropertyType.IsValueType |&lt;br /&gt;                        typeProperty.PropertyType.FullName.Equals(&amp;quot;System.String&amp;quot;)&lt;br /&gt;                    );&lt;br /&gt; &lt;br /&gt;        // Proceed only if toReturn is still true ;&lt;br /&gt;        // Also, the following applies to only entire properties&lt;br /&gt;        if (toReturn &amp;amp; entireProperty)&lt;br /&gt;        {&lt;br /&gt;            object reflectedValue = typeProperty.GetValue(profileProperty, null);&lt;br /&gt;            string strReflectedValue = (reflectedValue == null) ? String.Empty : reflectedValue.ToString();&lt;br /&gt;            toReturn &amp;amp;= !strReflectedValue.Equals(&amp;quot;UserProfile_GUID&amp;quot;);&lt;br /&gt;            toReturn &amp;amp;= !strReflectedValue.StartsWith(&amp;quot;SPS-&amp;quot;);&lt;br /&gt;        }&lt;br /&gt;        return toReturn;&lt;br /&gt;    }&lt;br /&gt; &lt;br /&gt;&lt;i&gt;The full Export Profiles method looks like this -&lt;/i&gt;&lt;br /&gt; &lt;br /&gt;    internal static void ExportProfiles(ProgramInputs inputs, UserProfileManager profileManager)&lt;br /&gt;    {&lt;br /&gt;        // Variable Naming convention: &amp;lt;objectinConcern&amp;gt;&amp;lt;Property/Properties&amp;gt;&lt;br /&gt;    &lt;br /&gt;        PropertyCollection profileProperties = profileManager.Properties;&lt;br /&gt;    &lt;br /&gt;        XmlDocument exportProperties = new XmlDocument();&lt;br /&gt;        XmlNode nodeProperties = exportProperties.CreateNode(XmlNodeType.Element, &amp;quot;Properties&amp;quot;, &amp;quot;&amp;quot;);&lt;br /&gt;        exportProperties.AppendChild(nodeProperties);&lt;br /&gt;    &lt;br /&gt;        PropertyInfo[] allProps = typeof(Property).GetProperties();&lt;br /&gt;        Dictionary&amp;lt;string, PropertyInfo&amp;gt; typeProperties = new Dictionary&amp;lt;string, PropertyInfo&amp;gt;();&lt;br /&gt;        foreach (PropertyInfo typeProperty in allProps)&lt;br /&gt;        {&lt;br /&gt;            typeProperties.Add(typeProperty.Name, typeProperty);&lt;br /&gt;        }&lt;br /&gt;    &lt;br /&gt;        foreach (Property profileProperty in profileProperties)&lt;br /&gt;        {&lt;br /&gt;            // Should I be even exporting this property?&lt;br /&gt;            bool isExportable = ShouldExport(typeProperties&lt;a href="http://www.codeplex.com/MOSSProfileReplicate/Wiki/View.aspx?title=%22Name%22"&gt;&amp;quot;Name&amp;quot;&lt;/a&gt;, profileProperty, true);&lt;br /&gt;    &lt;br /&gt;            if (isExportable)&lt;br /&gt;            {&lt;br /&gt;                XmlNode nodeProperty = exportProperties.CreateNode(XmlNodeType.Element, &amp;quot;Property&amp;quot;, &amp;quot;&amp;quot;);&lt;br /&gt;                nodeProperties.AppendChild(nodeProperty);&lt;br /&gt;    &lt;br /&gt;                foreach (PropertyInfo typeProperty in typeProperties.Values)&lt;br /&gt;                {&lt;br /&gt;                    if (ShouldExport(typeProperty, profileProperty, false))&lt;br /&gt;                    {&lt;br /&gt;                        XmlNode nodePropertyInfo = exportProperties.CreateNode(XmlNodeType.Element, &amp;quot;PropertyInfo&amp;quot;, &amp;quot;&amp;quot;);&lt;br /&gt;    &lt;br /&gt;                        XmlAttribute attribProfilePropInfo;&lt;br /&gt;                        object reflectedValue;&lt;br /&gt;    &lt;br /&gt;                        //Name&lt;br /&gt;                        attribProfilePropInfo = exportProperties.CreateNode(XmlNodeType.Attribute, &amp;quot;Name&amp;quot;, &amp;quot;&amp;quot;) as XmlAttribute;&lt;br /&gt;                        attribProfilePropInfo.Value = typeProperty.Name;&lt;br /&gt;                        nodePropertyInfo.Attributes.Append(attribProfilePropInfo);&lt;br /&gt;    &lt;br /&gt;                        // Data Type&lt;br /&gt;                        attribProfilePropInfo = exportProperties.CreateNode(XmlNodeType.Attribute, &amp;quot;Type&amp;quot;, &amp;quot;&amp;quot;) as XmlAttribute;&lt;br /&gt;                        attribProfilePropInfo.Value = typeProperty.PropertyType.AssemblyQualifiedName;&lt;br /&gt;                        nodePropertyInfo.Attributes.Append(attribProfilePropInfo);&lt;br /&gt;    &lt;br /&gt;                        // Value&lt;br /&gt;                        attribProfilePropInfo = exportProperties.CreateNode(XmlNodeType.Attribute, &amp;quot;Data&amp;quot;, &amp;quot;&amp;quot;) as XmlAttribute;&lt;br /&gt;                        reflectedValue = typeProperty.GetValue(profileProperty, null);&lt;br /&gt;                        attribProfilePropInfo.Value = (reflectedValue == null) ? String.Empty : reflectedValue.ToString();&lt;br /&gt;                        nodePropertyInfo.Attributes.Append(attribProfilePropInfo);&lt;br /&gt;    &lt;br /&gt;                        nodeProperty.AppendChild(nodePropertyInfo);&lt;br /&gt;                    }&lt;br /&gt;                }&lt;br /&gt;            }&lt;br /&gt;        }&lt;br /&gt;    &lt;br /&gt;        exportProperties.Save(inputs.FileName);&lt;br /&gt;    }&lt;br /&gt; &lt;br /&gt;&lt;i&gt;The ImportProfiles method is the exact anti-thesis of the above, so I am not going to bother copy pasting that here.&lt;/i&gt;&lt;br /&gt;
&lt;/div&gt;</description><author>alogan</author><pubDate>Mon, 15 Jan 2007 08:50:19 GMT</pubDate><guid isPermaLink="false">UPDATED WIKI: Home 20070115085019A</guid></item><item><title>UPDATED WIKI: Home</title><link>http://www.codeplex.com/MOSSProfileReplicate/Wiki/View.aspx?title=Home&amp;version=11</link><description>&lt;div class="wikidoc"&gt;
The &amp;#34;SharePoint 2007 Shared Services Provider User Profile Property Replicator&amp;#34; was designed to take custom user profile properties and export&amp;#47;import them into another MOSS 2007 server.&amp;#13;&amp;#10;During most development cycles you will create custom user profile properties and currently the only way to move these from DEV&amp;#47;TEST&amp;#47;PROD is to backup&amp;#47;restore the Shared Services Provider.&amp;#13;&amp;#10;This tool will now reduce the amount of manual interaction required.
&lt;br /&gt; &lt;br /&gt;Recommended Reading/Basics before you dive into this blog post: &lt;a href="http://blah.winsmarts.com/2007-1-User_Profiles_and_Audience_Targeting.aspx" class="externalLink"&gt;http://blah.winsmarts.com/2007-1-User_Profiles_and_Audience_Targeting.aspx&lt;/a&gt;.&lt;br /&gt; &lt;br /&gt;&lt;b&gt;What is this utility?&lt;/b&gt;&lt;br /&gt;This is a command line utility that will allow you to manage profile properties setup on a SharePoint web's SharedService provider. It allows you to export properties from an SSP to XML, and vice versa.&lt;br /&gt; &lt;br /&gt;&lt;b&gt;How to use this utility?&lt;/b&gt;&lt;br /&gt;The utility comes with online help. Just type in &amp;quot;ProfilePropertyMgr -help&amp;quot; at commandline to get the help screen. The help screen reproduced below for your pleasure -&lt;br /&gt; &lt;br /&gt;&amp;lt;b&amp;gt;Test 123&amp;lt;/b&amp;gt;&lt;br /&gt;=================================================&lt;br /&gt;&lt;b&gt;Profile Property Manager - Help&lt;/b&gt;&lt;br /&gt;================================================= &lt;br /&gt; &lt;br /&gt;&lt;b&gt;Usage:&lt;/b&gt; ProfilePropertyMgr -url &amp;lt;UrlToWeb&amp;gt; -filename &amp;lt;FileName&amp;gt; -import&lt;br /&gt;ProfilePropertyMgr -url &amp;lt;UrlToWeb&amp;gt; -filename &amp;lt;FileName&amp;gt; -export &lt;br /&gt; &lt;br /&gt;or &lt;br /&gt; &lt;br /&gt;ProfilePropertyMgr -help &lt;br /&gt; &lt;br /&gt;&lt;b&gt;Used For&lt;/b&gt;&lt;br /&gt;Export Profile properties from SharePoint to an XML file.&lt;br /&gt;Import Profile properties from an XML file to SharePoint. &lt;br /&gt; &lt;br /&gt;&lt;b&gt;Required Parameters are:&lt;/b&gt;&lt;br /&gt;-url &amp;lt;UrlToWeb&amp;gt;&lt;br /&gt;-file &amp;lt;FileName.xml&amp;gt; &lt;br /&gt; &lt;br /&gt;&lt;b&gt;XML File structure:&lt;/b&gt;&lt;br /&gt;&amp;lt;Properties&amp;gt;&lt;br /&gt;  &amp;lt;Property&amp;gt;&lt;br /&gt;    &amp;lt;PropertyInfo Name=&amp;quot; Type=&amp;quot; Data=&amp;quot;/&amp;gt;&lt;br /&gt;    &amp;lt;PropertyInfo ..&amp;gt;&lt;br /&gt;    ...&lt;br /&gt;  &amp;lt;/Property&amp;gt;&lt;br /&gt;  &amp;lt;Property&amp;gt;...&amp;lt;/Property&amp;gt;&lt;br /&gt;  ...&lt;br /&gt;&amp;lt;/Properties&amp;gt; &lt;br /&gt; &lt;br /&gt;&lt;b&gt;Sample usage:&lt;/b&gt;&lt;br /&gt;&lt;ul&gt;
&lt;li&gt;ProfilePropertyMgr -url http://moss2007 -filename output.xml -export&lt;/li&gt;&lt;li&gt;ProfilePropertyMgr -url http://moss2007 -filename input.xml -import &lt;/li&gt;
&lt;/ul&gt; &lt;br /&gt;&lt;b&gt;Code Explanation&lt;/b&gt;&lt;br /&gt;The code accepts input as command line parameters, and passes them to a business object called ProgramInputs as shown below: &lt;br /&gt; &lt;br /&gt;static void Main(string[] args)&lt;br /&gt;{&lt;br /&gt;    ProgramInputs inputs = new ProgramInputs(args);&lt;br /&gt; &lt;br /&gt;&lt;i&gt;The ProgramInputs business object has 3 properties - Boolean &amp;quot;IsValid&amp;quot;, String &amp;quot;URL&amp;quot;, and &amp;quot;CurrentOperation&amp;quot;. CurrentOperation is a custom enum with 3 possible valies - Unspecified, Import and Export. ProgramInputs encapsulates the functionality to validate inputs, and tell the end user if the inputs are accepted, or what was missing.&lt;/i&gt;&lt;br /&gt; &lt;br /&gt;Once we know that the inputs are valid, we can act upon them. This is done using the following code&lt;br /&gt; &lt;br /&gt;if (inputs.IsValid)&lt;br /&gt;{&lt;br /&gt;  ...&lt;br /&gt;}&lt;br /&gt;else&lt;br /&gt;{&lt;br /&gt;    Trace.WriteLine(&amp;quot;Invalid inputs specified&amp;quot;, true);&lt;br /&gt;    Trace.PrintHelp();&lt;br /&gt;}&lt;br /&gt; &lt;br /&gt;And the actual code looks like this - &lt;br /&gt; &lt;br /&gt;using (SPSite site = new SPSite(inputs.Url))&lt;br /&gt;{&lt;br /&gt;    ServerContext context = ServerContext.GetContext(site);&lt;br /&gt;    UserProfileManager profileManager = new UserProfileManager(context);&lt;br /&gt; &lt;br /&gt;    switch (inputs.CurrentOperation)&lt;br /&gt;    {&lt;br /&gt;        case Operation.Unspecified:&lt;br /&gt;            throw new InvalidOperationException(&amp;quot;Invalid input operation specified, or input operation omitted, cannot continue&amp;quot;);&lt;br /&gt;        case Operation.Import:&lt;br /&gt;            WorkerBee.ImportProfiles(inputs, profileManager);&lt;br /&gt;            break;&lt;br /&gt;        case Operation.Export:&lt;br /&gt;            WorkerBee.ExportProfiles(inputs, profileManager);&lt;br /&gt;            break;&lt;br /&gt;        default: // This will never happen, so safely ignored.&lt;br /&gt;            break;&lt;br /&gt;    }&lt;br /&gt;}&lt;br /&gt; &lt;br /&gt;As you would note from the above, the work is delegated to a class called WorkerBee. It has two methods, one to export, and one to import. I first get a hold of all the SharePoint properties using ProfileManager.Properties, and then I use reflection to sniff out which properties are exportable. Basically, anything that can be succesfully imported on the other end, is exportable on this end (duh!). So what is importable/exportable? Anything that is Read/Write, is value-type (or string), and doesn't start with &amp;quot;SSP-&amp;quot; (reserved for SharePoint), or isn't the reserved UserProfile_GUID property column. This in C#, is described as below - &lt;br /&gt; &lt;br /&gt;private static bool ShouldExport(PropertyInfo typeProperty, Property profileProperty, bool entireProperty)&lt;br /&gt;{&lt;br /&gt;    bool toReturn = false;&lt;br /&gt; &lt;br /&gt;    toReturn = typeProperty.CanRead &amp;amp; typeProperty.CanWrite &amp;amp;&lt;br /&gt;                (&lt;br /&gt;                    typeProperty.PropertyType.IsValueType |&lt;br /&gt;                    typeProperty.PropertyType.FullName.Equals(&amp;quot;System.String&amp;quot;)&lt;br /&gt;                );&lt;br /&gt; &lt;br /&gt;    // Proceed only if toReturn is still true ;&lt;br /&gt;    // Also, the following applies to only entire properties&lt;br /&gt;    if (toReturn &amp;amp; entireProperty)&lt;br /&gt;    {&lt;br /&gt;        object reflectedValue = typeProperty.GetValue(profileProperty, null);&lt;br /&gt;        string strReflectedValue = (reflectedValue == null) ? String.Empty : reflectedValue.ToString();&lt;br /&gt;        toReturn &amp;amp;= !strReflectedValue.Equals(&amp;quot;UserProfile_GUID&amp;quot;);&lt;br /&gt;        toReturn &amp;amp;= !strReflectedValue.StartsWith(&amp;quot;SPS-&amp;quot;);&lt;br /&gt;    }&lt;br /&gt;    return toReturn;&lt;br /&gt;}&lt;br /&gt;The full Export Profiles method looks like this - &lt;br /&gt; &lt;br /&gt;internal static void ExportProfiles(ProgramInputs inputs, UserProfileManager profileManager)&lt;br /&gt;{&lt;br /&gt;    // Variable Naming convention: &amp;lt;objectinConcern&amp;gt;&amp;lt;Property/Properties&amp;gt;&lt;br /&gt; &lt;br /&gt;    PropertyCollection profileProperties = profileManager.Properties;&lt;br /&gt; &lt;br /&gt;    XmlDocument exportProperties = new XmlDocument();&lt;br /&gt;    XmlNode nodeProperties = exportProperties.CreateNode(XmlNodeType.Element, &amp;quot;Properties&amp;quot;, &amp;quot;&amp;quot;);&lt;br /&gt;    exportProperties.AppendChild(nodeProperties);&lt;br /&gt; &lt;br /&gt;    PropertyInfo[] allProps = typeof(Property).GetProperties();&lt;br /&gt;    Dictionary&amp;lt;string, PropertyInfo&amp;gt; typeProperties = new Dictionary&amp;lt;string, PropertyInfo&amp;gt;();&lt;br /&gt;    foreach (PropertyInfo typeProperty in allProps)&lt;br /&gt;    {&lt;br /&gt;        typeProperties.Add(typeProperty.Name, typeProperty);&lt;br /&gt;    }&lt;br /&gt; &lt;br /&gt;    foreach (Property profileProperty in profileProperties)&lt;br /&gt;    {&lt;br /&gt;        // Should I be even exporting this property?&lt;br /&gt;        bool isExportable = ShouldExport(typeProperties&lt;a href="http://www.codeplex.com/MOSSProfileReplicate/Wiki/View.aspx?title=%22Name%22"&gt;&amp;quot;Name&amp;quot;&lt;/a&gt;, profileProperty, true);&lt;br /&gt; &lt;br /&gt;        if (isExportable)&lt;br /&gt;        {&lt;br /&gt;            XmlNode nodeProperty = exportProperties.CreateNode(XmlNodeType.Element, &amp;quot;Property&amp;quot;, &amp;quot;&amp;quot;);&lt;br /&gt;            nodeProperties.AppendChild(nodeProperty);&lt;br /&gt; &lt;br /&gt;            foreach (PropertyInfo typeProperty in typeProperties.Values)&lt;br /&gt;            {&lt;br /&gt;                if (ShouldExport(typeProperty, profileProperty, false))&lt;br /&gt;                {&lt;br /&gt;                    XmlNode nodePropertyInfo = exportProperties.CreateNode(XmlNodeType.Element, &amp;quot;PropertyInfo&amp;quot;, &amp;quot;&amp;quot;);&lt;br /&gt; &lt;br /&gt;                    XmlAttribute attribProfilePropInfo;&lt;br /&gt;                    object reflectedValue;&lt;br /&gt; &lt;br /&gt;                    //Name&lt;br /&gt;                    attribProfilePropInfo = exportProperties.CreateNode(XmlNodeType.Attribute, &amp;quot;Name&amp;quot;, &amp;quot;&amp;quot;) as XmlAttribute;&lt;br /&gt;                    attribProfilePropInfo.Value = typeProperty.Name;&lt;br /&gt;                    nodePropertyInfo.Attributes.Append(attribProfilePropInfo);&lt;br /&gt; &lt;br /&gt;                    // Data Type&lt;br /&gt;                    attribProfilePropInfo = exportProperties.CreateNode(XmlNodeType.Attribute, &amp;quot;Type&amp;quot;, &amp;quot;&amp;quot;) as XmlAttribute;&lt;br /&gt;                    attribProfilePropInfo.Value = typeProperty.PropertyType.AssemblyQualifiedName;&lt;br /&gt;                    nodePropertyInfo.Attributes.Append(attribProfilePropInfo);&lt;br /&gt; &lt;br /&gt;                    // Value&lt;br /&gt;                    attribProfilePropInfo = exportProperties.CreateNode(XmlNodeType.Attribute, &amp;quot;Data&amp;quot;, &amp;quot;&amp;quot;) as XmlAttribute;&lt;br /&gt;                    reflectedValue = typeProperty.GetValue(profileProperty, null);&lt;br /&gt;                    attribProfilePropInfo.Value = (reflectedValue == null) ? String.Empty : reflectedValue.ToString();&lt;br /&gt;                    nodePropertyInfo.Attributes.Append(attribProfilePropInfo);&lt;br /&gt; &lt;br /&gt;                    nodeProperty.AppendChild(nodePropertyInfo);&lt;br /&gt;                }&lt;br /&gt;            }&lt;br /&gt;        }&lt;br /&gt;    }&lt;br /&gt; &lt;br /&gt;    exportProperties.Save(inputs.FileName);&lt;br /&gt;}&lt;br /&gt;The ImportProfiles method is the exact anti-thesis of the above, so I am not going to bother copy pasting that here.&lt;br /&gt;
&lt;/div&gt;</description><author>alogan</author><pubDate>Mon, 15 Jan 2007 08:47:36 GMT</pubDate><guid isPermaLink="false">UPDATED WIKI: Home 20070115084736A</guid></item><item><title>UPDATED WIKI: Home</title><link>http://www.codeplex.com/MOSSProfileReplicate/Wiki/View.aspx?title=Home&amp;version=10</link><description>&lt;div class="wikidoc"&gt;
The &amp;#34;SharePoint 2007 Shared Services Provider User Profile Property Replicator&amp;#34; was designed to take custom user profile properties and export&amp;#47;import them into another MOSS 2007 server.&amp;#13;&amp;#10;During most development cycles you will create custom user profile properties and currently the only way to move these from DEV&amp;#47;TEST&amp;#47;PROD is to backup&amp;#47;restore the Shared Services Provider.&amp;#13;&amp;#10;This tool will now reduce the amount of manual interaction required.
&lt;br /&gt; &lt;br /&gt;Recommended Reading/Basics before you dive into this blog post: &lt;a href="http://blah.winsmarts.com/2007-1-User_Profiles_and_Audience_Targeting.aspx" class="externalLink"&gt;http://blah.winsmarts.com/2007-1-User_Profiles_and_Audience_Targeting.aspx&lt;/a&gt;.&lt;br /&gt; &lt;br /&gt;&lt;b&gt;What is this utility?&lt;/b&gt;&lt;br /&gt;This is a command line utility that will allow you to manage profile properties setup on a SharePoint web's SharedService provider. It allows you to export properties from an SSP to XML, and vice versa.&lt;br /&gt; &lt;br /&gt;&lt;b&gt;How to use this utility?&lt;/b&gt;&lt;br /&gt;The utility comes with online help. Just type in &amp;quot;ProfilePropertyMgr -help&amp;quot; at commandline to get the help screen. The help screen reproduced below for your pleasure -&lt;br /&gt; &lt;br /&gt;=================================================&lt;br /&gt;&lt;b&gt;Profile Property Manager - Help&lt;/b&gt;&lt;br /&gt;================================================= &lt;br /&gt; &lt;br /&gt;&lt;b&gt;Usage:&lt;/b&gt; ProfilePropertyMgr -url &amp;lt;UrlToWeb&amp;gt; -filename &amp;lt;FileName&amp;gt; -import&lt;br /&gt;ProfilePropertyMgr -url &amp;lt;UrlToWeb&amp;gt; -filename &amp;lt;FileName&amp;gt; -export &lt;br /&gt; &lt;br /&gt;or &lt;br /&gt; &lt;br /&gt;ProfilePropertyMgr -help &lt;br /&gt; &lt;br /&gt;&lt;b&gt;Used For&lt;/b&gt;&lt;br /&gt;Export Profile properties from SharePoint to an XML file.&lt;br /&gt;Import Profile properties from an XML file to SharePoint. &lt;br /&gt; &lt;br /&gt;&lt;b&gt;Required Parameters are:&lt;/b&gt;&lt;br /&gt;-url &amp;lt;UrlToWeb&amp;gt;&lt;br /&gt;-file &amp;lt;FileName.xml&amp;gt; &lt;br /&gt; &lt;br /&gt;&lt;b&gt;XML File structure:&lt;/b&gt;&lt;br /&gt;&amp;lt;Properties&amp;gt;&lt;br /&gt;  &amp;lt;Property&amp;gt;&lt;br /&gt;    &amp;lt;PropertyInfo Name=&amp;quot; Type=&amp;quot; Data=&amp;quot;/&amp;gt;&lt;br /&gt;    &amp;lt;PropertyInfo ..&amp;gt;&lt;br /&gt;    ...&lt;br /&gt;  &amp;lt;/Property&amp;gt;&lt;br /&gt;  &amp;lt;Property&amp;gt;...&amp;lt;/Property&amp;gt;&lt;br /&gt;  ...&lt;br /&gt;&amp;lt;/Properties&amp;gt; &lt;br /&gt; &lt;br /&gt;&lt;b&gt;Sample usage:&lt;/b&gt;&lt;br /&gt;&lt;ul&gt;
&lt;li&gt;ProfilePropertyMgr -url http://moss2007 -filename output.xml -export&lt;/li&gt;&lt;li&gt;ProfilePropertyMgr -url http://moss2007 -filename input.xml -import &lt;/li&gt;
&lt;/ul&gt; &lt;br /&gt;&lt;b&gt;Code Explanation&lt;/b&gt;&lt;br /&gt;The code accepts input as command line parameters, and passes them to a business object called ProgramInputs as shown below: &lt;br /&gt; &lt;br /&gt;static void Main(string[] args)&lt;br /&gt;{&lt;br /&gt;    ProgramInputs inputs = new ProgramInputs(args);&lt;br /&gt; &lt;br /&gt;&lt;i&gt;The ProgramInputs business object has 3 properties - Boolean &amp;quot;IsValid&amp;quot;, String &amp;quot;URL&amp;quot;, and &amp;quot;CurrentOperation&amp;quot;. CurrentOperation is a custom enum with 3 possible valies - Unspecified, Import and Export. ProgramInputs encapsulates the functionality to validate inputs, and tell the end user if the inputs are accepted, or what was missing.&lt;/i&gt;&lt;br /&gt; &lt;br /&gt;Once we know that the inputs are valid, we can act upon them. This is done using the following code&lt;br /&gt; &lt;br /&gt;if (inputs.IsValid)&lt;br /&gt;{&lt;br /&gt;  ...&lt;br /&gt;}&lt;br /&gt;else&lt;br /&gt;{&lt;br /&gt;    Trace.WriteLine(&amp;quot;Invalid inputs specified&amp;quot;, true);&lt;br /&gt;    Trace.PrintHelp();&lt;br /&gt;}&lt;br /&gt; &lt;br /&gt;And the actual code looks like this - &lt;br /&gt; &lt;br /&gt;using (SPSite site = new SPSite(inputs.Url))&lt;br /&gt;{&lt;br /&gt;    ServerContext context = ServerContext.GetContext(site);&lt;br /&gt;    UserProfileManager profileManager = new UserProfileManager(context);&lt;br /&gt; &lt;br /&gt;    switch (inputs.CurrentOperation)&lt;br /&gt;    {&lt;br /&gt;        case Operation.Unspecified:&lt;br /&gt;            throw new InvalidOperationException(&amp;quot;Invalid input operation specified, or input operation omitted, cannot continue&amp;quot;);&lt;br /&gt;        case Operation.Import:&lt;br /&gt;            WorkerBee.ImportProfiles(inputs, profileManager);&lt;br /&gt;            break;&lt;br /&gt;        case Operation.Export:&lt;br /&gt;            WorkerBee.ExportProfiles(inputs, profileManager);&lt;br /&gt;            break;&lt;br /&gt;        default: // This will never happen, so safely ignored.&lt;br /&gt;            break;&lt;br /&gt;    }&lt;br /&gt;}&lt;br /&gt; &lt;br /&gt;As you would note from the above, the work is delegated to a class called WorkerBee. It has two methods, one to export, and one to import. I first get a hold of all the SharePoint properties using ProfileManager.Properties, and then I use reflection to sniff out which properties are exportable. Basically, anything that can be succesfully imported on the other end, is exportable on this end (duh!). So what is importable/exportable? Anything that is Read/Write, is value-type (or string), and doesn't start with &amp;quot;SSP-&amp;quot; (reserved for SharePoint), or isn't the reserved UserProfile_GUID property column. This in C#, is described as below - &lt;br /&gt; &lt;br /&gt;private static bool ShouldExport(PropertyInfo typeProperty, Property profileProperty, bool entireProperty)&lt;br /&gt;{&lt;br /&gt;    bool toReturn = false;&lt;br /&gt; &lt;br /&gt;    toReturn = typeProperty.CanRead &amp;amp; typeProperty.CanWrite &amp;amp;&lt;br /&gt;                (&lt;br /&gt;                    typeProperty.PropertyType.IsValueType |&lt;br /&gt;                    typeProperty.PropertyType.FullName.Equals(&amp;quot;System.String&amp;quot;)&lt;br /&gt;                );&lt;br /&gt; &lt;br /&gt;    // Proceed only if toReturn is still true ;&lt;br /&gt;    // Also, the following applies to only entire properties&lt;br /&gt;    if (toReturn &amp;amp; entireProperty)&lt;br /&gt;    {&lt;br /&gt;        object reflectedValue = typeProperty.GetValue(profileProperty, null);&lt;br /&gt;        string strReflectedValue = (reflectedValue == null) ? String.Empty : reflectedValue.ToString();&lt;br /&gt;        toReturn &amp;amp;= !strReflectedValue.Equals(&amp;quot;UserProfile_GUID&amp;quot;);&lt;br /&gt;        toReturn &amp;amp;= !strReflectedValue.StartsWith(&amp;quot;SPS-&amp;quot;);&lt;br /&gt;    }&lt;br /&gt;    return toReturn;&lt;br /&gt;}&lt;br /&gt;The full Export Profiles method looks like this - &lt;br /&gt; &lt;br /&gt;internal static void ExportProfiles(ProgramInputs inputs, UserProfileManager profileManager)&lt;br /&gt;{&lt;br /&gt;    // Variable Naming convention: &amp;lt;objectinConcern&amp;gt;&amp;lt;Property/Properties&amp;gt;&lt;br /&gt; &lt;br /&gt;    PropertyCollection profileProperties = profileManager.Properties;&lt;br /&gt; &lt;br /&gt;    XmlDocument exportProperties = new XmlDocument();&lt;br /&gt;    XmlNode nodeProperties = exportProperties.CreateNode(XmlNodeType.Element, &amp;quot;Properties&amp;quot;, &amp;quot;&amp;quot;);&lt;br /&gt;    exportProperties.AppendChild(nodeProperties);&lt;br /&gt; &lt;br /&gt;    PropertyInfo[] allProps = typeof(Property).GetProperties();&lt;br /&gt;    Dictionary&amp;lt;string, PropertyInfo&amp;gt; typeProperties = new Dictionary&amp;lt;string, PropertyInfo&amp;gt;();&lt;br /&gt;    foreach (PropertyInfo typeProperty in allProps)&lt;br /&gt;    {&lt;br /&gt;        typeProperties.Add(typeProperty.Name, typeProperty);&lt;br /&gt;    }&lt;br /&gt; &lt;br /&gt;    foreach (Property profileProperty in profileProperties)&lt;br /&gt;    {&lt;br /&gt;        // Should I be even exporting this property?&lt;br /&gt;        bool isExportable = ShouldExport(typeProperties&lt;a href="http://www.codeplex.com/MOSSProfileReplicate/Wiki/View.aspx?title=%22Name%22"&gt;&amp;quot;Name&amp;quot;&lt;/a&gt;, profileProperty, true);&lt;br /&gt; &lt;br /&gt;        if (isExportable)&lt;br /&gt;        {&lt;br /&gt;            XmlNode nodeProperty = exportProperties.CreateNode(XmlNodeType.Element, &amp;quot;Property&amp;quot;, &amp;quot;&amp;quot;);&lt;br /&gt;            nodeProperties.AppendChild(nodeProperty);&lt;br /&gt; &lt;br /&gt;            foreach (PropertyInfo typeProperty in typeProperties.Values)&lt;br /&gt;            {&lt;br /&gt;                if (ShouldExport(typeProperty, profileProperty, false))&lt;br /&gt;                {&lt;br /&gt;                    XmlNode nodePropertyInfo = exportProperties.CreateNode(XmlNodeType.Element, &amp;quot;PropertyInfo&amp;quot;, &amp;quot;&amp;quot;);&lt;br /&gt; &lt;br /&gt;                    XmlAttribute attribProfilePropInfo;&lt;br /&gt;                    object reflectedValue;&lt;br /&gt; &lt;br /&gt;                    //Name&lt;br /&gt;                    attribProfilePropInfo = exportProperties.CreateNode(XmlNodeType.Attribute, &amp;quot;Name&amp;quot;, &amp;quot;&amp;quot;) as XmlAttribute;&lt;br /&gt;                    attribProfilePropInfo.Value = typeProperty.Name;&lt;br /&gt;                    nodePropertyInfo.Attributes.Append(attribProfilePropInfo);&lt;br /&gt; &lt;br /&gt;                    // Data Type&lt;br /&gt;                    attribProfilePropInfo = exportProperties.CreateNode(XmlNodeType.Attribute, &amp;quot;Type&amp;quot;, &amp;quot;&amp;quot;) as XmlAttribute;&lt;br /&gt;                    attribProfilePropInfo.Value = typeProperty.PropertyType.AssemblyQualifiedName;&lt;br /&gt;                    nodePropertyInfo.Attributes.Append(attribProfilePropInfo);&lt;br /&gt; &lt;br /&gt;                    // Value&lt;br /&gt;                    attribProfilePropInfo = exportProperties.CreateNode(XmlNodeType.Attribute, &amp;quot;Data&amp;quot;, &amp;quot;&amp;quot;) as XmlAttribute;&lt;br /&gt;                    reflectedValue = typeProperty.GetValue(profileProperty, null);&lt;br /&gt;                    attribProfilePropInfo.Value = (reflectedValue == null) ? String.Empty : reflectedValue.ToString();&lt;br /&gt;                    nodePropertyInfo.Attributes.Append(attribProfilePropInfo);&lt;br /&gt; &lt;br /&gt;                    nodeProperty.AppendChild(nodePropertyInfo);&lt;br /&gt;                }&lt;br /&gt;            }&lt;br /&gt;        }&lt;br /&gt;    }&lt;br /&gt; &lt;br /&gt;    exportProperties.Save(inputs.FileName);&lt;br /&gt;}&lt;br /&gt;The ImportProfiles method is the exact anti-thesis of the above, so I am not going to bother copy pasting that here.&lt;br /&gt;
&lt;/div&gt;</description><author>alogan</author><pubDate>Mon, 15 Jan 2007 08:47:26 GMT</pubDate><guid isPermaLink="false">UPDATED WIKI: Home 20070115084726A</guid></item><item><title>UPDATED WIKI: Home</title><link>http://www.codeplex.com/MOSSProfileReplicate/Wiki/View.aspx?title=Home&amp;version=9</link><description>&lt;div class="wikidoc"&gt;
The &amp;#34;SharePoint 2007 Shared Services Provider User Profile Property Replicator&amp;#34; was designed to take custom user profile properties and export&amp;#47;import them into another MOSS 2007 server.&amp;#13;&amp;#10;During most development cycles you will create custom user profile properties and currently the only way to move these from DEV&amp;#47;TEST&amp;#47;PROD is to backup&amp;#47;restore the Shared Services Provider.&amp;#13;&amp;#10;This tool will now reduce the amount of manual interaction required.
&lt;br /&gt; &lt;br /&gt;Recommended Reading/Basics before you dive into this blog post: &lt;a href="http://blah.winsmarts.com/2007-1-User_Profiles_and_Audience_Targeting.aspx" class="externalLink"&gt;http://blah.winsmarts.com/2007-1-User_Profiles_and_Audience_Targeting.aspx&lt;/a&gt;.&lt;br /&gt; &lt;br /&gt;&lt;b&gt;What is this utility?&lt;/b&gt;&lt;br /&gt;This is a command line utility that will allow you to manage profile properties setup on a SharePoint web's SharedService provider. It allows you to export properties from an SSP to XML, and vice versa.&lt;br /&gt; &lt;br /&gt;&lt;b&gt;How to use this utility?&lt;/b&gt;&lt;br /&gt;The utility comes with online help. Just type in &amp;quot;ProfilePropertyMgr -help&amp;quot; at commandline to get the help screen. The help screen reproduced below for your pleasure -&lt;br /&gt; &lt;br /&gt;=================================================&lt;br /&gt;&lt;b&gt;Profile Property Manager - Help&lt;/b&gt;&lt;br /&gt;================================================= &lt;br /&gt; &lt;br /&gt;&lt;b&gt;Usage:&lt;/b&gt; ProfilePropertyMgr -url &amp;lt;UrlToWeb&amp;gt; -filename &amp;lt;FileName&amp;gt; -import&lt;br /&gt;ProfilePropertyMgr -url &amp;lt;UrlToWeb&amp;gt; -filename &amp;lt;FileName&amp;gt; -export &lt;br /&gt; &lt;br /&gt;or &lt;br /&gt; &lt;br /&gt;ProfilePropertyMgr -help &lt;br /&gt; &lt;br /&gt;&lt;b&gt;Used For&lt;/b&gt;&lt;br /&gt;Export Profile properties from SharePoint to an XML file.&lt;br /&gt;Import Profile properties from an XML file to SharePoint. &lt;br /&gt; &lt;br /&gt;&lt;b&gt;Required Parameters are:&lt;/b&gt;&lt;br /&gt;-url &amp;lt;UrlToWeb&amp;gt;&lt;br /&gt;-file &amp;lt;FileName.xml&amp;gt; &lt;br /&gt; &lt;br /&gt;&lt;b&gt;XML File structure:&lt;/b&gt;&lt;br /&gt;&amp;lt;Properties&amp;gt;&lt;br /&gt;  &amp;lt;Property&amp;gt;&lt;br /&gt;    &amp;lt;PropertyInfo Name=&amp;quot; Type=&amp;quot; Data=&amp;quot;/&amp;gt;&lt;br /&gt;    &amp;lt;PropertyInfo ..&amp;gt;&lt;br /&gt;    ...&lt;br /&gt;  &amp;lt;/Property&amp;gt;&lt;br /&gt;  &amp;lt;Property&amp;gt;...&amp;lt;/Property&amp;gt;&lt;br /&gt;  ...&lt;br /&gt;&amp;lt;/Properties&amp;gt; &lt;br /&gt; &lt;br /&gt;&lt;b&gt;Sample usage:&lt;/b&gt;&lt;br /&gt;&lt;ul&gt;
&lt;li&gt;ProfilePropertyMgr -url http://moss2007 -filename output.xml -export&lt;/li&gt;&lt;li&gt;ProfilePropertyMgr -url http://moss2007 -filename input.xml -import &lt;/li&gt;
&lt;/ul&gt; &lt;br /&gt;&lt;b&gt;Code Explanation&lt;/b&gt;&lt;br /&gt;The code accepts input as command line parameters, and passes them to a business object called ProgramInputs as shown below: &lt;br /&gt; &lt;br /&gt;static void Main(string[] args)&lt;br /&gt;{&lt;br /&gt;    ProgramInputs inputs = new ProgramInputs(args);&lt;br /&gt; &lt;br /&gt;The ProgramInputs business object has 3 properties - Boolean &amp;quot;IsValid&amp;quot;, String &amp;quot;URL&amp;quot;, and &amp;quot;CurrentOperation&amp;quot;. CurrentOperation is a custom enum with 3 possible valies - Unspecified, Import and Export. ProgramInputs encapsulates the functionality to validate inputs, and tell the end user if the inputs are accepted, or what was missing.&lt;br /&gt; &lt;br /&gt;Once we know that the inputs are valid, we can act upon them. This is done using the following code&lt;br /&gt; &lt;br /&gt;if (inputs.IsValid)&lt;br /&gt;{&lt;br /&gt;  ...&lt;br /&gt;}&lt;br /&gt;else&lt;br /&gt;{&lt;br /&gt;    Trace.WriteLine(&amp;quot;Invalid inputs specified&amp;quot;, true);&lt;br /&gt;    Trace.PrintHelp();&lt;br /&gt;}&lt;br /&gt; &lt;br /&gt;And the actual code looks like this - &lt;br /&gt; &lt;br /&gt;using (SPSite site = new SPSite(inputs.Url))&lt;br /&gt;{&lt;br /&gt;    ServerContext context = ServerContext.GetContext(site);&lt;br /&gt;    UserProfileManager profileManager = new UserProfileManager(context);&lt;br /&gt; &lt;br /&gt;    switch (inputs.CurrentOperation)&lt;br /&gt;    {&lt;br /&gt;        case Operation.Unspecified:&lt;br /&gt;            throw new InvalidOperationException(&amp;quot;Invalid input operation specified, or input operation omitted, cannot continue&amp;quot;);&lt;br /&gt;        case Operation.Import:&lt;br /&gt;            WorkerBee.ImportProfiles(inputs, profileManager);&lt;br /&gt;            break;&lt;br /&gt;        case Operation.Export:&lt;br /&gt;            WorkerBee.ExportProfiles(inputs, profileManager);&lt;br /&gt;            break;&lt;br /&gt;        default: // This will never happen, so safely ignored.&lt;br /&gt;            break;&lt;br /&gt;    }&lt;br /&gt;}&lt;br /&gt; &lt;br /&gt;As you would note from the above, the work is delegated to a class called WorkerBee. It has two methods, one to export, and one to import. I first get a hold of all the SharePoint properties using ProfileManager.Properties, and then I use reflection to sniff out which properties are exportable. Basically, anything that can be succesfully imported on the other end, is exportable on this end (duh!). So what is importable/exportable? Anything that is Read/Write, is value-type (or string), and doesn't start with &amp;quot;SSP-&amp;quot; (reserved for SharePoint), or isn't the reserved UserProfile_GUID property column. This in C#, is described as below - &lt;br /&gt; &lt;br /&gt;private static bool ShouldExport(PropertyInfo typeProperty, Property profileProperty, bool entireProperty)&lt;br /&gt;{&lt;br /&gt;    bool toReturn = false;&lt;br /&gt; &lt;br /&gt;    toReturn = typeProperty.CanRead &amp;amp; typeProperty.CanWrite &amp;amp;&lt;br /&gt;                (&lt;br /&gt;                    typeProperty.PropertyType.IsValueType |&lt;br /&gt;                    typeProperty.PropertyType.FullName.Equals(&amp;quot;System.String&amp;quot;)&lt;br /&gt;                );&lt;br /&gt; &lt;br /&gt;    // Proceed only if toReturn is still true ;&lt;br /&gt;    // Also, the following applies to only entire properties&lt;br /&gt;    if (toReturn &amp;amp; entireProperty)&lt;br /&gt;    {&lt;br /&gt;        object reflectedValue = typeProperty.GetValue(profileProperty, null);&lt;br /&gt;        string strReflectedValue = (reflectedValue == null) ? String.Empty : reflectedValue.ToString();&lt;br /&gt;        toReturn &amp;amp;= !strReflectedValue.Equals(&amp;quot;UserProfile_GUID&amp;quot;);&lt;br /&gt;        toReturn &amp;amp;= !strReflectedValue.StartsWith(&amp;quot;SPS-&amp;quot;);&lt;br /&gt;    }&lt;br /&gt;    return toReturn;&lt;br /&gt;}&lt;br /&gt;The full Export Profiles method looks like this - &lt;br /&gt; &lt;br /&gt;internal static void ExportProfiles(ProgramInputs inputs, UserProfileManager profileManager)&lt;br /&gt;{&lt;br /&gt;    // Variable Naming convention: &amp;lt;objectinConcern&amp;gt;&amp;lt;Property/Properties&amp;gt;&lt;br /&gt; &lt;br /&gt;    PropertyCollection profileProperties = profileManager.Properties;&lt;br /&gt; &lt;br /&gt;    XmlDocument exportProperties = new XmlDocument();&lt;br /&gt;    XmlNode nodeProperties = exportProperties.CreateNode(XmlNodeType.Element, &amp;quot;Properties&amp;quot;, &amp;quot;&amp;quot;);&lt;br /&gt;    exportProperties.AppendChild(nodeProperties);&lt;br /&gt; &lt;br /&gt;    PropertyInfo[] allProps = typeof(Property).GetProperties();&lt;br /&gt;    Dictionary&amp;lt;string, PropertyInfo&amp;gt; typeProperties = new Dictionary&amp;lt;string, PropertyInfo&amp;gt;();&lt;br /&gt;    foreach (PropertyInfo typeProperty in allProps)&lt;br /&gt;    {&lt;br /&gt;        typeProperties.Add(typeProperty.Name, typeProperty);&lt;br /&gt;    }&lt;br /&gt; &lt;br /&gt;    foreach (Property profileProperty in profileProperties)&lt;br /&gt;    {&lt;br /&gt;        // Should I be even exporting this property?&lt;br /&gt;        bool isExportable = ShouldExport(typeProperties&lt;a href="http://www.codeplex.com/MOSSProfileReplicate/Wiki/View.aspx?title=%22Name%22"&gt;&amp;quot;Name&amp;quot;&lt;/a&gt;, profileProperty, true);&lt;br /&gt; &lt;br /&gt;        if (isExportable)&lt;br /&gt;        {&lt;br /&gt;            XmlNode nodeProperty = exportProperties.CreateNode(XmlNodeType.Element, &amp;quot;Property&amp;quot;, &amp;quot;&amp;quot;);&lt;br /&gt;            nodeProperties.AppendChild(nodeProperty);&lt;br /&gt; &lt;br /&gt;            foreach (PropertyInfo typeProperty in typeProperties.Values)&lt;br /&gt;            {&lt;br /&gt;                if (ShouldExport(typeProperty, profileProperty, false))&lt;br /&gt;                {&lt;br /&gt;                    XmlNode nodePropertyInfo = exportProperties.CreateNode(XmlNodeType.Element, &amp;quot;PropertyInfo&amp;quot;, &amp;quot;&amp;quot;);&lt;br /&gt; &lt;br /&gt;                    XmlAttribute attribProfilePropInfo;&lt;br /&gt;                    object reflectedValue;&lt;br /&gt; &lt;br /&gt;                    //Name&lt;br /&gt;                    attribProfilePropInfo = exportProperties.CreateNode(XmlNodeType.Attribute, &amp;quot;Name&amp;quot;, &amp;quot;&amp;quot;) as XmlAttribute;&lt;br /&gt;                    attribProfilePropInfo.Value = typeProperty.Name;&lt;br /&gt;                    nodePropertyInfo.Attributes.Append(attribProfilePropInfo);&lt;br /&gt; &lt;br /&gt;                    // Data Type&lt;br /&gt;                    attribProfilePropInfo = exportProperties.CreateNode(XmlNodeType.Attribute, &amp;quot;Type&amp;quot;, &amp;quot;&amp;quot;) as XmlAttribute;&lt;br /&gt;                    attribProfilePropInfo.Value = typeProperty.PropertyType.AssemblyQualifiedName;&lt;br /&gt;                    nodePropertyInfo.Attributes.Append(attribProfilePropInfo);&lt;br /&gt; &lt;br /&gt;                    // Value&lt;br /&gt;                    attribProfilePropInfo = exportProperties.CreateNode(XmlNodeType.Attribute, &amp;quot;Data&amp;quot;, &amp;quot;&amp;quot;) as XmlAttribute;&lt;br /&gt;                    reflectedValue = typeProperty.GetValue(profileProperty, null);&lt;br /&gt;                    attribProfilePropInfo.Value = (reflectedValue == null) ? String.Empty : reflectedValue.ToString();&lt;br /&gt;                    nodePropertyInfo.Attributes.Append(attribProfilePropInfo);&lt;br /&gt; &lt;br /&gt;                    nodeProperty.AppendChild(nodePropertyInfo);&lt;br /&gt;                }&lt;br /&gt;            }&lt;br /&gt;        }&lt;br /&gt;    }&lt;br /&gt; &lt;br /&gt;    exportProperties.Save(inputs.FileName);&lt;br /&gt;}&lt;br /&gt;The ImportProfiles method is the exact anti-thesis of the above, so I am not going to bother copy pasting that here.&lt;br /&gt;
&lt;/div&gt;</description><author>alogan</author><pubDate>Mon, 15 Jan 2007 08:47:06 GMT</pubDate><guid isPermaLink="false">UPDATED WIKI: Home 20070115084706A</guid></item><item><title>UPDATED WIKI: Home</title><link>http://www.codeplex.com/MOSSProfileReplicate/Wiki/View.aspx?title=Home&amp;version=8</link><description>&lt;div class="wikidoc"&gt;
The &amp;#34;SharePoint 2007 Shared Services Provider User Profile Property Replicator&amp;#34; was designed to take custom user profile properties and export&amp;#47;import them into another MOSS 2007 server.&amp;#13;&amp;#10;During most development cycles you will create custom user profile properties and currently the only way to move these from DEV&amp;#47;TEST&amp;#47;PROD is to backup&amp;#47;restore the Shared Services Provider.&amp;#13;&amp;#10;This tool will now reduce the amount of manual interaction required.
&lt;br /&gt; &lt;br /&gt;Recommended Reading/Basics before you dive into this blog post: &lt;a href="http://blah.winsmarts.com/2007-1-User_Profiles_and_Audience_Targeting.aspx" class="externalLink"&gt;http://blah.winsmarts.com/2007-1-User_Profiles_and_Audience_Targeting.aspx&lt;/a&gt;.&lt;br /&gt; &lt;br /&gt;&lt;b&gt;What is this utility?&lt;/b&gt;&lt;br /&gt;This is a command line utility that will allow you to manage profile properties setup on a SharePoint web's SharedService provider. It allows you to export properties from an SSP to XML, and vice versa.&lt;br /&gt; &lt;br /&gt;&lt;b&gt;How to use this utility?&lt;/b&gt;&lt;br /&gt;The utility comes with online help. Just type in &amp;quot;ProfilePropertyMgr -help&amp;quot; at commandline to get the help screen. The help screen reproduced below for your pleasure -&lt;br /&gt; &lt;br /&gt;=================================================&lt;br /&gt;&lt;b&gt;Profile Property Manager - Help&lt;/b&gt;&lt;br /&gt;================================================= &lt;br /&gt; &lt;br /&gt;&lt;b&gt;Usage:&lt;/b&gt; ProfilePropertyMgr -url &amp;lt;UrlToWeb&amp;gt; -filename &amp;lt;FileName&amp;gt; -import&lt;br /&gt;ProfilePropertyMgr -url &amp;lt;UrlToWeb&amp;gt; -filename &amp;lt;FileName&amp;gt; -export &lt;br /&gt; &lt;br /&gt;or &lt;br /&gt; &lt;br /&gt;ProfilePropertyMgr -help &lt;br /&gt; &lt;br /&gt;&lt;b&gt;Used For&lt;/b&gt;&lt;br /&gt;Export Profile properties from SharePoint to an XML file.&lt;br /&gt;Import Profile properties from an XML file to SharePoint. &lt;br /&gt; &lt;br /&gt;&lt;b&gt;Required Parameters are:&lt;/b&gt;&lt;br /&gt;-url &amp;lt;UrlToWeb&amp;gt;&lt;br /&gt;-file &amp;lt;FileName.xml&amp;gt; &lt;br /&gt; &lt;br /&gt;&lt;b&gt;XML File structure:&lt;/b&gt;&lt;br /&gt;&amp;lt;Properties&amp;gt;&lt;br /&gt;  &amp;lt;Property&amp;gt;&lt;br /&gt;    &amp;lt;PropertyInfo Name=&amp;quot; Type=&amp;quot; Data=&amp;quot;/&amp;gt;&lt;br /&gt;    &amp;lt;PropertyInfo ..&amp;gt;&lt;br /&gt;    ...&lt;br /&gt;  &amp;lt;/Property&amp;gt;&lt;br /&gt;  &amp;lt;Property&amp;gt;...&amp;lt;/Property&amp;gt;&lt;br /&gt;  ...&lt;br /&gt;&amp;lt;/Properties&amp;gt; &lt;br /&gt; &lt;br /&gt;&lt;b&gt;Sample usage:&lt;/b&gt;&lt;br /&gt;&lt;ul&gt;
&lt;li&gt;ProfilePropertyMgr -url http://moss2007 -filename output.xml -export&lt;/li&gt;&lt;li&gt;ProfilePropertyMgr -url http://moss2007 -filename input.xml -import &lt;/li&gt;
&lt;/ul&gt; &lt;br /&gt;&lt;b&gt;Code Explanation&lt;/b&gt;&lt;br /&gt;The code accepts input as command line parameters, and passes them to a business object called ProgramInputs as shown below: &lt;br /&gt; &lt;br /&gt;_static void Main(string[] args)&lt;br /&gt;{&lt;br /&gt;    ProgramInputs inputs = new ProgramInputs(args);_&lt;br /&gt; &lt;br /&gt;The ProgramInputs business object has 3 properties - Boolean &amp;quot;IsValid&amp;quot;, String &amp;quot;URL&amp;quot;, and &amp;quot;CurrentOperation&amp;quot;. CurrentOperation is a custom enum with 3 possible valies - Unspecified, Import and Export. ProgramInputs encapsulates the functionality to validate inputs, and tell the end user if the inputs are accepted, or what was missing.&lt;br /&gt; &lt;br /&gt;Once we know that the inputs are valid, we can act upon them. This is done using the following code&lt;br /&gt; &lt;br /&gt;if (inputs.IsValid)&lt;br /&gt;{&lt;br /&gt;  ...&lt;br /&gt;}&lt;br /&gt;else&lt;br /&gt;{&lt;br /&gt;    Trace.WriteLine(&amp;quot;Invalid inputs specified&amp;quot;, true);&lt;br /&gt;    Trace.PrintHelp();&lt;br /&gt;}&lt;br /&gt; &lt;br /&gt;And the actual code looks like this - &lt;br /&gt; &lt;br /&gt;using (SPSite site = new SPSite(inputs.Url))&lt;br /&gt;{&lt;br /&gt;    ServerContext context = ServerContext.GetContext(site);&lt;br /&gt;    UserProfileManager profileManager = new UserProfileManager(context);&lt;br /&gt; &lt;br /&gt;    switch (inputs.CurrentOperation)&lt;br /&gt;    {&lt;br /&gt;        case Operation.Unspecified:&lt;br /&gt;            throw new InvalidOperationException(&amp;quot;Invalid input operation specified, or input operation omitted, cannot continue&amp;quot;);&lt;br /&gt;        case Operation.Import:&lt;br /&gt;            WorkerBee.ImportProfiles(inputs, profileManager);&lt;br /&gt;            break;&lt;br /&gt;        case Operation.Export:&lt;br /&gt;            WorkerBee.ExportProfiles(inputs, profileManager);&lt;br /&gt;            break;&lt;br /&gt;        default: // This will never happen, so safely ignored.&lt;br /&gt;            break;&lt;br /&gt;    }&lt;br /&gt;}&lt;br /&gt; &lt;br /&gt;As you would note from the above, the work is delegated to a class called WorkerBee. It has two methods, one to export, and one to import. I first get a hold of all the SharePoint properties using ProfileManager.Properties, and then I use reflection to sniff out which properties are exportable. Basically, anything that can be succesfully imported on the other end, is exportable on this end (duh!). So what is importable/exportable? Anything that is Read/Write, is value-type (or string), and doesn't start with &amp;quot;SSP-&amp;quot; (reserved for SharePoint), or isn't the reserved UserProfile_GUID property column. This in C#, is described as below - &lt;br /&gt; &lt;br /&gt;private static bool ShouldExport(PropertyInfo typeProperty, Property profileProperty, bool entireProperty)&lt;br /&gt;{&lt;br /&gt;    bool toReturn = false;&lt;br /&gt; &lt;br /&gt;    toReturn = typeProperty.CanRead &amp;amp; typeProperty.CanWrite &amp;amp;&lt;br /&gt;                (&lt;br /&gt;                    typeProperty.PropertyType.IsValueType |&lt;br /&gt;                    typeProperty.PropertyType.FullName.Equals(&amp;quot;System.String&amp;quot;)&lt;br /&gt;                );&lt;br /&gt; &lt;br /&gt;    // Proceed only if toReturn is still true ;&lt;br /&gt;    // Also, the following applies to only entire properties&lt;br /&gt;    if (toReturn &amp;amp; entireProperty)&lt;br /&gt;    {&lt;br /&gt;        object reflectedValue = typeProperty.GetValue(profileProperty, null);&lt;br /&gt;        string strReflectedValue = (reflectedValue == null) ? String.Empty : reflectedValue.ToString();&lt;br /&gt;        toReturn &amp;amp;= !strReflectedValue.Equals(&amp;quot;UserProfile_GUID&amp;quot;);&lt;br /&gt;        toReturn &amp;amp;= !strReflectedValue.StartsWith(&amp;quot;SPS-&amp;quot;);&lt;br /&gt;    }&lt;br /&gt;    return toReturn;&lt;br /&gt;}&lt;br /&gt;The full Export Profiles method looks like this - &lt;br /&gt; &lt;br /&gt;internal static void ExportProfiles(ProgramInputs inputs, UserProfileManager profileManager)&lt;br /&gt;{&lt;br /&gt;    // Variable Naming convention: &amp;lt;objectinConcern&amp;gt;&amp;lt;Property/Properties&amp;gt;&lt;br /&gt; &lt;br /&gt;    PropertyCollection profileProperties = profileManager.Properties;&lt;br /&gt; &lt;br /&gt;    XmlDocument exportProperties = new XmlDocument();&lt;br /&gt;    XmlNode nodeProperties = exportProperties.CreateNode(XmlNodeType.Element, &amp;quot;Properties&amp;quot;, &amp;quot;&amp;quot;);&lt;br /&gt;    exportProperties.AppendChild(nodeProperties);&lt;br /&gt; &lt;br /&gt;    PropertyInfo[] allProps = typeof(Property).GetProperties();&lt;br /&gt;    Dictionary&amp;lt;string, PropertyInfo&amp;gt; typeProperties = new Dictionary&amp;lt;string, PropertyInfo&amp;gt;();&lt;br /&gt;    foreach (PropertyInfo typeProperty in allProps)&lt;br /&gt;    {&lt;br /&gt;        typeProperties.Add(typeProperty.Name, typeProperty);&lt;br /&gt;    }&lt;br /&gt; &lt;br /&gt;    foreach (Property profileProperty in profileProperties)&lt;br /&gt;    {&lt;br /&gt;        // Should I be even exporting this property?&lt;br /&gt;        bool isExportable = ShouldExport(typeProperties&lt;a href="http://www.codeplex.com/MOSSProfileReplicate/Wiki/View.aspx?title=%22Name%22"&gt;&amp;quot;Name&amp;quot;&lt;/a&gt;, profileProperty, true);&lt;br /&gt; &lt;br /&gt;        if (isExportable)&lt;br /&gt;        {&lt;br /&gt;            XmlNode nodeProperty = exportProperties.CreateNode(XmlNodeType.Element, &amp;quot;Property&amp;quot;, &amp;quot;&amp;quot;);&lt;br /&gt;            nodeProperties.AppendChild(nodeProperty);&lt;br /&gt; &lt;br /&gt;            foreach (PropertyInfo typeProperty in typeProperties.Values)&lt;br /&gt;            {&lt;br /&gt;                if (ShouldExport(typeProperty, profileProperty, false))&lt;br /&gt;                {&lt;br /&gt;                    XmlNode nodePropertyInfo = exportProperties.CreateNode(XmlNodeType.Element, &amp;quot;PropertyInfo&amp;quot;, &amp;quot;&amp;quot;);&lt;br /&gt; &lt;br /&gt;                    XmlAttribute attribProfilePropInfo;&lt;br /&gt;                    object reflectedValue;&lt;br /&gt; &lt;br /&gt;                    //Name&lt;br /&gt;                    attribProfilePropInfo = exportProperties.CreateNode(XmlNodeType.Attribute, &amp;quot;Name&amp;quot;, &amp;quot;&amp;quot;) as XmlAttribute;&lt;br /&gt;                    attribProfilePropInfo.Value = typeProperty.Name;&lt;br /&gt;                    nodePropertyInfo.Attributes.Append(attribProfilePropInfo);&lt;br /&gt; &lt;br /&gt;                    // Data Type&lt;br /&gt;                    attribProfilePropInfo = exportProperties.CreateNode(XmlNodeType.Attribute, &amp;quot;Type&amp;quot;, &amp;quot;&amp;quot;) as XmlAttribute;&lt;br /&gt;                    attribProfilePropInfo.Value = typeProperty.PropertyType.AssemblyQualifiedName;&lt;br /&gt;                    nodePropertyInfo.Attributes.Append(attribProfilePropInfo);&lt;br /&gt; &lt;br /&gt;                    // Value&lt;br /&gt;                    attribProfilePropInfo = exportProperties.CreateNode(XmlNodeType.Attribute, &amp;quot;Data&amp;quot;, &amp;quot;&amp;quot;) as XmlAttribute;&lt;br /&gt;                    reflectedValue = typeProperty.GetValue(profileProperty, null);&lt;br /&gt;                    attribProfilePropInfo.Value = (reflectedValue == null) ? String.Empty : reflectedValue.ToString();&lt;br /&gt;                    nodePropertyInfo.Attributes.Append(attribProfilePropInfo);&lt;br /&gt; &lt;br /&gt;                    nodeProperty.AppendChild(nodePropertyInfo);&lt;br /&gt;                }&lt;br /&gt;            }&lt;br /&gt;        }&lt;br /&gt;    }&lt;br /&gt; &lt;br /&gt;    exportProperties.Save(inputs.FileName);&lt;br /&gt;}&lt;br /&gt;The ImportProfiles method is the exact anti-thesis of the above, so I am not going to bother copy pasting that here.&lt;br /&gt;
&lt;/div&gt;</description><author>alogan</author><pubDate>Mon, 15 Jan 2007 08:46:46 GMT</pubDate><guid isPermaLink="false">UPDATED WIKI: Home 20070115084646A</guid></item><item><title>UPDATED WIKI: Home</title><link>http://www.codeplex.com/MOSSProfileReplicate/Wiki/View.aspx?title=Home&amp;version=7</link><description>&lt;div class="wikidoc"&gt;
The &amp;#34;SharePoint 2007 Shared Services Provider User Profile Property Replicator&amp;#34; was designed to take custom user profile properties and export&amp;#47;import them into another MOSS 2007 server.&amp;#13;&amp;#10;During most development cycles you will create custom user profile properties and currently the only way to move these from DEV&amp;#47;TEST&amp;#47;PROD is to backup&amp;#47;restore the Shared Services Provider.&amp;#13;&amp;#10;This tool will now reduce the amount of manual interaction required.
&lt;br /&gt; &lt;br /&gt;Recommended Reading/Basics before you dive into this blog post: &lt;a href="http://blah.winsmarts.com/2007-1-User_Profiles_and_Audience_Targeting.aspx" class="externalLink"&gt;http://blah.winsmarts.com/2007-1-User_Profiles_and_Audience_Targeting.aspx&lt;/a&gt;.&lt;br /&gt; &lt;br /&gt;&lt;b&gt;What is this utility?&lt;/b&gt;&lt;br /&gt;This is a command line utility that will allow you to manage profile properties setup on a SharePoint web's SharedService provider. It allows you to export properties from an SSP to XML, and vice versa.&lt;br /&gt; &lt;br /&gt;&lt;b&gt;How to use this utility?&lt;/b&gt;&lt;br /&gt;The utility comes with online help. Just type in &amp;quot;ProfilePropertyMgr -help&amp;quot; at commandline to get the help screen. The help screen reproduced below for your pleasure -&lt;br /&gt; &lt;br /&gt;=================================================&lt;br /&gt;&lt;b&gt;Profile Property Manager - Help&lt;/b&gt;&lt;br /&gt;================================================= &lt;br /&gt; &lt;br /&gt;&lt;b&gt;Usage:&lt;/b&gt; ProfilePropertyMgr -url &amp;lt;UrlToWeb&amp;gt; -filename &amp;lt;FileName&amp;gt; -import&lt;br /&gt;ProfilePropertyMgr -url &amp;lt;UrlToWeb&amp;gt; -filename &amp;lt;FileName&amp;gt; -export &lt;br /&gt; &lt;br /&gt;or &lt;br /&gt; &lt;br /&gt;ProfilePropertyMgr -help &lt;br /&gt; &lt;br /&gt;&lt;b&gt;Used For&lt;/b&gt;&lt;br /&gt;Export Profile properties from SharePoint to an XML file.&lt;br /&gt;Import Profile properties from an XML file to SharePoint. &lt;br /&gt; &lt;br /&gt;&lt;b&gt;Required Parameters are:&lt;/b&gt;&lt;br /&gt;-url &amp;lt;UrlToWeb&amp;gt;&lt;br /&gt;-file &amp;lt;FileName.xml&amp;gt; &lt;br /&gt; &lt;br /&gt;&lt;b&gt;XML File structure:&lt;/b&gt;&lt;br /&gt;&amp;lt;Properties&amp;gt;&lt;br /&gt;  &amp;lt;Property&amp;gt;&lt;br /&gt;    &amp;lt;PropertyInfo Name=&amp;quot; Type=&amp;quot; Data=&amp;quot;/&amp;gt;&lt;br /&gt;    &amp;lt;PropertyInfo ..&amp;gt;&lt;br /&gt;    ...&lt;br /&gt;  &amp;lt;/Property&amp;gt;&lt;br /&gt;  &amp;lt;Property&amp;gt;...&amp;lt;/Property&amp;gt;&lt;br /&gt;  ...&lt;br /&gt;&amp;lt;/Properties&amp;gt; &lt;br /&gt; &lt;br /&gt;&lt;b&gt;Sample usage:&lt;/b&gt;&lt;br /&gt;&lt;ul&gt;
&lt;li&gt;ProfilePropertyMgr -url http://moss2007 -filename output.xml -export&lt;/li&gt;&lt;li&gt;ProfilePropertyMgr -url http://moss2007 -filename input.xml -import &lt;/li&gt;
&lt;/ul&gt; &lt;br /&gt;&lt;b&gt;Code Explanation&lt;/b&gt;&lt;br /&gt;The code accepts input as command line parameters, and passes them to a business object called ProgramInputs as shown below: &lt;br /&gt; &lt;br /&gt;_&lt;br /&gt;static void Main(string[] args)&lt;br /&gt;{&lt;br /&gt;    ProgramInputs inputs = new ProgramInputs(args);&lt;br /&gt;_&lt;br /&gt; &lt;br /&gt;The ProgramInputs business object has 3 properties - Boolean &amp;quot;IsValid&amp;quot;, String &amp;quot;URL&amp;quot;, and &amp;quot;CurrentOperation&amp;quot;. CurrentOperation is a custom enum with 3 possible valies - Unspecified, Import and Export. ProgramInputs encapsulates the functionality to validate inputs, and tell the end user if the inputs are accepted, or what was missing.&lt;br /&gt; &lt;br /&gt;Once we know that the inputs are valid, we can act upon them. This is done using the following code&lt;br /&gt; &lt;br /&gt;if (inputs.IsValid)&lt;br /&gt;{&lt;br /&gt;  ...&lt;br /&gt;}&lt;br /&gt;else&lt;br /&gt;{&lt;br /&gt;    Trace.WriteLine(&amp;quot;Invalid inputs specified&amp;quot;, true);&lt;br /&gt;    Trace.PrintHelp();&lt;br /&gt;}&lt;br /&gt; &lt;br /&gt;And the actual code looks like this - &lt;br /&gt; &lt;br /&gt;using (SPSite site = new SPSite(inputs.Url))&lt;br /&gt;{&lt;br /&gt;    ServerContext context = ServerContext.GetContext(site);&lt;br /&gt;    UserProfileManager profileManager = new UserProfileManager(context);&lt;br /&gt; &lt;br /&gt;    switch (inputs.CurrentOperation)&lt;br /&gt;    {&lt;br /&gt;        case Operation.Unspecified:&lt;br /&gt;            throw new InvalidOperationException(&amp;quot;Invalid input operation specified, or input operation omitted, cannot continue&amp;quot;);&lt;br /&gt;        case Operation.Import:&lt;br /&gt;            WorkerBee.ImportProfiles(inputs, profileManager);&lt;br /&gt;            break;&lt;br /&gt;        case Operation.Export:&lt;br /&gt;            WorkerBee.ExportProfiles(inputs, profileManager);&lt;br /&gt;            break;&lt;br /&gt;        default: // This will never happen, so safely ignored.&lt;br /&gt;            break;&lt;br /&gt;    }&lt;br /&gt;}&lt;br /&gt; &lt;br /&gt;As you would note from the above, the work is delegated to a class called WorkerBee. It has two methods, one to export, and one to import. I first get a hold of all the SharePoint properties using ProfileManager.Properties, and then I use reflection to sniff out which properties are exportable. Basically, anything that can be succesfully imported on the other end, is exportable on this end (duh!). So what is importable/exportable? Anything that is Read/Write, is value-type (or string), and doesn't start with &amp;quot;SSP-&amp;quot; (reserved for SharePoint), or isn't the reserved UserProfile_GUID property column. This in C#, is described as below - &lt;br /&gt; &lt;br /&gt;private static bool ShouldExport(PropertyInfo typeProperty, Property profileProperty, bool entireProperty)&lt;br /&gt;{&lt;br /&gt;    bool toReturn = false;&lt;br /&gt; &lt;br /&gt;    toReturn = typeProperty.CanRead &amp;amp; typeProperty.CanWrite &amp;amp;&lt;br /&gt;                (&lt;br /&gt;                    typeProperty.PropertyType.IsValueType |&lt;br /&gt;                    typeProperty.PropertyType.FullName.Equals(&amp;quot;System.String&amp;quot;)&lt;br /&gt;                );&lt;br /&gt; &lt;br /&gt;    // Proceed only if toReturn is still true ;&lt;br /&gt;    // Also, the following applies to only entire properties&lt;br /&gt;    if (toReturn &amp;amp; entireProperty)&lt;br /&gt;    {&lt;br /&gt;        object reflectedValue = typeProperty.GetValue(profileProperty, null);&lt;br /&gt;        string strReflectedValue = (reflectedValue == null) ? String.Empty : reflectedValue.ToString();&lt;br /&gt;        toReturn &amp;amp;= !strReflectedValue.Equals(&amp;quot;UserProfile_GUID&amp;quot;);&lt;br /&gt;        toReturn &amp;amp;= !strReflectedValue.StartsWith(&amp;quot;SPS-&amp;quot;);&lt;br /&gt;    }&lt;br /&gt;    return toReturn;&lt;br /&gt;}&lt;br /&gt;The full Export Profiles method looks like this - &lt;br /&gt; &lt;br /&gt;internal static void ExportProfiles(ProgramInputs inputs, UserProfileManager profileManager)&lt;br /&gt;{&lt;br /&gt;    // Variable Naming convention: &amp;lt;objectinConcern&amp;gt;&amp;lt;Property/Properties&amp;gt;&lt;br /&gt; &lt;br /&gt;    PropertyCollection profileProperties = profileManager.Properties;&lt;br /&gt; &lt;br /&gt;    XmlDocument exportProperties = new XmlDocument();&lt;br /&gt;    XmlNode nodeProperties = exportProperties.CreateNode(XmlNodeType.Element, &amp;quot;Properties&amp;quot;, &amp;quot;&amp;quot;);&lt;br /&gt;    exportProperties.AppendChild(nodeProperties);&lt;br /&gt; &lt;br /&gt;    PropertyInfo[] allProps = typeof(Property).GetProperties();&lt;br /&gt;    Dictionary&amp;lt;string, PropertyInfo&amp;gt; typeProperties = new Dictionary&amp;lt;string, PropertyInfo&amp;gt;();&lt;br /&gt;    foreach (PropertyInfo typeProperty in allProps)&lt;br /&gt;    {&lt;br /&gt;        typeProperties.Add(typeProperty.Name, typeProperty);&lt;br /&gt;    }&lt;br /&gt; &lt;br /&gt;    foreach (Property profileProperty in profileProperties)&lt;br /&gt;    {&lt;br /&gt;        // Should I be even exporting this property?&lt;br /&gt;        bool isExportable = ShouldExport(typeProperties&lt;a href="http://www.codeplex.com/MOSSProfileReplicate/Wiki/View.aspx?title=%22Name%22"&gt;&amp;quot;Name&amp;quot;&lt;/a&gt;, profileProperty, true);&lt;br /&gt; &lt;br /&gt;        if (isExportable)&lt;br /&gt;        {&lt;br /&gt;            XmlNode nodeProperty = exportProperties.CreateNode(XmlNodeType.Element, &amp;quot;Property&amp;quot;, &amp;quot;&amp;quot;);&lt;br /&gt;            nodeProperties.AppendChild(nodeProperty);&lt;br /&gt; &lt;br /&gt;            foreach (PropertyInfo typeProperty in typeProperties.Values)&lt;br /&gt;            {&lt;br /&gt;                if (ShouldExport(typeProperty, profileProperty, false))&lt;br /&gt;                {&lt;br /&gt;                    XmlNode nodePropertyInfo = exportProperties.CreateNode(XmlNodeType.Element, &amp;quot;PropertyInfo&amp;quot;, &amp;quot;&amp;quot;);&lt;br /&gt; &lt;br /&gt;                    XmlAttribute attribProfilePropInfo;&lt;br /&gt;                    object reflectedValue;&lt;br /&gt; &lt;br /&gt;                    //Name&lt;br /&gt;                    attribProfilePropInfo = exportProperties.CreateNode(XmlNodeType.Attribute, &amp;quot;Name&amp;quot;, &amp;quot;&amp;quot;) as XmlAttribute;&lt;br /&gt;                    attribProfilePropInfo.Value = typeProperty.Name;&lt;br /&gt;                    nodePropertyInfo.Attributes.Append(attribProfilePropInfo);&lt;br /&gt; &lt;br /&gt;                    // Data Type&lt;br /&gt;                    attribProfilePropInfo = exportProperties.CreateNode(XmlNodeType.Attribute, &amp;quot;Type&amp;quot;, &amp;quot;&amp;quot;) as XmlAttribute;&lt;br /&gt;                    attribProfilePropInfo.Value = typeProperty.PropertyType.AssemblyQualifiedName;&lt;br /&gt;                    nodePropertyInfo.Attributes.Append(attribProfilePropInfo);&lt;br /&gt; &lt;br /&gt;                    // Value&lt;br /&gt;                    attribProfilePropInfo = exportProperties.CreateNode(XmlNodeType.Attribute, &amp;quot;Data&amp;quot;, &amp;quot;&amp;quot;) as XmlAttribute;&lt;br /&gt;                    reflectedValue = typeProperty.GetValue(profileProperty, null);&lt;br /&gt;                    attribProfilePropInfo.Value = (reflectedValue == null) ? String.Empty : reflectedValue.ToString();&lt;br /&gt;                    nodePropertyInfo.Attributes.Append(attribProfilePropInfo);&lt;br /&gt; &lt;br /&gt;                    nodeProperty.AppendChild(nodePropertyInfo);&lt;br /&gt;                }&lt;br /&gt;            }&lt;br /&gt;        }&lt;br /&gt;    }&lt;br /&gt; &lt;br /&gt;    exportProperties.Save(inputs.FileName);&lt;br /&gt;}&lt;br /&gt;The ImportProfiles method is the exact anti-thesis of the above, so I am not going to bother copy pasting that here.&lt;br /&gt;
&lt;/div&gt;</description><author>alogan</author><pubDate>Mon, 15 Jan 2007 08:46:18 GMT</pubDate><guid isPermaLink="false">UPDATED WIKI: Home 20070115084618A</guid></item><item><title>UPDATED WIKI: Home</title><link>http://www.codeplex.com/MOSSProfileReplicate/Wiki/View.aspx?title=Home&amp;version=6</link><description>&lt;div class="wikidoc"&gt;
The &amp;#34;SharePoint 2007 Shared Services Provider User Profile Property Replicator&amp;#34; was designed to take custom user profile properties and export&amp;#47;import them into another MOSS 2007 server.&amp;#13;&amp;#10;During most development cycles you will create custom user profile properties and currently the only way to move these from DEV&amp;#47;TEST&amp;#47;PROD is to backup&amp;#47;restore the Shared Services Provider.&amp;#13;&amp;#10;This tool will now reduce the amount of manual interaction required.
&lt;br /&gt; &lt;br /&gt;Recommended Reading/Basics before you dive into this blog post: &lt;a href="http://blah.winsmarts.com/2007-1-User_Profiles_and_Audience_Targeting.aspx" class="externalLink"&gt;http://blah.winsmarts.com/2007-1-User_Profiles_and_Audience_Targeting.aspx&lt;/a&gt;.&lt;br /&gt; &lt;br /&gt;&lt;b&gt;What is this utility?&lt;/b&gt;&lt;br /&gt;This is a command line utility that will allow you to manage profile properties setup on a SharePoint web's SharedService provider. It allows you to export properties from an SSP to XML, and vice versa.&lt;br /&gt; &lt;br /&gt;&lt;b&gt;How to use this utility?&lt;/b&gt;&lt;br /&gt;The utility comes with online help. Just type in &amp;quot;ProfilePropertyMgr -help&amp;quot; at commandline to get the help screen. The help screen reproduced below for your pleasure -&lt;br /&gt; &lt;br /&gt;=================================================&lt;br /&gt;&lt;b&gt;Profile Property Manager - Help&lt;/b&gt;&lt;br /&gt;================================================= &lt;br /&gt; &lt;br /&gt;&lt;b&gt;Usage:&lt;/b&gt; ProfilePropertyMgr -url &amp;lt;UrlToWeb&amp;gt; -filename &amp;lt;FileName&amp;gt; -import&lt;br /&gt;ProfilePropertyMgr -url &amp;lt;UrlToWeb&amp;gt; -filename &amp;lt;FileName&amp;gt; -export &lt;br /&gt; &lt;br /&gt;or &lt;br /&gt; &lt;br /&gt;ProfilePropertyMgr -help &lt;br /&gt; &lt;br /&gt;&lt;h2&gt;
Used For
&lt;/h2&gt;Export Profile properties from SharePoint to an XML file.&lt;br /&gt;Import Profile properties from an XML file to SharePoint. &lt;br /&gt; &lt;br /&gt;&lt;h2&gt;
Required Parameters are:
&lt;/h2&gt;-url &amp;lt;UrlToWeb&amp;gt;&lt;br /&gt;-file &amp;lt;FileName.xml&amp;gt; &lt;br /&gt; &lt;br /&gt;&lt;h2&gt;
XML File structure:
&lt;/h2&gt;&amp;lt;Properties&amp;gt;&lt;br /&gt;  &amp;lt;Property&amp;gt;&lt;br /&gt;    &amp;lt;PropertyInfo Name=&amp;quot; Type=&amp;quot; Data=&amp;quot;/&amp;gt;&lt;br /&gt;    &amp;lt;PropertyInfo ..&amp;gt;&lt;br /&gt;    ...&lt;br /&gt;  &amp;lt;/Property&amp;gt;&lt;br /&gt;  &amp;lt;Property&amp;gt;...&amp;lt;/Property&amp;gt;&lt;br /&gt;  ...&lt;br /&gt;&amp;lt;/Properties&amp;gt; &lt;br /&gt; &lt;br /&gt;&lt;b&gt;Sample usage:&lt;/b&gt;&lt;br /&gt;&lt;ul&gt;
&lt;li&gt;ProfilePropertyMgr -url http://moss2007 -filename output.xml -export&lt;/li&gt;&lt;li&gt;ProfilePropertyMgr -url http://moss2007 -filename input.xml -import &lt;/li&gt;
&lt;/ul&gt; &lt;br /&gt;&lt;b&gt;Code Explanation&lt;/b&gt;&lt;br /&gt;The code accepts input as command line parameters, and passes them to a business object called ProgramInputs as shown below: &lt;br /&gt; &lt;br /&gt;static void Main(string[] args)&lt;br /&gt;{&lt;br /&gt;    ProgramInputs inputs = new ProgramInputs(args);&lt;br /&gt;The ProgramInputs business object has 3 properties - Boolean &amp;quot;IsValid&amp;quot;, String &amp;quot;URL&amp;quot;, and &amp;quot;CurrentOperation&amp;quot;. CurrentOperation is a custom enum with 3 possible valies - Unspecified, Import and Export. ProgramInputs encapsulates the functionality to validate inputs, and tell the end user if the inputs are accepted, or what was missing.&lt;br /&gt; &lt;br /&gt;Once we know that the inputs are valid, we can act upon them. This is done using the following code&lt;br /&gt; &lt;br /&gt;if (inputs.IsValid)&lt;br /&gt;{&lt;br /&gt;  ...&lt;br /&gt;}&lt;br /&gt;else&lt;br /&gt;{&lt;br /&gt;    Trace.WriteLine(&amp;quot;Invalid inputs specified&amp;quot;, true);&lt;br /&gt;    Trace.PrintHelp();&lt;br /&gt;}&lt;br /&gt; &lt;br /&gt;And the actual code looks like this - &lt;br /&gt; &lt;br /&gt;using (SPSite site = new SPSite(inputs.Url))&lt;br /&gt;{&lt;br /&gt;    ServerContext context = ServerContext.GetContext(site);&lt;br /&gt;    UserProfileManager profileManager = new UserProfileManager(context);&lt;br /&gt; &lt;br /&gt;    switch (inputs.CurrentOperation)&lt;br /&gt;    {&lt;br /&gt;        case Operation.Unspecified:&lt;br /&gt;            throw new InvalidOperationException(&amp;quot;Invalid input operation specified, or input operation omitted, cannot continue&amp;quot;);&lt;br /&gt;        case Operation.Import:&lt;br /&gt;            WorkerBee.ImportProfiles(inputs, profileManager);&lt;br /&gt;            break;&lt;br /&gt;        case Operation.Export:&lt;br /&gt;            WorkerBee.ExportProfiles(inputs, profileManager);&lt;br /&gt;            break;&lt;br /&gt;        default: // This will never happen, so safely ignored.&lt;br /&gt;            break;&lt;br /&gt;    }&lt;br /&gt;}&lt;br /&gt; &lt;br /&gt;As you would note from the above, the work is delegated to a class called WorkerBee. It has two methods, one to export, and one to import. I first get a hold of all the SharePoint properties using ProfileManager.Properties, and then I use reflection to sniff out which properties are exportable. Basically, anything that can be succesfully imported on the other end, is exportable on this end (duh!). So what is importable/exportable? Anything that is Read/Write, is value-type (or string), and doesn't start with &amp;quot;SSP-&amp;quot; (reserved for SharePoint), or isn't the reserved UserProfile_GUID property column. This in C#, is described as below - &lt;br /&gt; &lt;br /&gt;private static bool ShouldExport(PropertyInfo typeProperty, Property profileProperty, bool entireProperty)&lt;br /&gt;{&lt;br /&gt;    bool toReturn = false;&lt;br /&gt; &lt;br /&gt;    toReturn = typeProperty.CanRead &amp;amp; typeProperty.CanWrite &amp;amp;&lt;br /&gt;                (&lt;br /&gt;                    typeProperty.PropertyType.IsValueType |&lt;br /&gt;                    typeProperty.PropertyType.FullName.Equals(&amp;quot;System.String&amp;quot;)&lt;br /&gt;                );&lt;br /&gt; &lt;br /&gt;    // Proceed only if toReturn is still true ;&lt;br /&gt;    // Also, the following applies to only entire properties&lt;br /&gt;    if (toReturn &amp;amp; entireProperty)&lt;br /&gt;    {&lt;br /&gt;        object reflectedValue = typeProperty.GetValue(profileProperty, null);&lt;br /&gt;        string strReflectedValue = (reflectedValue == null) ? String.Empty : reflectedValue.ToString();&lt;br /&gt;        toReturn &amp;amp;= !strReflectedValue.Equals(&amp;quot;UserProfile_GUID&amp;quot;);&lt;br /&gt;        toReturn &amp;amp;= !strReflectedValue.StartsWith(&amp;quot;SPS-&amp;quot;);&lt;br /&gt;    }&lt;br /&gt;    return toReturn;&lt;br /&gt;}&lt;br /&gt;The full Export Profiles method looks like this - &lt;br /&gt; &lt;br /&gt;internal static void ExportProfiles(ProgramInputs inputs, UserProfileManager profileManager)&lt;br /&gt;{&lt;br /&gt;    // Variable Naming convention: &amp;lt;objectinConcern&amp;gt;&amp;lt;Property/Properties&amp;gt;&lt;br /&gt; &lt;br /&gt;    PropertyCollection profileProperties = profileManager.Properties;&lt;br /&gt; &lt;br /&gt;    XmlDocument exportProperties = new XmlDocument();&lt;br /&gt;    XmlNode nodeProperties = exportProperties.CreateNode(XmlNodeType.Element, &amp;quot;Properties&amp;quot;, &amp;quot;&amp;quot;);&lt;br /&gt;    exportProperties.AppendChild(nodeProperties);&lt;br /&gt; &lt;br /&gt;    PropertyInfo[] allProps = typeof(Property).GetProperties();&lt;br /&gt;    Dictionary&amp;lt;string, PropertyInfo&amp;gt; typeProperties = new Dictionary&amp;lt;string, PropertyInfo&amp;gt;();&lt;br /&gt;    foreach (PropertyInfo typeProperty in allProps)&lt;br /&gt;    {&lt;br /&gt;        typeProperties.Add(typeProperty.Name, typeProperty);&lt;br /&gt;    }&lt;br /&gt; &lt;br /&gt;    foreach (Property profileProperty in profileProperties)&lt;br /&gt;    {&lt;br /&gt;        // Should I be even exporting this property?&lt;br /&gt;        bool isExportable = ShouldExport(typeProperties&lt;a href="http://www.codeplex.com/MOSSProfileReplicate/Wiki/View.aspx?title=%22Name%22"&gt;&amp;quot;Name&amp;quot;&lt;/a&gt;, profileProperty, true);&lt;br /&gt; &lt;br /&gt;        if (isExportable)&lt;br /&gt;        {&lt;br /&gt;            XmlNode nodeProperty = exportProperties.CreateNode(XmlNodeType.Element, &amp;quot;Property&amp;quot;, &amp;quot;&amp;quot;);&lt;br /&gt;            nodeProperties.AppendChild(nodeProperty);&lt;br /&gt; &lt;br /&gt;            foreach (PropertyInfo typeProperty in typeProperties.Values)&lt;br /&gt;            {&lt;br /&gt;                if (ShouldExport(typeProperty, profileProperty, false))&lt;br /&gt;                {&lt;br /&gt;                    XmlNode nodePropertyInfo = exportProperties.CreateNode(XmlNodeType.Element, &amp;quot;PropertyInfo&amp;quot;, &amp;quot;&amp;quot;);&lt;br /&gt; &lt;br /&gt;                    XmlAttribute attribProfilePropInfo;&lt;br /&gt;                    object reflectedValue;&lt;br /&gt; &lt;br /&gt;                    //Name&lt;br /&gt;                    attribProfilePropInfo = exportProperties.CreateNode(XmlNodeType.Attribute, &amp;quot;Name&amp;quot;, &amp;quot;&amp;quot;) as XmlAttribute;&lt;br /&gt;                    attribProfilePropInfo.Value = typeProperty.Name;&lt;br /&gt;                    nodePropertyInfo.Attributes.Append(attribProfilePropInfo);&lt;br /&gt; &lt;br /&gt;                    // Data Type&lt;br /&gt;                    attribProfilePropInfo = exportProperties.CreateNode(XmlNodeType.Attribute, &amp;quot;Type&amp;quot;, &amp;quot;&amp;quot;) as XmlAttribute;&lt;br /&gt;                    attribProfilePropInfo.Value = typeProperty.PropertyType.AssemblyQualifiedName;&lt;br /&gt;                    nodePropertyInfo.Attributes.Append(attribProfilePropInfo);&lt;br /&gt; &lt;br /&gt;                    // Value&lt;br /&gt;                    attribProfilePropInfo = exportProperties.CreateNode(XmlNodeType.Attribute, &amp;quot;Data&amp;quot;, &amp;quot;&amp;quot;) as XmlAttribute;&lt;br /&gt;                    reflectedValue = typeProperty.GetValue(profileProperty, null);&lt;br /&gt;                    attribProfilePropInfo.Value = (reflectedValue == null) ? String.Empty : reflectedValue.ToString();&lt;br /&gt;                    nodePropertyInfo.Attributes.Append(attribProfilePropInfo);&lt;br /&gt; &lt;br /&gt;                    nodeProperty.AppendChild(nodePropertyInfo);&lt;br /&gt;                }&lt;br /&gt;            }&lt;br /&gt;        }&lt;br /&gt;    }&lt;br /&gt; &lt;br /&gt;    exportProperties.Save(inputs.FileName);&lt;br /&gt;}&lt;br /&gt;The ImportProfiles method is the exact anti-thesis of the above, so I am not going to bother copy pasting that here.&lt;br /&gt;
&lt;/div&gt;</description><author>alogan</author><pubDate>Mon, 15 Jan 2007 08:44:23 GMT</pubDate><guid isPermaLink="false">UPDATED WIKI: Home 20070115084423A</guid></item><item><title>UPDATED WIKI: Home</title><link>http://www.codeplex.com/MOSSProfileReplicate/Wiki/View.aspx?title=Home&amp;version=5</link><description>&lt;div class="wikidoc"&gt;
The &amp;#34;SharePoint 2007 Shared Services Provider User Profile Property Replicator&amp;#34; was designed to take custom user profile properties and export&amp;#47;import them into another MOSS 2007 server.&amp;#13;&amp;#10;During most development cycles you will create custom user profile properties and currently the only way to move these from DEV&amp;#47;TEST&amp;#47;PROD is to backup&amp;#47;restore the Shared Services Provider.&amp;#13;&amp;#10;This tool will now reduce the amount of manual interaction required.
&lt;br /&gt; &lt;br /&gt;Recommended Reading/Basics before you dive into this blog post: &lt;a href="http://blah.winsmarts.com/2007-1-User_Profiles_and_Audience_Targeting.aspx" class="externalLink"&gt;http://blah.winsmarts.com/2007-1-User_Profiles_and_Audience_Targeting.aspx&lt;/a&gt;.&lt;br /&gt; &lt;br /&gt;&lt;b&gt;What is this utility?&lt;/b&gt;&lt;br /&gt;This is a command line utility that will allow you to manage profile properties setup on a SharePoint web's SharedService provider. It allows you to export properties from an SSP to XML, and vice versa.&lt;br /&gt; &lt;br /&gt;&lt;b&gt;How to use this utility?&lt;/b&gt;&lt;br /&gt;The utility comes with online help. Just type in &amp;quot;ProfilePropertyMgr -help&amp;quot; at commandline to get the help screen. The help screen reproduced below for your pleasure -&lt;br /&gt; &lt;br /&gt;=================================================&lt;br /&gt;&lt;b&gt;Profile Property Manager - Help&lt;/b&gt;&lt;br /&gt;================================================= &lt;br /&gt; &lt;br /&gt;&lt;b&gt;Usage:&lt;/b&gt; ProfilePropertyMgr -url &amp;lt;UrlToWeb&amp;gt; -filename &amp;lt;FileName&amp;gt; -import&lt;br /&gt;ProfilePropertyMgr -url &amp;lt;UrlToWeb&amp;gt; -filename &amp;lt;FileName&amp;gt; -export &lt;br /&gt; &lt;br /&gt;or &lt;br /&gt; &lt;br /&gt;ProfilePropertyMgr -help &lt;br /&gt; &lt;br /&gt;&lt;h2&gt;
Used For
&lt;/h2&gt;Export Profile properties from SharePoint to an XML file.&lt;br /&gt;Import Profile properties from an XML file to SharePoint. &lt;br /&gt; &lt;br /&gt;&lt;h2&gt;
Required Parameters are:
&lt;/h2&gt;-url &amp;lt;UrlToWeb&amp;gt;&lt;br /&gt;-file &amp;lt;FileName.xml&amp;gt; &lt;br /&gt; &lt;br /&gt;&lt;h2&gt;
XML File structure:
&lt;/h2&gt;&amp;lt;Properties&amp;gt;&lt;br /&gt;&amp;lt;Property&amp;gt;&lt;br /&gt;&amp;lt;PropertyInfo Name=&amp;quot; Type=&amp;quot; Data=&amp;quot;/&amp;gt;&lt;br /&gt;&amp;lt;PropertyInfo ..&amp;gt;&lt;br /&gt;...&lt;br /&gt;&amp;lt;/Property&amp;gt;&lt;br /&gt;&amp;lt;Property&amp;gt;...&amp;lt;/Property&amp;gt;&lt;br /&gt;...&lt;br /&gt;&amp;lt;/Properties&amp;gt; &lt;br /&gt; &lt;br /&gt;&lt;ul&gt;
&lt;ul&gt;
&lt;ul&gt;
&lt;ul&gt;
&lt;ul&gt;
&lt;ul&gt;
&lt;ul&gt;
&lt;ul&gt;
&lt;ul&gt;
&lt;ul&gt;
&lt;ul&gt;
&lt;li&gt;Sample usage: ***********&lt;/li&gt;
&lt;/ul&gt;
&lt;/ul&gt;
&lt;/ul&gt;
&lt;/ul&gt;
&lt;/ul&gt;
&lt;/ul&gt;
&lt;/ul&gt;
&lt;/ul&gt;
&lt;/ul&gt;
&lt;/ul&gt;
&lt;/ul&gt;ProfilePropertyMgr -url http://moss2007 -filename output.xml -export&lt;br /&gt;ProfilePropertyMgr -url http://moss2007 -filename input.xml -import &lt;br /&gt; &lt;br /&gt;Code Explanation&lt;br /&gt;The code accepts input as command line parameters, and passes them to a business object called ProgramInputs as shown below: &lt;br /&gt; &lt;br /&gt;static void Main(string[] args)&lt;br /&gt;{&lt;br /&gt;    ProgramInputs inputs = new ProgramInputs(args);&lt;br /&gt;The ProgramInputs business object has 3 properties - Boolean &amp;quot;IsValid&amp;quot;, String &amp;quot;URL&amp;quot;, and &amp;quot;CurrentOperation&amp;quot;. CurrentOperation is a custom enum with 3 possible valies - Unspecified, Import and Export. ProgramInputs encapsulates the functionality to validate inputs, and tell the end user if the inputs are accepted, or what was missing.&lt;br /&gt; &lt;br /&gt;Once we know that the inputs are valid, we can act upon them. This is done using the following code&lt;br /&gt; &lt;br /&gt;if (inputs.IsValid)&lt;br /&gt;{&lt;br /&gt;  ...&lt;br /&gt;}&lt;br /&gt;else&lt;br /&gt;{&lt;br /&gt;    Trace.WriteLine(&amp;quot;Invalid inputs specified&amp;quot;, true);&lt;br /&gt;    Trace.PrintHelp();&lt;br /&gt;}&lt;br /&gt; &lt;br /&gt;And the actual code looks like this - &lt;br /&gt; &lt;br /&gt;using (SPSite site = new SPSite(inputs.Url))&lt;br /&gt;{&lt;br /&gt;    ServerContext context = ServerContext.GetContext(site);&lt;br /&gt;    UserProfileManager profileManager = new UserProfileManager(context);&lt;br /&gt; &lt;br /&gt;    switch (inputs.CurrentOperation)&lt;br /&gt;    {&lt;br /&gt;        case Operation.Unspecified:&lt;br /&gt;            throw new InvalidOperationException(&amp;quot;Invalid input operation specified, or input operation omitted, cannot continue&amp;quot;);&lt;br /&gt;        case Operation.Import:&lt;br /&gt;            WorkerBee.ImportProfiles(inputs, profileManager);&lt;br /&gt;            break;&lt;br /&gt;        case Operation.Export:&lt;br /&gt;            WorkerBee.ExportProfiles(inputs, profileManager);&lt;br /&gt;            break;&lt;br /&gt;        default: // This will never happen, so safely ignored.&lt;br /&gt;            break;&lt;br /&gt;    }&lt;br /&gt;}&lt;br /&gt; &lt;br /&gt;As you would note from the above, the work is delegated to a class called WorkerBee. It has two methods, one to export, and one to import. I first get a hold of all the SharePoint properties using ProfileManager.Properties, and then I use reflection to sniff out which properties are exportable. Basically, anything that can be succesfully imported on the other end, is exportable on this end (duh!). So what is importable/exportable? Anything that is Read/Write, is value-type (or string), and doesn't start with &amp;quot;SSP-&amp;quot; (reserved for SharePoint), or isn't the reserved UserProfile_GUID property column. This in C#, is described as below - &lt;br /&gt; &lt;br /&gt;private static bool ShouldExport(PropertyInfo typeProperty, Property profileProperty, bool entireProperty)&lt;br /&gt;{&lt;br /&gt;    bool toReturn = false;&lt;br /&gt; &lt;br /&gt;    toReturn = typeProperty.CanRead &amp;amp; typeProperty.CanWrite &amp;amp;&lt;br /&gt;                (&lt;br /&gt;                    typeProperty.PropertyType.IsValueType |&lt;br /&gt;                    typeProperty.PropertyType.FullName.Equals(&amp;quot;System.String&amp;quot;)&lt;br /&gt;                );&lt;br /&gt; &lt;br /&gt;    // Proceed only if toReturn is still true ;&lt;br /&gt;    // Also, the following applies to only entire properties&lt;br /&gt;    if (toReturn &amp;amp; entireProperty)&lt;br /&gt;    {&lt;br /&gt;        object reflectedValue = typeProperty.GetValue(profileProperty, null);&lt;br /&gt;        string strReflectedValue = (reflectedValue == null) ? String.Empty : reflectedValue.ToString();&lt;br /&gt;        toReturn &amp;amp;= !strReflectedValue.Equals(&amp;quot;UserProfile_GUID&amp;quot;);&lt;br /&gt;        toReturn &amp;amp;= !strReflectedValue.StartsWith(&amp;quot;SPS-&amp;quot;);&lt;br /&gt;    }&lt;br /&gt;    return toReturn;&lt;br /&gt;}&lt;br /&gt;The full Export Profiles method looks like this - &lt;br /&gt; &lt;br /&gt;internal static void ExportProfiles(ProgramInputs inputs, UserProfileManager profileManager)&lt;br /&gt;{&lt;br /&gt;    // Variable Naming convention: &amp;lt;objectinConcern&amp;gt;&amp;lt;Property/Properties&amp;gt;&lt;br /&gt; &lt;br /&gt;    PropertyCollection profileProperties = profileManager.Properties;&lt;br /&gt; &lt;br /&gt;    XmlDocument exportProperties = new XmlDocument();&lt;br /&gt;    XmlNode nodeProperties = exportProperties.CreateNode(XmlNodeType.Element, &amp;quot;Properties&amp;quot;, &amp;quot;&amp;quot;);&lt;br /&gt;    exportProperties.AppendChild(nodeProperties);&lt;br /&gt; &lt;br /&gt;    PropertyInfo[] allProps = typeof(Property).GetProperties();&lt;br /&gt;    Dictionary&amp;lt;string, PropertyInfo&amp;gt; typeProperties = new Dictionary&amp;lt;string, PropertyInfo&amp;gt;();&lt;br /&gt;    foreach (PropertyInfo typeProperty in allProps)&lt;br /&gt;    {&lt;br /&gt;        typeProperties.Add(typeProperty.Name, typeProperty);&lt;br /&gt;    }&lt;br /&gt; &lt;br /&gt;    foreach (Property profileProperty in profileProperties)&lt;br /&gt;    {&lt;br /&gt;        // Should I be even exporting this property?&lt;br /&gt;        bool isExportable = ShouldExport(typeProperties&lt;a href="http://www.codeplex.com/MOSSProfileReplicate/Wiki/View.aspx?title=%22Name%22"&gt;&amp;quot;Name&amp;quot;&lt;/a&gt;, profileProperty, true);&lt;br /&gt; &lt;br /&gt;        if (isExportable)&lt;br /&gt;        {&lt;br /&gt;            XmlNode nodeProperty = exportProperties.CreateNode(XmlNodeType.Element, &amp;quot;Property&amp;quot;, &amp;quot;&amp;quot;);&lt;br /&gt;            nodeProperties.AppendChild(nodeProperty);&lt;br /&gt; &lt;br /&gt;            foreach (PropertyInfo typeProperty in typeProperties.Values)&lt;br /&gt;            {&lt;br /&gt;                if (ShouldExport(typeProperty, profileProperty, false))&lt;br /&gt;                {&lt;br /&gt;                    XmlNode nodePropertyInfo = exportProperties.CreateNode(XmlNodeType.Element, &amp;quot;PropertyInfo&amp;quot;, &amp;quot;&amp;quot;);&lt;br /&gt; &lt;br /&gt;                    XmlAttribute attribProfilePropInfo;&lt;br /&gt;                    object reflectedValue;&lt;br /&gt; &lt;br /&gt;                    //Name&lt;br /&gt;                    attribProfilePropInfo = exportProperties.CreateNode(XmlNodeType.Attribute, &amp;quot;Name&amp;quot;, &amp;quot;&amp;quot;) as XmlAttribute;&lt;br /&gt;                    attribProfilePropInfo.Value = typeProperty.Name;&lt;br /&gt;                    nodePropertyInfo.Attributes.Append(attribProfilePropInfo);&lt;br /&gt; &lt;br /&gt;                    // Data Type&lt;br /&gt;                    attribProfilePropInfo = exportProperties.CreateNode(XmlNodeType.Attribute, &amp;quot;Type&amp;quot;, &amp;quot;&amp;quot;) as XmlAttribute;&lt;br /&gt;                    attribProfilePropInfo.Value = typeProperty.PropertyType.AssemblyQualifiedName;&lt;br /&gt;                    nodePropertyInfo.Attributes.Append(attribProfilePropInfo);&lt;br /&gt; &lt;br /&gt;                    // Value&lt;br /&gt;                    attribProfilePropInfo = exportProperties.CreateNode(XmlNodeType.Attribute, &amp;quot;Data&amp;quot;, &amp;quot;&amp;quot;) as XmlAttribute;&lt;br /&gt;                    reflectedValue = typeProperty.GetValue(profileProperty, null);&lt;br /&gt;                    attribProfilePropInfo.Value = (reflectedValue == null) ? String.Empty : reflectedValue.ToString();&lt;br /&gt;                    nodePropertyInfo.Attributes.Append(attribProfilePropInfo);&lt;br /&gt; &lt;br /&gt;                    nodeProperty.AppendChild(nodePropertyInfo);&lt;br /&gt;                }&lt;br /&gt;            }&lt;br /&gt;        }&lt;br /&gt;    }&lt;br /&gt; &lt;br /&gt;    exportProperties.Save(inputs.FileName);&lt;br /&gt;}&lt;br /&gt;The ImportProfiles method is the exact anti-thesis of the above, so I am not going to bother copy pasting that here.&lt;br /&gt;
&lt;/div&gt;</description><author>alogan</author><pubDate>Mon, 15 Jan 2007 08:42:54 GMT</pubDate><guid isPermaLink="false">UPDATED WIKI: Home 20070115084254A</guid></item><item><title>UPDATED WIKI: Home</title><link>http://www.codeplex.com/MOSSProfileReplicate/Wiki/View.aspx?title=Home&amp;version=4</link><description>&lt;div class="wikidoc"&gt;
The &amp;#34;SharePoint 2007 Shared Services Provider User Profile Property Replicator&amp;#34; was designed to take custom user profile properties and export&amp;#47;import them into another MOSS 2007 server.&amp;#13;&amp;#10;During most development cycles you will create custom user profile properties and currently the only way to move these from DEV&amp;#47;TEST&amp;#47;PROD is to backup&amp;#47;restore the Shared Services Provider.&amp;#13;&amp;#10;This tool will now reduce the amount of manual interaction required.
&lt;br /&gt; &lt;br /&gt;Recommended Reading/Basics before you dive into this blog post: &lt;a href="http://blah.winsmarts.com/2007-1-User_Profiles_and_Audience_Targeting.aspx,User%20Profiles%20and%20Audience%20Targeting" class="externalLink"&gt;http://blah.winsmarts.com/2007-1-User_Profiles_and_Audience_Targeting.aspx,User Profiles and Audience Targeting&lt;/a&gt;.&lt;br /&gt; &lt;br /&gt;&lt;b&gt;What is this utility?&lt;/b&gt;&lt;br /&gt;This is a command line utility that will allow you to manage profile properties setup on a SharePoint web's SharedService provider. It allows you to export properties from an SSP to XML, and vice versa.&lt;br /&gt; &lt;br /&gt;&lt;b&gt;How to use this utility?&lt;/b&gt;&lt;br /&gt;The utility comes with online help. Just type in &amp;quot;ProfilePropertyMgr -help&amp;quot; at commandline to get the help screen. The help screen reproduced below for your pleasure -&lt;br /&gt; &lt;br /&gt;=================================================&lt;br /&gt;&lt;b&gt;Profile Property Manager - Help&lt;/b&gt;&lt;br /&gt;================================================= &lt;br /&gt; &lt;br /&gt;&lt;b&gt;Usage:&lt;/b&gt; ProfilePropertyMgr -url &amp;lt;UrlToWeb&amp;gt; -filename &amp;lt;FileName&amp;gt; -import&lt;br /&gt;ProfilePropertyMgr -url &amp;lt;UrlToWeb&amp;gt; -filename &amp;lt;FileName&amp;gt; -export &lt;br /&gt; &lt;br /&gt;or &lt;br /&gt; &lt;br /&gt;ProfilePropertyMgr -help &lt;br /&gt; &lt;br /&gt;&lt;h2&gt;
Used For
&lt;/h2&gt;Export Profile properties from SharePoint to an XML file.&lt;br /&gt;Import Profile properties from an XML file to SharePoint. &lt;br /&gt; &lt;br /&gt;&lt;h2&gt;
Required Parameters are:
&lt;/h2&gt;-url &amp;lt;UrlToWeb&amp;gt;&lt;br /&gt;-file &amp;lt;FileName.xml&amp;gt; &lt;br /&gt; &lt;br /&gt;&lt;h2&gt;
XML File structure:
&lt;/h2&gt;&amp;lt;Properties&amp;gt;&lt;br /&gt;&amp;lt;Property&amp;gt;&lt;br /&gt;&amp;lt;PropertyInfo Name=&amp;quot; Type=&amp;quot; Data=&amp;quot;/&amp;gt;&lt;br /&gt;&amp;lt;PropertyInfo ..&amp;gt;&lt;br /&gt;...&lt;br /&gt;&amp;lt;/Property&amp;gt;&lt;br /&gt;&amp;lt;Property&amp;gt;...&amp;lt;/Property&amp;gt;&lt;br /&gt;...&lt;br /&gt;&amp;lt;/Properties&amp;gt; &lt;br /&gt; &lt;br /&gt;&lt;ul&gt;
&lt;ul&gt;
&lt;ul&gt;
&lt;ul&gt;
&lt;ul&gt;
&lt;ul&gt;
&lt;ul&gt;
&lt;ul&gt;
&lt;ul&gt;
&lt;ul&gt;
&lt;ul&gt;
&lt;li&gt;Sample usage: ***********&lt;/li&gt;
&lt;/ul&gt;
&lt;/ul&gt;
&lt;/ul&gt;
&lt;/ul&gt;
&lt;/ul&gt;
&lt;/ul&gt;
&lt;/ul&gt;
&lt;/ul&gt;
&lt;/ul&gt;
&lt;/ul&gt;
&lt;/ul&gt;ProfilePropertyMgr -url http://moss2007 -filename output.xml -export&lt;br /&gt;ProfilePropertyMgr -url http://moss2007 -filename input.xml -import &lt;br /&gt; &lt;br /&gt;Code Explanation&lt;br /&gt;The code accepts input as command line parameters, and passes them to a business object called ProgramInputs as shown below: &lt;br /&gt; &lt;br /&gt;static void Main(string[] args)&lt;br /&gt;{&lt;br /&gt;    ProgramInputs inputs = new ProgramInputs(args);&lt;br /&gt;The ProgramInputs business object has 3 properties - Boolean &amp;quot;IsValid&amp;quot;, String &amp;quot;URL&amp;quot;, and &amp;quot;CurrentOperation&amp;quot;. CurrentOperation is a custom enum with 3 possible valies - Unspecified, Import and Export. ProgramInputs encapsulates the functionality to validate inputs, and tell the end user if the inputs are accepted, or what was missing.&lt;br /&gt; &lt;br /&gt;Once we know that the inputs are valid, we can act upon them. This is done using the following code&lt;br /&gt; &lt;br /&gt;if (inputs.IsValid)&lt;br /&gt;{&lt;br /&gt;  ...&lt;br /&gt;}&lt;br /&gt;else&lt;br /&gt;{&lt;br /&gt;    Trace.WriteLine(&amp;quot;Invalid inputs specified&amp;quot;, true);&lt;br /&gt;    Trace.PrintHelp();&lt;br /&gt;}&lt;br /&gt; &lt;br /&gt;And the actual code looks like this - &lt;br /&gt; &lt;br /&gt;using (SPSite site = new SPSite(inputs.Url))&lt;br /&gt;{&lt;br /&gt;    ServerContext context = ServerContext.GetContext(site);&lt;br /&gt;    UserProfileManager profileManager = new UserProfileManager(context);&lt;br /&gt; &lt;br /&gt;    switch (inputs.CurrentOperation)&lt;br /&gt;    {&lt;br /&gt;        case Operation.Unspecified:&lt;br /&gt;            throw new InvalidOperationException(&amp;quot;Invalid input operation specified, or input operation omitted, cannot continue&amp;quot;);&lt;br /&gt;        case Operation.Import:&lt;br /&gt;            WorkerBee.ImportProfiles(inputs, profileManager);&lt;br /&gt;            break;&lt;br /&gt;        case Operation.Export:&lt;br /&gt;            WorkerBee.ExportProfiles(inputs, profileManager);&lt;br /&gt;            break;&lt;br /&gt;        default: // This will never happen, so safely ignored.&lt;br /&gt;            break;&lt;br /&gt;    }&lt;br /&gt;}&lt;br /&gt; &lt;br /&gt;As you would note from the above, the work is delegated to a class called WorkerBee. It has two methods, one to export, and one to import. I first get a hold of all the SharePoint properties using ProfileManager.Properties, and then I use reflection to sniff out which properties are exportable. Basically, anything that can be succesfully imported on the other end, is exportable on this end (duh!). So what is importable/exportable? Anything that is Read/Write, is value-type (or string), and doesn't start with &amp;quot;SSP-&amp;quot; (reserved for SharePoint), or isn't the reserved UserProfile_GUID property column. This in C#, is described as below - &lt;br /&gt; &lt;br /&gt;private static bool ShouldExport(PropertyInfo typeProperty, Property profileProperty, bool entireProperty)&lt;br /&gt;{&lt;br /&gt;    bool toReturn = false;&lt;br /&gt; &lt;br /&gt;    toReturn = typeProperty.CanRead &amp;amp; typeProperty.CanWrite &amp;amp;&lt;br /&gt;                (&lt;br /&gt;                    typeProperty.PropertyType.IsValueType |&lt;br /&gt;                    typeProperty.PropertyType.FullName.Equals(&amp;quot;System.String&amp;quot;)&lt;br /&gt;                );&lt;br /&gt; &lt;br /&gt;    // Proceed only if toReturn is still true ;&lt;br /&gt;    // Also, the following applies to only entire properties&lt;br /&gt;    if (toReturn &amp;amp; entireProperty)&lt;br /&gt;    {&lt;br /&gt;        object reflectedValue = typeProperty.GetValue(profileProperty, null);&lt;br /&gt;        string strReflectedValue = (reflectedValue == null) ? String.Empty : reflectedValue.ToString();&lt;br /&gt;        toReturn &amp;amp;= !strReflectedValue.Equals(&amp;quot;UserProfile_GUID&amp;quot;);&lt;br /&gt;        toReturn &amp;amp;= !strReflectedValue.StartsWith(&amp;quot;SPS-&amp;quot;);&lt;br /&gt;    }&lt;br /&gt;    return toReturn;&lt;br /&gt;}&lt;br /&gt;The full Export Profiles method looks like this - &lt;br /&gt; &lt;br /&gt;internal static void ExportProfiles(ProgramInputs inputs, UserProfileManager profileManager)&lt;br /&gt;{&lt;br /&gt;    // Variable Naming convention: &amp;lt;objectinConcern&amp;gt;&amp;lt;Property/Properties&amp;gt;&lt;br /&gt; &lt;br /&gt;    PropertyCollection profileProperties = profileManager.Properties;&lt;br /&gt; &lt;br /&gt;    XmlDocument exportProperties = new XmlDocument();&lt;br /&gt;    XmlNode nodeProperties = exportProperties.CreateNode(XmlNodeType.Element, &amp;quot;Properties&amp;quot;, &amp;quot;&amp;quot;);&lt;br /&gt;    exportProperties.AppendChild(nodeProperties);&lt;br /&gt; &lt;br /&gt;    PropertyInfo[] allProps = typeof(Property).GetProperties();&lt;br /&gt;    Dictionary&amp;lt;string, PropertyInfo&amp;gt; typeProperties = new Dictionary&amp;lt;string, PropertyInfo&amp;gt;();&lt;br /&gt;    foreach (PropertyInfo typeProperty in allProps)&lt;br /&gt;    {&lt;br /&gt;        typeProperties.Add(typeProperty.Name, typeProperty);&lt;br /&gt;    }&lt;br /&gt; &lt;br /&gt;    foreach (Property profileProperty in profileProperties)&lt;br /&gt;    {&lt;br /&gt;        // Should I be even exporting this property?&lt;br /&gt;        bool isExportable = ShouldExport(typeProperties&lt;a href="http://www.codeplex.com/MOSSProfileReplicate/Wiki/View.aspx?title=%22Name%22"&gt;&amp;quot;Name&amp;quot;&lt;/a&gt;, profileProperty, true);&lt;br /&gt; &lt;br /&gt;        if (isExportable)&lt;br /&gt;        {&lt;br /&gt;            XmlNode nodeProperty = exportProperties.CreateNode(XmlNodeType.Element, &amp;quot;Property&amp;quot;, &amp;quot;&amp;quot;);&lt;br /&gt;            nodeProperties.AppendChild(nodeProperty);&lt;br /&gt; &lt;br /&gt;            foreach (PropertyInfo typeProperty in typeProperties.Values)&lt;br /&gt;            {&lt;br /&gt;                if (ShouldExport(typeProperty, profileProperty, false))&lt;br /&gt;                {&lt;br /&gt;                    XmlNode nodePropertyInfo = exportProperties.CreateNode(XmlNodeType.Element, &amp;quot;PropertyInfo&amp;quot;, &amp;quot;&amp;quot;);&lt;br /&gt; &lt;br /&gt;                    XmlAttribute attribProfilePropInfo;&lt;br /&gt;                    object reflectedValue;&lt;br /&gt; &lt;br /&gt;                    //Name&lt;br /&gt;                    attribProfilePropInfo = exportProperties.CreateNode(XmlNodeType.Attribute, &amp;quot;Name&amp;quot;, &amp;quot;&amp;quot;) as XmlAttribute;&lt;br /&gt;                    attribProfilePropInfo.Value = typeProperty.Name;&lt;br /&gt;                    nodePropertyInfo.Attributes.Append(attribProfilePropInfo);&lt;br /&gt; &lt;br /&gt;                    // Data Type&lt;br /&gt;                    attribProfilePropInfo = exportProperties.CreateNode(XmlNodeType.Attribute, &amp;quot;Type&amp;quot;, &amp;quot;&amp;quot;) as XmlAttribute;&lt;br /&gt;                    attribProfilePropInfo.Value = typeProperty.PropertyType.AssemblyQualifiedName;&lt;br /&gt;                    nodePropertyInfo.Attributes.Append(attribProfilePropInfo);&lt;br /&gt; &lt;br /&gt;                    // Value&lt;br /&gt;                    attribProfilePropInfo = exportProperties.CreateNode(XmlNodeType.Attribute, &amp;quot;Data&amp;quot;, &amp;quot;&amp;quot;) as XmlAttribute;&lt;br /&gt;                    reflectedValue = typeProperty.GetValue(profileProperty, null);&lt;br /&gt;                    attribProfilePropInfo.Value = (reflectedValue == null) ? String.Empty : reflectedValue.ToString();&lt;br /&gt;                    nodePropertyInfo.Attributes.Append(attribProfilePropInfo);&lt;br /&gt; &lt;br /&gt;                    nodeProperty.AppendChild(nodePropertyInfo);&lt;br /&gt;                }&lt;br /&gt;            }&lt;br /&gt;        }&lt;br /&gt;    }&lt;br /&gt; &lt;br /&gt;    exportProperties.Save(inputs.FileName);&lt;br /&gt;}&lt;br /&gt;The ImportProfiles method is the exact anti-thesis of the above, so I am not going to bother copy pasting that here.&lt;br /&gt;
&lt;/div&gt;</description><author>alogan</author><pubDate>Mon, 15 Jan 2007 08:42:39 GMT</pubDate><guid isPermaLink="false">UPDATED WIKI: Home 20070115084239A</guid></item><item><title>UPDATED WIKI: Home</title><link>http://www.codeplex.com/MOSSProfileReplicate/Wiki/View.aspx?title=Home&amp;version=3</link><description>&lt;div class="wikidoc"&gt;
The &amp;#34;SharePoint 2007 Shared Services Provider User Profile Property Replicator&amp;#34; was designed to take custom user profile properties and export&amp;#47;import them into another MOSS 2007 server.&amp;#13;&amp;#10;During most development cycles you will create custom user profile properties and currently the only way to move these from DEV&amp;#47;TEST&amp;#47;PROD is to backup&amp;#47;restore the Shared Services Provider.&amp;#13;&amp;#10;This tool will now reduce the amount of manual interaction required.
&lt;br /&gt; &lt;br /&gt;Recommended Reading/Basics before you dive into this blog post: &lt;a href="User%20Profiles%20and%20Audience%20Targeting" class="externalLink"&gt;http://blah.winsmarts.com/2007-1-User_Profiles_and_Audience_Targeting.aspx&lt;/a&gt;.&lt;br /&gt; &lt;br /&gt;&lt;b&gt;What is this utility?&lt;/b&gt;&lt;br /&gt;This is a command line utility that will allow you to manage profile properties setup on a SharePoint web's SharedService provider. It allows you to export properties from an SSP to XML, and vice versa.&lt;br /&gt; &lt;br /&gt;&lt;b&gt;How to use this utility?&lt;/b&gt;&lt;br /&gt;The utility comes with online help. Just type in &amp;quot;ProfilePropertyMgr -help&amp;quot; at commandline to get the help screen. The help screen reproduced below for your pleasure -&lt;br /&gt; &lt;br /&gt;=================================================&lt;br /&gt;&lt;b&gt;Profile Property Manager - Help&lt;/b&gt;&lt;br /&gt;================================================= &lt;br /&gt; &lt;br /&gt;&lt;b&gt;Usage:&lt;/b&gt; ProfilePropertyMgr -url &amp;lt;UrlToWeb&amp;gt; -filename &amp;lt;FileName&amp;gt; -import&lt;br /&gt;ProfilePropertyMgr -url &amp;lt;UrlToWeb&amp;gt; -filename &amp;lt;FileName&amp;gt; -export &lt;br /&gt; &lt;br /&gt;or &lt;br /&gt; &lt;br /&gt;ProfilePropertyMgr -help &lt;br /&gt; &lt;br /&gt;&lt;h2&gt;
Used For
&lt;/h2&gt;Export Profile properties from SharePoint to an XML file.&lt;br /&gt;Import Profile properties from an XML file to SharePoint. &lt;br /&gt; &lt;br /&gt;&lt;h2&gt;
Required Parameters are:
&lt;/h2&gt;-url &amp;lt;UrlToWeb&amp;gt;&lt;br /&gt;-file &amp;lt;FileName.xml&amp;gt; &lt;br /&gt; &lt;br /&gt;&lt;h2&gt;
XML File structure:
&lt;/h2&gt;&amp;lt;Properties&amp;gt;&lt;br /&gt;&amp;lt;Property&amp;gt;&lt;br /&gt;&amp;lt;PropertyInfo Name=&amp;quot; Type=&amp;quot; Data=&amp;quot;/&amp;gt;&lt;br /&gt;&amp;lt;PropertyInfo ..&amp;gt;&lt;br /&gt;...&lt;br /&gt;&amp;lt;/Property&amp;gt;&lt;br /&gt;&amp;lt;Property&amp;gt;...&amp;lt;/Property&amp;gt;&lt;br /&gt;...&lt;br /&gt;&amp;lt;/Properties&amp;gt; &lt;br /&gt; &lt;br /&gt;&lt;ul&gt;
&lt;ul&gt;
&lt;ul&gt;
&lt;ul&gt;
&lt;ul&gt;
&lt;ul&gt;
&lt;ul&gt;
&lt;ul&gt;
&lt;ul&gt;
&lt;ul&gt;
&lt;ul&gt;
&lt;li&gt;Sample usage: ***********&lt;/li&gt;
&lt;/ul&gt;
&lt;/ul&gt;
&lt;/ul&gt;
&lt;/ul&gt;
&lt;/ul&gt;
&lt;/ul&gt;
&lt;/ul&gt;
&lt;/ul&gt;
&lt;/ul&gt;
&lt;/ul&gt;
&lt;/ul&gt;ProfilePropertyMgr -url http://moss2007 -filename output.xml -export&lt;br /&gt;ProfilePropertyMgr -url http://moss2007 -filename input.xml -import &lt;br /&gt; &lt;br /&gt;Code Explanation&lt;br /&gt;The code accepts input as command line parameters, and passes them to a business object called ProgramInputs as shown below: &lt;br /&gt; &lt;br /&gt;static void Main(string[] args)&lt;br /&gt;{&lt;br /&gt;    ProgramInputs inputs = new ProgramInputs(args);&lt;br /&gt;The ProgramInputs business object has 3 properties - Boolean &amp;quot;IsValid&amp;quot;, String &amp;quot;URL&amp;quot;, and &amp;quot;CurrentOperation&amp;quot;. CurrentOperation is a custom enum with 3 possible valies - Unspecified, Import and Export. ProgramInputs encapsulates the functionality to validate inputs, and tell the end user if the inputs are accepted, or what was missing.&lt;br /&gt; &lt;br /&gt;Once we know that the inputs are valid, we can act upon them. This is done using the following code&lt;br /&gt; &lt;br /&gt;if (inputs.IsValid)&lt;br /&gt;{&lt;br /&gt;  ...&lt;br /&gt;}&lt;br /&gt;else&lt;br /&gt;{&lt;br /&gt;    Trace.WriteLine(&amp;quot;Invalid inputs specified&amp;quot;, true);&lt;br /&gt;    Trace.PrintHelp();&lt;br /&gt;}&lt;br /&gt; &lt;br /&gt;And the actual code looks like this - &lt;br /&gt; &lt;br /&gt;using (SPSite site = new SPSite(inputs.Url))&lt;br /&gt;{&lt;br /&gt;    ServerContext context = ServerContext.GetContext(site);&lt;br /&gt;    UserProfileManager profileManager = new UserProfileManager(context);&lt;br /&gt; &lt;br /&gt;    switch (inputs.CurrentOperation)&lt;br /&gt;    {&lt;br /&gt;        case Operation.Unspecified:&lt;br /&gt;            throw new InvalidOperationException(&amp;quot;Invalid input operation specified, or input operation omitted, cannot continue&amp;quot;);&lt;br /&gt;        case Operation.Import:&lt;br /&gt;            WorkerBee.ImportProfiles(inputs, profileManager);&lt;br /&gt;            break;&lt;br /&gt;        case Operation.Export:&lt;br /&gt;            WorkerBee.ExportProfiles(inputs, profileManager);&lt;br /&gt;            break;&lt;br /&gt;        default: // This will never happen, so safely ignored.&lt;br /&gt;            break;&lt;br /&gt;    }&lt;br /&gt;}&lt;br /&gt; &lt;br /&gt;As you would note from the above, the work is delegated to a class called WorkerBee. It has two methods, one to export, and one to import. I first get a hold of all the SharePoint properties using ProfileManager.Properties, and then I use reflection to sniff out which properties are exportable. Basically, anything that can be succesfully imported on the other end, is exportable on this end (duh!). So what is importable/exportable? Anything that is Read/Write, is value-type (or string), and doesn't start with &amp;quot;SSP-&amp;quot; (reserved for SharePoint), or isn't the reserved UserProfile_GUID property column. This in C#, is described as below - &lt;br /&gt; &lt;br /&gt;private static bool ShouldExport(PropertyInfo typeProperty, Property profileProperty, bool entireProperty)&lt;br /&gt;{&lt;br /&gt;    bool toReturn = false;&lt;br /&gt; &lt;br /&gt;    toReturn = typeProperty.CanRead &amp;amp; typeProperty.CanWrite &amp;amp;&lt;br /&gt;                (&lt;br /&gt;                    typeProperty.PropertyType.IsValueType |&lt;br /&gt;                    typeProperty.PropertyType.FullName.Equals(&amp;quot;System.String&amp;quot;)&lt;br /&gt;                );&lt;br /&gt; &lt;br /&gt;    // Proceed only if toReturn is still true ;&lt;br /&gt;    // Also, the following applies to only entire properties&lt;br /&gt;    if (toReturn &amp;amp; entireProperty)&lt;br /&gt;    {&lt;br /&gt;        object reflectedValue = typeProperty.GetValue(profileProperty, null);&lt;br /&gt;        string strReflectedValue = (reflectedValue == null) ? String.Empty : reflectedValue.ToString();&lt;br /&gt;        toReturn &amp;amp;= !strReflectedValue.Equals(&amp;quot;UserProfile_GUID&amp;quot;);&lt;br /&gt;        toReturn &amp;amp;= !strReflectedValue.StartsWith(&amp;quot;SPS-&amp;quot;);&lt;br /&gt;    }&lt;br /&gt;    return toReturn;&lt;br /&gt;}&lt;br /&gt;The full Export Profiles method looks like this - &lt;br /&gt; &lt;br /&gt;internal static void ExportProfiles(ProgramInputs inputs, UserProfileManager profileManager)&lt;br /&gt;{&lt;br /&gt;    // Variable Naming convention: &amp;lt;objectinConcern&amp;gt;&amp;lt;Property/Properties&amp;gt;&lt;br /&gt; &lt;br /&gt;    PropertyCollection profileProperties = profileManager.Properties;&lt;br /&gt; &lt;br /&gt;    XmlDocument exportProperties = new XmlDocument();&lt;br /&gt;    XmlNode nodeProperties = exportProperties.CreateNode(XmlNodeType.Element, &amp;quot;Properties&amp;quot;, &amp;quot;&amp;quot;);&lt;br /&gt;    exportProperties.AppendChild(nodeProperties);&lt;br /&gt; &lt;br /&gt;    PropertyInfo[] allProps = typeof(Property).GetProperties();&lt;br /&gt;    Dictionary&amp;lt;string, PropertyInfo&amp;gt; typeProperties = new Dictionary&amp;lt;string, PropertyInfo&amp;gt;();&lt;br /&gt;    foreach (PropertyInfo typeProperty in allProps)&lt;br /&gt;    {&lt;br /&gt;        typeProperties.Add(typeProperty.Name, typeProperty);&lt;br /&gt;    }&lt;br /&gt; &lt;br /&gt;    foreach (Property profileProperty in profileProperties)&lt;br /&gt;    {&lt;br /&gt;        // Should I be even exporting this property?&lt;br /&gt;        bool isExportable = ShouldExport(typeProperties&lt;a href="http://www.codeplex.com/MOSSProfileReplicate/Wiki/View.aspx?title=%22Name%22"&gt;&amp;quot;Name&amp;quot;&lt;/a&gt;, profileProperty, true);&lt;br /&gt; &lt;br /&gt;        if (isExportable)&lt;br /&gt;        {&lt;br /&gt;            XmlNode nodeProperty = exportProperties.CreateNode(XmlNodeType.Element, &amp;quot;Property&amp;quot;, &amp;quot;&amp;quot;);&lt;br /&gt;            nodeProperties.AppendChild(nodeProperty);&lt;br /&gt; &lt;br /&gt;            foreach (PropertyInfo typeProperty in typeProperties.Values)&lt;br /&gt;            {&lt;br /&gt;                if (ShouldExport(typeProperty, profileProperty, false))&lt;br /&gt;                {&lt;br /&gt;                    XmlNode nodePropertyInfo = exportProperties.CreateNode(XmlNodeType.Element, &amp;quot;PropertyInfo&amp;quot;, &amp;quot;&amp;quot;);&lt;br /&gt; &lt;br /&gt;                    XmlAttribute attribProfilePropInfo;&lt;br /&gt;                    object reflectedValue;&lt;br /&gt; &lt;br /&gt;                    //Name&lt;br /&gt;                    attribProfilePropInfo = exportProperties.CreateNode(XmlNodeType.Attribute, &amp;quot;Name&amp;quot;, &amp;quot;&amp;quot;) as XmlAttribute;&lt;br /&gt;                    attribProfilePropInfo.Value = typeProperty.Name;&lt;br /&gt;                    nodePropertyInfo.Attributes.Append(attribProfilePropInfo);&lt;br /&gt; &lt;br /&gt;                    // Data Type&lt;br /&gt;                    attribProfilePropInfo = exportProperties.CreateNode(XmlNodeType.Attribute, &amp;quot;Type&amp;quot;, &amp;quot;&amp;quot;) as XmlAttribute;&lt;br /&gt;                    attribProfilePropInfo.Value = typeProperty.PropertyType.AssemblyQualifiedName;&lt;br /&gt;                    nodePropertyInfo.Attributes.Append(attribProfilePropInfo);&lt;br /&gt; &lt;br /&gt;                    // Value&lt;br /&gt;                    attribProfilePropInfo = exportProperties.CreateNode(XmlNodeType.Attribute, &amp;quot;Data&amp;quot;, &amp;quot;&amp;quot;) as XmlAttribute;&lt;br /&gt;                    reflectedValue = typeProperty.GetValue(profileProperty, null);&lt;br /&gt;                    attribProfilePropInfo.Value = (reflectedValue == null) ? String.Empty : reflectedValue.ToString();&lt;br /&gt;                    nodePropertyInfo.Attributes.Append(attribProfilePropInfo);&lt;br /&gt; &lt;br /&gt;                    nodeProperty.AppendChild(nodePropertyInfo);&lt;br /&gt;                }&lt;br /&gt;            }&lt;br /&gt;        }&lt;br /&gt;    }&lt;br /&gt; &lt;br /&gt;    exportProperties.Save(inputs.FileName);&lt;br /&gt;}&lt;br /&gt;The ImportProfiles method is the exact anti-thesis of the above, so I am not going to bother copy pasting that here.&lt;br /&gt;
&lt;/div&gt;</description><author>alogan</author><pubDate>Mon, 15 Jan 2007 08:42:10 GMT</pubDate><guid isPermaLink="false">UPDATED WIKI: Home 20070115084210A</guid></item><item><title>UPDATED WIKI: Home</title><link>http://www.codeplex.com/MOSSProfileReplicate/Wiki/View.aspx?title=Home&amp;version=2</link><description>&lt;div class="wikidoc"&gt;
The &amp;#34;SharePoint 2007 Shared Services Provider User Profile Property Replicator&amp;#34; was designed to take custom user profile properties and export&amp;#47;import them into another MOSS 2007 server.&amp;#13;&amp;#10;During most development cycles you will create custom user profile properties and currently the only way to move these from DEV&amp;#47;TEST&amp;#47;PROD is to backup&amp;#47;restore the Shared Services Provider.&amp;#13;&amp;#10;This tool will now reduce the amount of manual interaction required.
&lt;br /&gt; &lt;br /&gt;Recommended Reading/Basics before you dive into this blog post: User Profiles and Audience Targeting.&lt;br /&gt; &lt;br /&gt;&lt;b&gt;What is this utility?&lt;/b&gt;&lt;br /&gt;This is a command line utility that will allow you to manage profile properties setup on a SharePoint web's SharedService provider. It allows you to export properties from an SSP to XML, and vice versa.&lt;br /&gt; &lt;br /&gt;&lt;b&gt;How to use this utility?&lt;/b&gt;&lt;br /&gt;The utility comes with online help. Just type in &amp;quot;ProfilePropertyMgr -help&amp;quot; at commandline to get the help screen. The help screen reproduced below for your pleasure -&lt;br /&gt; &lt;br /&gt;=================================================&lt;br /&gt;&lt;b&gt;Profile Property Manager - Help&lt;/b&gt;&lt;br /&gt;================================================= &lt;br /&gt; &lt;br /&gt;&lt;b&gt;Usage:&lt;/b&gt; ProfilePropertyMgr -url &amp;lt;UrlToWeb&amp;gt; -filename &amp;lt;FileName&amp;gt; -import&lt;br /&gt;ProfilePropertyMgr -url &amp;lt;UrlToWeb&amp;gt; -filename &amp;lt;FileName&amp;gt; -export &lt;br /&gt; &lt;br /&gt;or &lt;br /&gt; &lt;br /&gt;ProfilePropertyMgr -help &lt;br /&gt; &lt;br /&gt;&lt;h2&gt;
Used For
&lt;/h2&gt;Export Profile properties from SharePoint to an XML file.&lt;br /&gt;Import Profile properties from an XML file to SharePoint. &lt;br /&gt; &lt;br /&gt;&lt;h2&gt;
Required Parameters are:
&lt;/h2&gt;-url &amp;lt;UrlToWeb&amp;gt;&lt;br /&gt;-file &amp;lt;FileName.xml&amp;gt; &lt;br /&gt; &lt;br /&gt;&lt;h2&gt;
XML File structure:
&lt;/h2&gt;&amp;lt;Properties&amp;gt;&lt;br /&gt;&amp;lt;Property&amp;gt;&lt;br /&gt;&amp;lt;PropertyInfo Name=&amp;quot; Type=&amp;quot; Data=&amp;quot;/&amp;gt;&lt;br /&gt;&amp;lt;PropertyInfo ..&amp;gt;&lt;br /&gt;...&lt;br /&gt;&amp;lt;/Property&amp;gt;&lt;br /&gt;&amp;lt;Property&amp;gt;...&amp;lt;/Property&amp;gt;&lt;br /&gt;...&lt;br /&gt;&amp;lt;/Properties&amp;gt; &lt;br /&gt; &lt;br /&gt;&lt;ul&gt;
&lt;ul&gt;
&lt;ul&gt;
&lt;ul&gt;
&lt;ul&gt;
&lt;ul&gt;
&lt;ul&gt;
&lt;ul&gt;
&lt;ul&gt;
&lt;ul&gt;
&lt;ul&gt;
&lt;li&gt;Sample usage: ***********&lt;/li&gt;
&lt;/ul&gt;
&lt;/ul&gt;
&lt;/ul&gt;
&lt;/ul&gt;
&lt;/ul&gt;
&lt;/ul&gt;
&lt;/ul&gt;
&lt;/ul&gt;
&lt;/ul&gt;
&lt;/ul&gt;
&lt;/ul&gt;ProfilePropertyMgr -url http://moss2007 -filename output.xml -export&lt;br /&gt;ProfilePropertyMgr -url http://moss2007 -filename input.xml -import &lt;br /&gt; &lt;br /&gt;Code Explanation&lt;br /&gt;The code accepts input as command line parameters, and passes them to a business object called ProgramInputs as shown below: &lt;br /&gt; &lt;br /&gt;static void Main(string[] args)&lt;br /&gt;{&lt;br /&gt;    ProgramInputs inputs = new ProgramInputs(args);&lt;br /&gt;The ProgramInputs business object has 3 properties - Boolean &amp;quot;IsValid&amp;quot;, String &amp;quot;URL&amp;quot;, and &amp;quot;CurrentOperation&amp;quot;. CurrentOperation is a custom enum with 3 possible valies - Unspecified, Import and Export. ProgramInputs encapsulates the functionality to validate inputs, and tell the end user if the inputs are accepted, or what was missing.&lt;br /&gt; &lt;br /&gt;Once we know that the inputs are valid, we can act upon them. This is done using the following code&lt;br /&gt; &lt;br /&gt;if (inputs.IsValid)&lt;br /&gt;{&lt;br /&gt;  ...&lt;br /&gt;}&lt;br /&gt;else&lt;br /&gt;{&lt;br /&gt;    Trace.WriteLine(&amp;quot;Invalid inputs specified&amp;quot;, true);&lt;br /&gt;    Trace.PrintHelp();&lt;br /&gt;}&lt;br /&gt; &lt;br /&gt;And the actual code looks like this - &lt;br /&gt; &lt;br /&gt;using (SPSite site = new SPSite(inputs.Url))&lt;br /&gt;{&lt;br /&gt;    ServerContext context = ServerContext.GetContext(site);&lt;br /&gt;    UserProfileManager profileManager = new UserProfileManager(context);&lt;br /&gt; &lt;br /&gt;    switch (inputs.CurrentOperation)&lt;br /&gt;    {&lt;br /&gt;        case Operation.Unspecified:&lt;br /&gt;            throw new InvalidOperationException(&amp;quot;Invalid input operation specified, or input operation omitted, cannot continue&amp;quot;);&lt;br /&gt;        case Operation.Import:&lt;br /&gt;            WorkerBee.ImportProfiles(inputs, profileManager);&lt;br /&gt;            break;&lt;br /&gt;        case Operation.Export:&lt;br /&gt;            WorkerBee.ExportProfiles(inputs, profileManager);&lt;br /&gt;            break;&lt;br /&gt;        default: // This will never happen, so safely ignored.&lt;br /&gt;            break;&lt;br /&gt;    }&lt;br /&gt;}&lt;br /&gt; &lt;br /&gt;As you would note from the above, the work is delegated to a class called WorkerBee. It has two methods, one to export, and one to import. I first get a hold of all the SharePoint properties using ProfileManager.Properties, and then I use reflection to sniff out which properties are exportable. Basically, anything that can be succesfully imported on the other end, is exportable on this end (duh!). So what is importable/exportable? Anything that is Read/Write, is value-type (or string), and doesn't start with &amp;quot;SSP-&amp;quot; (reserved for SharePoint), or isn't the reserved UserProfile_GUID property column. This in C#, is described as below - &lt;br /&gt; &lt;br /&gt;private static bool ShouldExport(PropertyInfo typeProperty, Property profileProperty, bool entireProperty)&lt;br /&gt;{&lt;br /&gt;    bool toReturn = false;&lt;br /&gt; &lt;br /&gt;    toReturn = typeProperty.CanRead &amp;amp; typeProperty.CanWrite &amp;amp;&lt;br /&gt;                (&lt;br /&gt;                    typeProperty.PropertyType.IsValueType |&lt;br /&gt;                    typeProperty.PropertyType.FullName.Equals(&amp;quot;System.String&amp;quot;)&lt;br /&gt;                );&lt;br /&gt; &lt;br /&gt;    // Proceed only if toReturn is still true ;&lt;br /&gt;    // Also, the following applies to only entire properties&lt;br /&gt;    if (toReturn &amp;amp; entireProperty)&lt;br /&gt;    {&lt;br /&gt;        object reflectedValue = typeProperty.GetValue(profileProperty, null);&lt;br /&gt;        string strReflectedValue = (reflectedValue == null) ? String.Empty : reflectedValue.ToString();&lt;br /&gt;        toReturn &amp;amp;= !strReflectedValue.Equals(&amp;quot;UserProfile_GUID&amp;quot;);&lt;br /&gt;        toReturn &amp;amp;= !strReflectedValue.StartsWith(&amp;quot;SPS-&amp;quot;);&lt;br /&gt;    }&lt;br /&gt;    return toReturn;&lt;br /&gt;}&lt;br /&gt;The full Export Profiles method looks like this - &lt;br /&gt; &lt;br /&gt;internal static void ExportProfiles(ProgramInputs inputs, UserProfileManager profileManager)&lt;br /&gt;{&lt;br /&gt;    // Variable Naming convention: &amp;lt;objectinConcern&amp;gt;&amp;lt;Property/Properties&amp;gt;&lt;br /&gt; &lt;br /&gt;    PropertyCollection profileProperties = profileManager.Properties;&lt;br /&gt; &lt;br /&gt;    XmlDocument exportProperties = new XmlDocument();&lt;br /&gt;    XmlNode nodeProperties = exportProperties.CreateNode(XmlNodeType.Element, &amp;quot;Properties&amp;quot;, &amp;quot;&amp;quot;);&lt;br /&gt;    exportProperties.AppendChild(nodeProperties);&lt;br /&gt; &lt;br /&gt;    PropertyInfo[] allProps = typeof(Property).GetProperties();&lt;br /&gt;    Dictionary&amp;lt;string, PropertyInfo&amp;gt; typeProperties = new Dictionary&amp;lt;string, PropertyInfo&amp;gt;();&lt;br /&gt;    foreach (PropertyInfo typeProperty in allProps)&lt;br /&gt;    {&lt;br /&gt;        typeProperties.Add(typeProperty.Name, typeProperty);&lt;br /&gt;    }&lt;br /&gt; &lt;br /&gt;    foreach (Property profileProperty in profileProperties)&lt;br /&gt;    {&lt;br /&gt;        // Should I be even exporting this property?&lt;br /&gt;        bool isExportable = ShouldExport(typeProperties&lt;a href="http://www.codeplex.com/MOSSProfileReplicate/Wiki/View.aspx?title=%22Name%22"&gt;&amp;quot;Name&amp;quot;&lt;/a&gt;, profileProperty, true);&lt;br /&gt; &lt;br /&gt;        if (isExportable)&lt;br /&gt;        {&lt;br /&gt;            XmlNode nodeProperty = exportProperties.CreateNode(XmlNodeType.Element, &amp;quot;Property&amp;quot;, &amp;quot;&amp;quot;);&lt;br /&gt;            nodeProperties.AppendChild(nodeProperty);&lt;br /&gt; &lt;br /&gt;            foreach (PropertyInfo typeProperty in typeProperties.Values)&lt;br /&gt;            {&lt;br /&gt;                if (ShouldExport(typeProperty, profileProperty, false))&lt;br /&gt;                {&lt;br /&gt;                    XmlNode nodePropertyInfo = exportProperties.CreateNode(XmlNodeType.Element, &amp;quot;PropertyInfo&amp;quot;, &amp;quot;&amp;quot;);&lt;br /&gt; &lt;br /&gt;                    XmlAttribute attribProfilePropInfo;&lt;br /&gt;                    object reflectedValue;&lt;br /&gt; &lt;br /&gt;                    //Name&lt;br /&gt;                    attribProfilePropInfo = exportProperties.CreateNode(XmlNodeType.Attribute, &amp;quot;Name&amp;quot;, &amp;quot;&amp;quot;) as XmlAttribute;&lt;br /&gt;                    attribProfilePropInfo.Value = typeProperty.Name;&lt;br /&gt;                    nodePropertyInfo.Attributes.Append(attribProfilePropInfo);&lt;br /&gt; &lt;br /&gt;                    // Data Type&lt;br /&gt;                    attribProfilePropInfo = exportProperties.CreateNode(XmlNodeType.Attribute, &amp;quot;Type&amp;quot;, &amp;quot;&amp;quot;) as XmlAttribute;&lt;br /&gt;                    attribProfilePropInfo.Value = typeProperty.PropertyType.AssemblyQualifiedName;&lt;br /&gt;                    nodePropertyInfo.Attributes.Append(attribProfilePropInfo);&lt;br /&gt; &lt;br /&gt;                    // Value&lt;br /&gt;                    attribProfilePropInfo = exportProperties.CreateNode(XmlNodeType.Attribute, &amp;quot;Data&amp;quot;, &amp;quot;&amp;quot;) as XmlAttribute;&lt;br /&gt;                    reflectedValue = typeProperty.GetValue(profileProperty, null);&lt;br /&gt;                    attribProfilePropInfo.Value = (reflectedValue == null) ? String.Empty : reflectedValue.ToString();&lt;br /&gt;                    nodePropertyInfo.Attributes.Append(attribProfilePropInfo);&lt;br /&gt; &lt;br /&gt;                    nodeProperty.AppendChild(nodePropertyInfo);&lt;br /&gt;                }&lt;br /&gt;            }&lt;br /&gt;        }&lt;br /&gt;    }&lt;br /&gt; &lt;br /&gt;    exportProperties.Save(inputs.FileName);&lt;br /&gt;}&lt;br /&gt;The ImportProfiles method is the exact anti-thesis of the above, so I am not going to bother copy pasting that here.&lt;br /&gt;
&lt;/div&gt;</description><author>alogan</author><pubDate>Mon, 15 Jan 2007 08:41:39 GMT</pubDate><guid isPermaLink="false">UPDATED WIKI: Home 20070115084139A</guid></item></channel></rss>