Joel's SharePoint Architect Blog

SharePoint 2010, MOSS & WSS Tips and Consultancy Tales

Subscribe Subscribe  View Joel Jeffery's profile on LinkedIn
joelblogs.co.uk | joelj.co.uk | joeljeffery.co.uk | jfdiphoenix.co.uk

Posts Tagged ‘SharePoint Administration’

The purpose of STSADM’s “copyappbincontent” command is:

stsadm –o copyappbincontent

Copies Web application–specific files, such as page resource (*.resx) files from their respective locations in the 12\CONFIG folder to the correct location in each Web application on the computer.

According to TechNet, there is no equivalent PowerShell cmd-let http://technet.microsoft.com/en-us/library/ff621081.aspxt:

No PowerShell Equivalent to stsadm -o copyappbincontent

However, there is a PowerShell cmd-let called Install-SPApplicationContent:

Install-SPApplicationContent

Copies shared application data to existing Web application folders.

Now that sounds pretty similar.

I’ve tried this out – making a custom layouts.sitemap.xml file, and invoking Install-SPApplicationContent. It copies/merges the sitemap into the correct place under inetpub\wwwroot\wss\VirtualDirectories\*\_app_bin.

So, how dissimilar are they? I’ve heard it said that the PowerShell version won’t apply your changes to the whole farm, only the current server. But surely, that’s what stsadm does too?

Let’s use the rather fantastic open-source ILSpy replacement for Reflector to reflect over the code,

STSADM’s copyappbincontent decompiled

// Microsoft.SharePoint.StsAdmin.SPCopyAppBinContent
public override void Run(StringDictionary keyValues)
{
    SPServiceInstance sPServiceInstance = SPWebServiceInstance.LocalContent;
    if (sPServiceInstance != null && sPServiceInstance.Status == SPObjectStatus.Online)
    {
        SPWebService contentService = SPWebService.ContentService;
        contentService.ApplyApplicationContentToLocalServer();
    }
    sPServiceInstance = SPWebServiceInstance.LocalAdministration;
    if (sPServiceInstance != null && sPServiceInstance.Status == SPObjectStatus.Online)
    {
        SPWebService administrationService = SPWebService.AdministrationService;
        administrationService.ApplyApplicationContentToLocalServer();
    }
}

Microsoft.SharePoint.PowerShell’s Install-SPApplicationContent decompiled

if (sPWebServiceInstance.Status == SPObjectStatus.Online)
{
  SPWebService administrationService = SPWebService.AdministrationService;
  ServiceHelper.TryToControlService("W3SVC", false, out flag, out flag2);
  administrationService.ApplyApplicationContentToLocalServer();
}
if (null != SPWebServiceInstance.LocalContent)
{
  if (SPWebServiceInstance.LocalContent.Status == SPObjectStatus.Online)
  {
    ServiceHelper.TryToControlService("W3SVC", false, out flag3, out flag4);
    SPWebService contentService = SPWebService.ContentService;
    contentService.ApplyApplicationContentToLocalServer();
  }
}

Conclusion

So, there you have it. Like two completely dissimilar things… in a pod.

To be clear: you need to invoke either of these methods on each server in your farm to deploy content from the 14 hive to the IIS virtual directories.

Or have I missed something?

Technorati Tags: PowerShell, SharePoint, SharePoint 2010, SharePoint Administration, SharePoint Development

SharePoint 2010 Locale Stapler / Master Locale

I’ve just put up another project on CodePlex. As usual, you can download the full project and source code for SharePoint 2010 Locale Stapler.

Why?

SharePoint doesn’t let you set a master locale per web application. SharePoint 2010 Publishing Features lets you specify that all sub sites inherit the locale settings from the parent… But this is sadly lacking.

How?

My project gives you a SharePoint farm solution with a couple of feature staplers (FeatureSiteTemplateAssociations) that fire for all templates (“GLOBAL”) at either the farm or web application level. On creation of a new site collection or site, the feature staple fires and looks up the regional settings of the root web at the root site collection for the web application, and then copies those settings to the current web (SharePoint site).

 

Manage Farm Features or Web Application Features

Code!

