Archive for the ‘Customization’ Category

Few Tips on CQWP (not from me )

September 22, 2011 Leave a comment

Categories: Customization Tags:

SPWebConfigModification Class

May 27, 2011 2 comments

We wanted to use SPWebConfigModification class to modify the web.config of web applications (some entries are made manually already).  Also different entries for different web applications. All these in powershell 🙂

Here is our important finding before we proceed..

  • The entries which are made in web.config that are not through this class cannot be modified/deleted using this class.
  • You can apply the modification only a particular web application by calling WebAppObject.WebService.ApplyWebConfigModifications() like our last line in the below given powershell
  • Also test to remove the entries through this class to confirm our entries are getting removed safely and to identity possible bugs in making the entries.

-> .

So, clean this mess… we have to first clear those entries manually and then put it back again through SPWebConfigModification. Now i want to read the entries from a xml file so that it easily manageable and easy to ask someone in production to execute it.

<!–entry for caching config section–>
<add name=”Caching1″ connectionString=”Initial dd Catalog=Caching;Data Source={Server name};Integrated Security=false;Uid=sqlCachingUser; Pwd=p@ssw0rd” providerName=”System.Data.SqlClient” />

Now comes our powershell

Write-Host “Enter WebApplication”
$IURL = Read-Host
Write-Host “Enter Config.xml file name”
$IConfigName = Read-Host
$IWebApp = [Microsoft.SharePoint.Administration.SPWebApplication]::Lookup($IURL)
Write-Host “Reading the Config.xml file..”
$configFile=[xml](get-content $IConfigName)
Write-Host “Config.xml file read”
foreach($config in $configFile.WebConfigModifications.WebConfig)
$Entry = new-object  Microsoft.SharePoint.Administration.SPWebConfigModification
$Entry.Path = $config.NodePath
$Entry.Name = $config.NodeKey
$Entry.Type =[Microsoft.SharePoint.Administration.SPWebConfigModification+SPWebConfigModificationType]::EnsureChildNode
$Entry.Owner = ‘APlainTextisEnough’
$Entry.Value =  $config.NodeValue.get_InnerXml()

now execute this powershell script in SharePoint 2010 management shell. Provide the first input as the web applicaiton url for which you want to enter the modifications. And secondly provide the path to .xml file which was stored earlier like .\config.xml.

That’s it.. your modification will reflect only to the web application what you have provided.

[Update 1] If you try to apply a webconfig entry and if that is not going through successfully then most likely that entry remains in configuration database. And when you try to apply webconfig modifications sometime later, the older entry will be still attempted in web.config file. So to check what are the webconfig modifications that are being applied you can check through


Through this, you can see what are the modifications that are being applied, but may not be actually present in web.config file.

Download .xml & powershell file from here

“The My Site of xxx is scheduled for deletion”

December 15, 2010 3 comments

We had strange issue (actually it is a feature of SharePoint) that when a user is moved out of organization (when his profile is removed by profile import) a mail is sent out to the manager of the user that ‘The My Site of xxx is scheduled for deletion’ and also it provide site collection admin access to that user’s personal site. And the issue is ‘Privacy’, user my site are personal site and should never be assigned to manager.

So, what we will attempt here is to stop

-> Stop the email sent to the manager

-> Stop the personal from being deleted

-> Stop the assigning the permission to the manager of the user

So, all the above activities are done through a Timer job ‘MySiteCleanUpJob’, which actually deletes the user profile and perform other activities including the above.  And thank fully this can be overwritten through code. Read the below link

So, we can write a class which inherits IProfileEventInterface and overloads the method ‘PreProfileDeleted‘.  If this method returns true then the profile will be deleted in profile store, and let’s assume we need that to happen and we will return true always.

Once the class is written, what to do next, how to plug in that. Put the following code in a feature receiver

SPService service = SPFarm.Local.Services.GetValue<SPWebService>(string.Empty);
MySiteCleanupJob job = service.JobDefinitions.GetValue<MySiteCleanupJob>(MySiteCleanupJob.DefaultJobName);
job.ProfileDeleteEventHandler = typeof(<<ClassName>>);

So far, everything explained is theoretical, so please try this in your test environment.  Will update the post once this is experimented.

[Update 2] New class cannot be hooked with the above specified way. It can be hooked through “stsadm -o profiledeletehandler” i could not get the equivalent powershell command.

Watch this space.. will update once deployed and tested

[Update 3] Here is the class

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Microsoft.SharePoint;
using Microsoft.Office;
using Microsoft.Office.Server;
using Microsoft.Office.Server.UserProfiles;
using Microsoft.Office.Server.Diagnostics;

namespace MyCompanyMySiteProfileHandler.MySiteProfileHandler
public class MyCompanyMySiteProfileHandler : IProfileEventInterface
public virtual bool PreProfileDeleted(UserProfile profile)
if (profile == null)
return false;
using (SPSite site = profile.PersonalSite)
if (site != null)
Microsoft.Office.Server.UserProfiles.MySiteProfileHandler handler = new Microsoft.Office.Server.UserProfiles.MySiteProfileHandler();
//By passing null we do not set the owner for personal site, but still schedule the site for deletion.
//this way reminder email will also not be sent, but the site will be deleted on 14th day from now
handler.SetMySiteOwner(profile, null);
catch(Exception oe)
//do something

//In any case return ture, to make sure the profiles does not remain unattended.
return true;

public virtual bool PreProfileDeleted(ServerContext context, UserProfile profile)
return true;