﻿<?xml version="1.0" encoding="UTF-8"?>
<!--RSS generated by Microsoft SharePoint Foundation RSS Generator on 5/21/2013 7:12:33 PM -->
<?xml-stylesheet type="text/xsl" href="/Blogs/fromthefield/_layouts/RssXslt.aspx?List=0ce77946-1e45-4b43-8c74-21963e64d4e1" version="1.0"?>
<rss version="2.0">
  <channel>
    <title>From The Field: Posts</title>
    <link>http://sharepoint.microsoft.com/blogs/fromthefield/Lists/Posts/AllPosts.aspx</link>
    <description>From The Field RSS feed</description>
    <lastBuildDate>Wed, 22 May 2013 02:12:33 GMT</lastBuildDate>
    <generator>Microsoft SharePoint Foundation RSS Generator</generator>
    <ttl>60</ttl>
    <language>en-US</language>
    <image>
      <title>From The Field: Posts</title>
      <url>http://sharepoint.microsoft.com/blogs/fromthefield/_layouts/images/homepage.gif</url>
      <link>http://sharepoint.microsoft.com/blogs/fromthefield/Lists/Posts/AllPosts.aspx</link>
    </image>
    <item>
      <title>Customizing the MySiteCleanup job</title>
      <link>http://sharepoint.microsoft.com/blogs/fromthefield/Lists/Posts/ViewPost.aspx?ID=163</link>
      <description><![CDATA[<div><b>Body:</b> <div class="ExternalClass718736D9A3FB4D27B20D801A268CB19D"><div class="ExternalClass9A00105A930F49C6A682D1BF3BD15FD5 ms-rteFontFace-8 ms-rteFontSize-3"><div class="ExternalClassDA48DE1DEC9F404388FE342D6C84440E"><div class="ExternalClassBFC00D1D9DE848759C36BE737D9BB99A"><p><span lang="EN-US"><font face="Batang">One issue that always comes up at my customers is the MySiteCleanup Job. They are not satisfied with the default implementation that SharePoint provides, and they want to change that way it behaves. Some feature requests for the job that I ran into so far with my various customers:</font></span></p>
<p> </p>
<div><span lang="EN-US"><span><font face="Batang">-</font><span style="font-variant:normal;font-weight:normal;font-style:normal;line-height:normal">        </span></span></span><span lang="EN-US"><font face="Batang">No “grace” period till a user (and later his MySite!!!) is deleted after missing from an Import</font></span></div>
<div><span lang="EN-US"><span><font face="Batang">-</font><span style="font-variant:normal;font-weight:normal;font-style:normal;line-height:normal">        </span></span></span><span lang="EN-US"><font face="Batang">Violation of data privacy by granting MySite access to the manager</font></span></div>
<div><span lang="EN-US"><span><font face="Batang">-</font><span style="font-variant:normal;font-weight:normal;font-style:normal;line-height:normal">        </span></span></span><span lang="EN-US"><font face="Batang">Modification of the Emails send out (The My Site of &quot;User&quot; is scheduled for deletion. As their manager you are now the temporary owner of their site[…])</font></span></div>
<div><span lang="EN-US"><span><font face="Batang">-</font><span style="font-variant:normal;font-weight:normal;font-style:normal;line-height:normal">        </span></span></span><span lang="EN-US"><font face="Batang">Splitting requests for the job tasks, so each step can be toggled on/off by itself (usually caused by the manager issue)</font></span></div>
<div><span lang="EN-US"><span><font face="Batang">-</font><span style="font-variant:normal;font-weight:normal;font-style:normal;line-height:normal">        </span></span></span><span lang="EN-US"><font face="Batang">No (supported) way to “stop” a site deletion once it was started</font></span></div>
<div><span lang="EN-US"><font face="Batang"></font></span> </div>
<div><span lang="EN-US"><font face="Batang">While most of these requests are “nice to have”, the manager issue is usually the one that kills the MySiteCleanup Job. Under German (and also EU) data protection laws, granting a manager access to his employees private files is a big no, and letting the Betriebsrat (Workers council) know about it is a sure way to turn it off. (It’s a sure way to turn almost any collaboration feature in SharePoint off, I did mention we have tight data protection laws?)</font></span></div>
<div><span lang="EN-US"><font face="Batang"></font></span> </div>
<div><span lang="EN-US"><font face="Batang">There is a way to completely modify the way this job is behaving. While this topic is coming up again and again (at least for me), there are very few resources that actually talk about how to modify this behavior but first let’s have a small review of the default implementation. </font></span><a href="http://blogs.msdn.com/b/chunliu/archive/2011/11/10/how-my-site-cleanup-job-works.aspx"><span lang="EN-US"><font color="#0563c1" face="Batang">Chun Liu’s Blog</font></span></a><span lang="EN-US"><font face="Batang"><span>  </span>published a small flowchart on what exactly it does, or check </font><a href="http://www.harbar.net/archive/2011/02/10/account-deletion-and-sharepoint-2010-user-profile-synchronization.aspx"><font color="#0563c1" face="Batang">Spence’s</font></a><font face="Batang"> blog for a bit more details about it.</font></span></div>
<div><span lang="EN-US"><span><font face="Batang"></font></span></span> </div>
<div><span lang="EN-US"><span><font face="Batang">1.</font><span style="font-variant:normal;font-weight:normal;font-style:normal;line-height:normal">      </span></span></span><span lang="EN-US"><font face="Batang">Cleanup user profiles</font></span></div>
<div><span lang="EN-US"><span><font face="Batang">a.</font><span style="font-variant:normal;font-weight:normal;font-style:normal;line-height:normal">      </span></span></span><span lang="EN-US"><font face="Batang">Set the owner to the manager</font></span></div>
<div><span lang="EN-US"><span><font face="Batang">b.</font><span style="font-variant:normal;font-weight:normal;font-style:normal;line-height:normal">      </span></span></span><span lang="EN-US"><font face="Batang">Inform the manager that he is owner</font></span></div>
<div><span lang="EN-US"><span><font face="Batang">c.</font><span style="font-variant:normal;font-weight:normal;font-style:normal;line-height:normal">      </span></span></span><span lang="EN-US"><font face="Batang">Schedule site for deletion</font></span></div>
<div><span lang="EN-US"><span><font face="Batang">d.</font><span style="font-variant:normal;font-weight:normal;font-style:normal;line-height:normal">      </span></span></span><span lang="EN-US"><font face="Batang">Delete Userprofile</font></span></div>
<div><span lang="EN-US"><span><font face="Batang">2.</font><span style="font-variant:normal;font-weight:normal;font-style:normal;line-height:normal">      </span></span></span><span lang="EN-US"><font face="Batang">Cleanup MySites</font></span></div>
<div><span lang="EN-US"><span><font face="Batang">a.</font><span style="font-variant:normal;font-weight:normal;font-style:normal;line-height:normal">      </span></span></span><span lang="EN-US"><font face="Batang">Send a reminder email after 11 days</font></span></div>
<div><span lang="EN-US"><span><font face="Batang">b.</font><span style="font-variant:normal;font-weight:normal;font-style:normal;line-height:normal">      </span></span></span><span lang="EN-US"><font face="Batang">Delete the site after 14 days</font></span></div>
<div><span lang="EN-US"><font face="Batang"></font></span> </div>
<div><span lang="EN-US"><font face="Batang">One important thing to mention is that this job is the <b>only</b> place where SharePoint will remove an old user profile (there is no longer a “3-miss and you are out” policy in the UPA import). So turning this job “off” will leave you with all old user profiles in your UPA.</font></span></div>
<div><span lang="EN-US"><font face="Batang"></font></span> </div>
<div><span lang="EN-US"><font face="Batang">What is interesting is that the steps in the 1<sup>st</sup> section can be modified. Basically the steps 1.a to 1.c are implemented in the Class </font></span><a href="http://msdn.microsoft.com/en-us/library/microsoft.office.server.userprofiles.mysiteprofilehandler.aspx"><span lang="EN-US"><font color="#0563c1" face="Batang">MySiteProfileHandler</font></span></a><span lang="EN-US"><font face="Batang"> and the profile is actually deleted if the method PreProfileDeleted() returns true. This is also the class that can be replaced by a custom implementation. To replace this class, you need to create your own version, which implements the </font></span><a href="http://msdn.microsoft.com/en-us/library/microsoft.office.server.userprofiles.iprofileeventinterface.aspx"><span lang="EN-US"><font color="#0563c1" face="Batang">IProfileEventInterface</font></span></a><span lang="EN-US"><font face="Batang">. </font></span></div>
<div><span lang="EN-US"><font face="Batang"></font></span> </div>
<div><span lang="EN-US"><font face="Batang">One thing that is a bit awkward about this implementation is that the class “only” implements 1.a -1.c. So, even if you replace it, you will still have the old implementation of the 2<sup>nd</sup> part of the job “active”. But since you are not able to schedule a site for deletion in your custom code, the 2nd part of the job does actually nothing at all. This means you also have to make sure you handle the MySite deletion properly. Since your code won’t be revisited after you gave your consent to delete the user, you need to make sure you implement an alternative workflow. 3 possible solution would be to either postpone the deletion of the user by X Days (Until you handled the MySite yourself), or create a small site workflow, attached to the MySite, that will cause the MySite to “self-destruct” after the given time (This wasn’t possible when the default timer job was implemented, but you have the option now), or backup and delete it right away (This would allow for a different retention of the MySite backups)</font></span></div>
<div><span lang="EN-US"><font face="Batang"></font></span> </div>
<div><span lang="EN-US"><font face="Batang">So once you have created the new class and put it into the GAC, the one step that is missing in order to use it in SharePoint is to register your custom implementation. To do this you have to fall back to a stsadm. You need to register the new class to running <b><i>stsadm -o profiledeletehandler -type &lt;full assembly path</i></b>&gt; <span> </span></font></span><a href="http://technet.microsoft.com/en-us/library/cc263114(v=office.12).aspx"><span lang="EN-US"><font color="#0563c1" face="Batang">http://technet.microsoft.com/en-us/library/cc263114(v=office.12).aspx</font></span></a><span lang="EN-US"><font face="Batang"> <span> </span>. This will store the type you entered in an internal (sorry, calling internal methods is also unsupported) property ProfileDeleteEventHandler of the MySiteCleanUpJob Instance.</font></span></div>
<div><span lang="EN-US"><font face="Batang">After that is done, SharePoint will apply your logic to the MySiteCleanup job, and you are set.</font></span></div>
<div><span lang="EN-US"><font face="Batang"></font></span> </div>
<div><span lang="EN-US"><font face="Batang">The are some drawbacks that you have to consider:</font></span></div>
<div><span lang="EN-US"><span><font face="Batang">-</font><span style="font-variant:normal;font-weight:normal;font-style:normal;line-height:normal">        </span></span></span><span lang="EN-US"><font face="Batang">Needs to be registered via STSADM</font></span></div>
<div><span lang="EN-US"><span><font face="Batang">-</font><span style="font-variant:normal;font-weight:normal;font-style:normal;line-height:normal">        </span></span></span><span lang="EN-US"><font face="Batang">Needs an assembly deployed into the GAC</font></span></div>
<div><span lang="EN-US"><span><font face="Batang">-</font><span style="font-variant:normal;font-weight:normal;font-style:normal;line-height:normal">        </span></span></span><span lang="EN-US"><font face="Batang">Not very transparent for a new Admin</font></span></div>
<div><span lang="EN-US"><span><font face="Batang">-</font><span style="font-variant:normal;font-weight:normal;font-style:normal;line-height:normal">        </span></span></span><span lang="EN-US"><font face="Batang">Unable to access the internal MySiteDeletion “Workflow” from my custom code – Need to reinvent the wheel </font></span></div>
<div><span lang="EN-US"><font face="Batang"></font></span> </div>
<div><span lang="EN-US"><font face="Batang">The option I would have loved the most, is the ability to configure how this process behaves right out of the box, but this is as close as we can get. Finding this option kind of surprised me, since there are very few places in SharePoint that use Interfaces (I love unit tests)</font></span></div>
<div><span lang="EN-US"><font face="Batang"></font></span> </div>
<div><span lang="EN-US"><font face="Batang"></font></span> </div>
<div><span lang="EN-US"><font face="Batang">I hope you will find this information usefull. If there are any questions, feel free to ping me.</font></span></div>
<p> </p>
<div><span lang="EN-US"><font face="Batang"></font></span> </div>
<p> </p>
<div><span lang="EN-US"><font face="Batang"> </font></span></div>
<p> </p></div></div></div></div></div>
<div><b>Category:</b> <a onclick="OpenPopUpPage('http://sharepoint.microsoft.com/Blogs/fromthefield/_layouts/listform.aspx?PageType=4&ListId={3431E8EC-5379-46F2-BEFC-9F1D50288E4A}&ID=12&RootFolder=*', RefreshPage); return false;" href="http://sharepoint.microsoft.com/Blogs/fromthefield/_layouts/listform.aspx?PageType=4&ListId={3431E8EC-5379-46F2-BEFC-9F1D50288E4A}&ID=12&RootFolder=*">Customization</a>; <a onclick="OpenPopUpPage('http://sharepoint.microsoft.com/Blogs/fromthefield/_layouts/listform.aspx?PageType=4&ListId={3431E8EC-5379-46F2-BEFC-9F1D50288E4A}&ID=34&RootFolder=*', RefreshPage); return false;" href="http://sharepoint.microsoft.com/Blogs/fromthefield/_layouts/listform.aspx?PageType=4&ListId={3431E8EC-5379-46F2-BEFC-9F1D50288E4A}&ID=34&RootFolder=*">My Site</a>; <a onclick="OpenPopUpPage('http://sharepoint.microsoft.com/Blogs/fromthefield/_layouts/listform.aspx?PageType=4&ListId={3431E8EC-5379-46F2-BEFC-9F1D50288E4A}&ID=30&RootFolder=*', RefreshPage); return false;" href="http://sharepoint.microsoft.com/Blogs/fromthefield/_layouts/listform.aspx?PageType=4&ListId={3431E8EC-5379-46F2-BEFC-9F1D50288E4A}&ID=30&RootFolder=*">SharePoint 2010</a>; <a onclick="OpenPopUpPage('http://sharepoint.microsoft.com/Blogs/fromthefield/_layouts/listform.aspx?PageType=4&ListId={3431E8EC-5379-46F2-BEFC-9F1D50288E4A}&ID=17&RootFolder=*', RefreshPage); return false;" href="http://sharepoint.microsoft.com/Blogs/fromthefield/_layouts/listform.aspx?PageType=4&ListId={3431E8EC-5379-46F2-BEFC-9F1D50288E4A}&ID=17&RootFolder=*">stsadm</a>; <a onclick="OpenPopUpPage('http://sharepoint.microsoft.com/Blogs/fromthefield/_layouts/listform.aspx?PageType=4&ListId={3431E8EC-5379-46F2-BEFC-9F1D50288E4A}&ID=39&RootFolder=*', RefreshPage); return false;" href="http://sharepoint.microsoft.com/Blogs/fromthefield/_layouts/listform.aspx?PageType=4&ListId={3431E8EC-5379-46F2-BEFC-9F1D50288E4A}&ID=39&RootFolder=*">MOSS 2007</a>; <a onclick="OpenPopUpPage('http://sharepoint.microsoft.com/Blogs/fromthefield/_layouts/listform.aspx?PageType=4&ListId={3431E8EC-5379-46F2-BEFC-9F1D50288E4A}&ID=40&RootFolder=*', RefreshPage); return false;" href="http://sharepoint.microsoft.com/Blogs/fromthefield/_layouts/listform.aspx?PageType=4&ListId={3431E8EC-5379-46F2-BEFC-9F1D50288E4A}&ID=40&RootFolder=*">SharePoint 2013</a></div>
<div><b>Published:</b> 4/23/2013 9:01 AM</div>
]]></description>
      <author>Heiko Hatzfeld</author>
      <category>Customization; My Site; SharePoint 2010; stsadm; MOSS 2007; SharePoint 2013</category>
      <pubDate>Tue, 23 Apr 2013 15:55:42 GMT</pubDate>
      <guid isPermaLink="true">http://sharepoint.microsoft.com/blogs/fromthefield/Lists/Posts/ViewPost.aspx?ID=163</guid>
    </item>
  </channel>
</rss>