First off, here’s the code for the payload – the method to do the copying.

/// <summary>
/// Sets the locale for web.
/// </summary>
/// <param name="web">The web.</param>
public static void SetLocaleForWeb(SPWeb web)
{
    try
    {
        // find the Uri of the current web
        Uri currentWebUri = new Uri(web.Url);
        // work out the Uri for the root (e.g. 
        // http://webapp1/sites/site1/subsite1 becomes http://webapp1)
        UriBuilder rootWebUri = new UriBuilder(currentWebUri.Scheme,
            currentWebUri.Host, currentWebUri.Port);
        string rootSiteUrl = rootWebUri.ToString();
        // attempt to change the locale / regional settings by running as system...
        SPSecurity.RunWithElevatedPrivileges(delegate
        {
            // ...to access the root site/web of the web app
            using (SPSite rootSite = new SPSite(rootSiteUrl))
            {
                using (SPWeb rootWeb = rootSite.RootWeb)
                {
                    // ...and change the locale and regional settings of the current site
                    // to those of the root site collection root web's.
                    web.Locale = (System.Globalization.CultureInfo)rootWeb.Locale.Clone();
                    web.Update();
                    web.RegionalSettings = new SPRegionalSettings(rootWeb);
                    web.Update();
                }
            }
        });
    }
    catch (Exception ex)
    {
        LogError(System.Reflection.MethodBase.GetCurrentMethod().Name,
            ex.Message, ex.StackTrace);
    }
}

And here’s the code that’s run on FeatureActivated at the Web level (and a similar one at the Site level):

/// <summary>
/// Occurs after a Feature is activated.
/// </summary>
/// <param name="properties">An <see cref="T:Microsoft.SharePoint.SPFeatureReceiverProperties"/>
/// object that represents the properties of the event.</param>
public override void FeatureActivated(SPFeatureReceiverProperties properties)
{
    if (properties.Feature.Parent is SPWeb)
    {
        SPWeb web = (SPWeb) properties.Feature.Parent;
        Utilities.SetLocaleForWeb(web);
    }
}

Next, we need to create a a feature to do the stapling itself. This should include an element manifest (or elephant) with FeatureSIteTemplateAssociation nodes.

<?xml version="1.0" encoding="utf-8"?>
<Elements xmlns="http://schemas.microsoft.com/sharepoint/">
  <!--Web-level feature-->
  <FeatureSiteTemplateAssociation
    Id="dd5923f9-05a4-4d6a-a78f-0dd8b08ff079"
    TemplateName="GLOBAL" />
  <!--Site-level feature-->
  <FeatureSiteTemplateAssociation
    Id="54fa6d42-c145-49dc-b2eb-f5db548bc111"
    TemplateName="GLOBAL" />
</Elements>

Once again, don’t forget the full project and source code is available on CodePlex here: http://slash.codeplex.com.

Enjoy!

Technorati Tags: SharePoint, SharePoint 2010, SharePoint Administration, SharePoint Development

Despite protests from music lovers, here is another of the songs from my SharePoint Show.

This is a mix from several live versions. In this song we visit what you can and can’t do in the Sandbox, and the several ways in which the User Code Service protects our server from the evils of any user code that tries to run a “Bad Command”.

Apologies to Lady Gaga, and all those who have been affected by issues in this video.

Technorati Tags: SharePoint, SharePoint 2010 Training, SharePoint Administration, SharePoint Architecture, SharePoint Development, SharePoint Videos

How Does the Recycle Bin Work in SharePoint 2010?

I was recently asked how the dual stage recycle bins worked in SharePoint 2010 by one of my students (thank you, Andrew!), and I realised that I didn’t know enough. It’s not just me either. This has to be one of the poorest-documented SharePoint features on the Internet.

This article charts my journey of discovery.

Introduction

The SharePoint Recycle Bin is a complex entity. It has two stages, both accessible from within the site collection.

The 1st stage, known as the “end user recycle bin”, is where lists, documents and list items delete by users are sent. Their storage limit is known to be included in whatever site collection quota.

The 2nd stage, (accessibly only by site collection administrators) known as the “deleted from end user recycle bin”, is where such documents are sent when the user deletes them from the recycle bin. Their storage limit is known to be a percentage on top of the site collection quota, and is specified as a single setting, that applies to a whole web application.

Objectives

This experiment aims to show through empirical means how the SharePoint 2010 1st and 2nd Stage Recycle Bins behave.

Hypothesis

It is commonly understood that when the 1st stage time-to-live is reached, the deleted items will migrate to the 2nd stage recycle bin, to be held their indefinitely, or until the percentage of space of the site collection quota has been reach.

It is documented on Microsoft TechNet that the Recycle Bin timer job runs daily to find deleted content and “moves it to the next stage or deletes it”:

image_thumb23

The behaviour is further documented on p68 of the Microsoft Press book “SharePoint 2010 Administrator’s Companion” by Bill English:

image_thumb24

The TechNet page “Plan to protect content by using recycle bins” is ambiguous in its wording, but can be read as contradicting the other two sources.

Firstly…

When a user does this The item is The item can be restored by

Deletes an item

Held in the first-stage Recycle Bin until the item is deleted from the Recycle Bin or the item has been in the Recycle Bin longer than the time limit configured for an item to be held in the Recycle Bin.

Users or site collection administrators

Deletes an item from the Recycle Bin

Held in the second-stage Recycle Bin

Site collection administrators

And secondly…

The time limit for the Recycle Bins applies to the total time after the item was first deleted — not the time spent in either Recycle Bin stage.

Method

This experiment was carried out with SharePoint 2010 SP1 and the July 2011 Cumulative Update.

Two documents were placed into a Shared Documents library.

image_thumb17

These documents were then deleted within 60 seconds of each other. Next, within a further 60 seconds, the second document was deleted from the 1st stage recycle bin. Its presence in the 2nd stage bin was then confirmed.

The site collection had a quota of 100MB.

image_thumb22

The web application recycle bin time to live was adjusted down to 1 day, and the system clock was advanced by 24 hours.

image_thumb11

The “Recycle Bin” timer job in Central Administration was then forced to run.

image_thumb9

Observations

After the Recycle Bin timer job completed, both the 1st and 2nd stage recycle bins were found to be empty.

image_thumb1

Nothing.

image_thumb7

Not a sausage.

Conclusions

  1. There is a timer job that empties recycle bins. If this does not run, nothing ever gets deleted.
  2. The timer job deletes from 1st and 2nd stage bins anything that is older than the retention age FROM THE DATE FIRST DELETED, up to the maximum size allowed through quotas.
  3. The only way a deleted item can get into the 2nd stage bin is if a user deletes it from the 1st stage recycle bin.
  4. You really need a file-level backup and restore solution.
  5. Even really clever people don’t understand how this works.

Technorati Tags: Recycle Bin, SharePoint 2010, SharePoint Administration

Renaming a Standalone SharePoint 2010 Server

OK. You never create standalone servers. I know. But, let’s just say you *did* have one, maybe for development or test, and let’s say you had such an environment on your laptop, and also let’s say your machine had an embarrassing name that you needed to change before you next demoed SharePoint stuff on it… OK, you get the picture. Smile

The Microsoft recommended steps are:

  1. Rename your PC using Computer properties:
    Renaming your PC
  2. Reboot.
  3. Run the PowerShell Command “Rename-SPServer

There is only one problem with this suggested method: it’s a steaming pile of nonsense.

The correct procedure would be:

  1. Rename your server using “Rename-SPServer”
  2. Rename the PC using Computer properties
  3. Reboot
  4. Rename your SQL instances
  5. Restart SQL
  6. iisreset /noforce

If you are unlucky enough to have tried to follow the official guidelines and renamed the PC before executing Rename-SPServer, you would get a message like this when trying to launch the SharePoint Management Shell:

The local farm is not accessible. Cmdlets with FeatureDependencyId are not registered.

Then the correct recovery would be:

  1. Rename the server using “stsadm -o renameserver
  2. iisreset /noforce
  3. Rename your SQL instances.
  4. Restart SQL
  5. iisreset /noforce

Best of luck!

Technorati Tags: PowerShell, SharePoint, SharePoint 2010, SharePoint Administration