How to warm-up SharePoint or other web applications and WCF (SOAP) services with PowerShell

There are many reasons you might want to warm-up a web application occasionally. It can be after a fresh deployment or on a regular basis after recycling application pools. Some times you might also need to warm-up SOAP services without going through front-end.

It might seems to be any easy task specially if you have PowerShell 3.0 or higher on your servers, but after Googling a while and reviewing some of the top hits I discovered that each solution is missing a part. Some only work in a single server scenario and some has forgotten that each HTTP response might contain links to scripts and images that we need to download and finally I could not find anything for SOAP services that just works. Long story short I decided to put together a simple script that just works and is easy to change to everyone’s needs.

Please note that my only assumption is you have PowerShell 3.0+ in your servers.

Currently the script takes care of the following tasks, but I will most likely improve it to cover other useful scenarios.

  • Calling SOAP operations and sending parameters and custom headers
  • Calling front-end URIs and downloading scripts and images that are local to the front-end
  • Logging to a configurable folder and file name
  • Cleaning up old log files

Currently, I have the following points in mind to improve the script.

  • Put configuration in a different file.
  • Improve function definitions (named and typed parameters and description).
  • Default values for parameters when it makes sense (e.g. log folder can be the current folder).
  • Support REST services.

I’m open to any suggestion and feature request. Please let me know if you found it useful or if have got something wrong.

How to warm-up SharePoint or other web applications and WCF (SOAP) services with PowerShell

How to create search query content source in SharePoint using PowerShell

They are called Content Sources in the graphical user interface of SharePoint and Search Query Content Source when using PowerShell. A content source is basically pointing to a source of data that can be indexed in the search database. Because the data is indexed, when later users run queries the result is returned almost instantaneous. It is very easy to add a content source by using SharePoint Central Administration, but you might need to create a long list of content sources in a batch for example as part of a disaster recovery process or many other reasons. Here is one way I do it in a PowerShell script.

$contentSourceConfig = @(
    @{
        Name = "Articles"
        StartAddresses = "http://mydomain1/site1/fr,http://mydomain1/site1/nl,http://mydomain1/site1/en"
    },
    @{
        Name = "Technical"
        StartAddresses = "http://mydomain1/site2/fr,http://mydomain1/site2/nl,http://mydomain1/site2/en"
    }
)

foreach($config in $contentSourceConfig) {
    $contentSourceName = $config.Name
    $startAddresses = $config.StartAddresses
    $contentSource = Get-SPEnterpriseSearchCrawlContentSource $contentSourceName -SearchApplication $ssa -ErrorAction SilentlyContinue
    if ($contentSource) { $contentSource.Delete() }
    $contentSource = New-SPEnterpriseSearchCrawlContentSource $contentSourceName -Type "Web" -StartAddresses $startAddresses -SearchApplication $ssa
    Write-Host "Search crawl content source: $contentSourceName created successfully."
}

As you see in the above example I have put all the required configuration in one array of custom objects. If you need to add more content sources you may simply copy-past one and change the properties. This way the configuration is separated and easier to read or change while still it is in the same file with the script so you won’t have to rely on extra XML file(s) to put beside the script.

If you are more comfortable by separating the configuration from the script. You can cut the first part and past it to another script file or use the XML approach.

For more details about the cmdlets I’ve used I suggest you have a look on the following MSDN articles:

How to create search query content source in SharePoint using PowerShell

Connecting WebParts programmatically in SharePoint

Let’s start by an example.

Example

In this blog post, I’m going to assume we have a webpart that displays a contact list and another one that displays a map with the possibility to pinpoint an address. To keep things simple I assume the address is merely a string.

public class Map : WebPart
{

}

public ContactList : WebPart
{
    [Personalizable]
    string SelectedAddress { get; set; }
}

To connect these webparts, we typically do the following four steps:

  • Write an interface to contain the information we need to transfer (i.e. Address)
  • Implement the interface in the provider webpart (i.e Map)
  • Write a callback method in the provider webpart to return the address.
  • Write another callback method in the consumer webpart to receive the address.
public interface IAddressConnection {
    string SelectedAddress { get; set; }
}

public class Map : WebPart
{
    [ConnectionConsumer("Pinpoint address", "Address")]
    public void ConsumeAddress(ISelectedAddress address)
    {
        // Set the map extent and display a pinpoint.
    }
}

public ContactList : WebPart, IAddressConnection
{
    [Personalizable]
    public string SelectedAddress { get; set; }

    [ConnectionProvider("Selected address", "Address")]
    public ISelectedAddress ProviderAddress()
    {
        return this;
    }
}

ConnectWebParts()

In order to connect two webparts, you need an instance of each webpart plus the WebPartManager (to be precise the SPLimitedWebPartManager) for the page they are hosted in and of course you need to know which of their connection points you are going to connect.

Let’s say you already have the WebPartManager and the two webparts at hand. In that case you can use the following method. Note that T is the interface these two webparts share.

public void ConnectWebParts(WebPartManager webPartManager, WebPart consumer, WebPart provider)
{
    var consumerConnection =
        webPartManager.GetConsumerConnectionPoints(consumer)
            .Cast<ConsumerConnectionPoint>()
            .FirstOrDefault(c => c.InterfaceType == typeof(T));
    var providerConnection =
        webPartManager.GetProviderConnectionPoints(provider)
            .Cast<ProviderConnectionPoint>()
            .FirstOrDefault(c => c.InterfaceType == typeof(T));
    webPartManager.ConnectWebParts(provider, providerConnection, consumer, consumerConnection);
}

The above method assumes that these webpart only have one connection point of type T, which makes sense most of the time, but in case your webpart have multiple connection points of the same interface.

By using ConnectWebParts method, we can easily connect the Map to the Contacts webpart.

ConnectWebParts<IAddressConnection>(webPartManager, map, contacts)

But, how to get the WebPartManager and instances of the webparts? you might ask. These webparts might be used in any page, but you definitely know on which page you are going to connect them. By having a reference to the page you can instantiate a WebPartManager and with that you can find you webparts too. If you are doing this in the code-behind of the page or a control (or webpart) in the page, you can do as following:

var webPartManager = WebPartManager.GetCurrentWebPartManager(this) // or this.Page if we are in a control.
var consumer =
    webPartManager.WebParts.Cast<WebPart>()
        .FirstOrDefault(w => w.GetType() == typeof(Map));
var provider =
    webPartManager.WebParts.Cast<WebPart>()
        .FirstOrDefault(w => w.GetType() == typeof(Contacts));
ConnectWebParts<IAddressConnection>(webPartManager, consumer, provider)

What if the code is not running in the page? Then you need to get an instance of the page. Let’s use SPLimitedWebPartManager this time.

using (var site = new SPSite("http://mydomain/mysite"))
{
    var file = site.RootWeb.GetFile("myfolder/mypage.aspx");
    var webPartManager = file.GetLimitedWebPartManager(PersonalizationScope.Shared);
    var consumer =
        webPartManager.WebParts.Cast<WebPart>()
            .FirstOrDefault(w => w.GetType() == typeof(Map));
    var provider =
        webPartManager.WebParts.Cast<WebPart>()
            .FirstOrDefault(w => w.GetType() == typeof(Contacts));
    ConnectWebParts<IAddressConnection>(webPartManager, consumer, provider)
}

Please note that you might need to checkout the page, publish and approve it if versioning or approval workflow has been enabled on the library that contains the page.

I hope you find it useful. By the way, don’t forget the null checks!

Connecting WebParts programmatically in SharePoint

BCS Part 1 – What can I build and what is the best way to do that?

If you already know SharePoint and probably experienced developing application in this platform you already know that when thinking about a new solution and all the requirements you’re going to meet in your project, picking the right tools and finding the best way to build the right solution is not always easy. When thinking about maintenance costs, upgradability and deeper integration with SharePoint, solutions that make better use of out the shelf tools win most of the time. Even with the introduction of Apps in SharePoint 2013, you can still benefit a lot from using Business Connectivity Services (aka BCS). Apart from the range of features and tools that are provided under the name of BCS (e.g. WebParts, integration with Secure Store Service, Office client applications) one of the main and sometimes overlooked areas is how BCS and Search can work together. If you enable search over the entities of your external system, you can surface data coming from it through search and you can even customise search pages to create totally different user experience (e.g. I remember a shopping cart solution that might be a subject for a future blog post).

Instead of going through all the possible solutions, in this post I’m going to provide you with some links I have gathered from around the web that I think are essential if one needs to make real word solutions with these technologies. In the future posts I will go into the details and on cover the missing documents that you will need to make solid solutions.

First of all the basics (please note that REST, ODATA and some other features are not available out-of-the-box in SP2010):

And then read carefully the followings to get to know Search interoperability with BCS:

Don’t worry if there are terms that you don’t understand completely, I provide some examples and behind the scene information so you can understand them well.

BCS Part 1 – What can I build and what is the best way to do that?

Everything you need to know about BCS – Intro

Business connectivity services is an integral part of Microsoft SharePoint Server when it comes to interacting with external systems (i.e. Line of Business Systems). There lots of tools and foundation from QCRUD operations to out-of-the-box web parts to let you surface the data and let users interact with it. For when you need to go further there is a capabale object model that can be utilized to make custom solutions most probably used to develop custom web parts. There is a visual designer in Visual Studio 2010+ that makes it easier to design and validate the interface between SharePoint and your external system. In SharePoint 2013, Microsoft has taken it to the next level by supporting OData, event listeners, apps, REST interface and a better external list (still could be better 😉 ).

With all these said, what makes working wih BCS complex is the shortage of learning resources and the way its object model and BDC files (interface definition) are design (specially the latter). You cannot even trust the documentations on MSDN sometimes (I will come back to this later). Although there are blog posts here and there to help you move forward, sometimes you are on your own to discover hidden gems and pitfalls.

In these series of posts my aim is to share my experience in building real world BCS solutions so you can save valuable development time by focusing on more productive tasks. I will try to show you the safe paths and pitfalls and be as complete as possible. There is not much difference between SharePoint 2010 and 2013, but when things are a little different I will show you how. At the end, comments are always welcome!

Comming up:

  • Part 1 – What can I build and what is the best way to do that?
  • Part 2 – Interacting with databases (SQL Server and Oracle as examples)
  • Part 3 – Interacting with other sources / .NET Connectivity Assemblies
  • Part 4 – Interacting with dynamic sources / Custom Connectors
  • Part 5 – Searchable BCS solutions
  • Part 6 – Enhancing BCS Performance
  • Part 7 – Surfacing BCS with search
  • Part 8 – Surfacing BCS with out-of-the-box web parts
  • Part 9 – Surfacing BCS with custom web parts
  • Part 10 – Surfacing BCS with Java Script and JSON (MVVM) in SharePoint 2010
  • Part 11 – Adding CSOM support to BCS in SharePoint 2010
  • Part 12 – Business Data Catalog file, the complete reference
  • Part 13 – Bullet-proof deployment of BCS solutions in Farm
  • Part 14 – BCS and Claims-Based-Authentication considerations

Do you have any suggestions for another part? then let me know in the comments.

Everything you need to know about BCS – Intro

First step in developing apps for SharePoint Online – Enabling F5

It’s Just a quick post to share one of my first experiences with SharePoint online and that’s how to enable F5 experience in Visual Studio. When you start writing your first App for SharePoint Online you might get the same error as me, saying that “Sideloading of apps is not enabled on this site”

Sideloading of apps is not enabled on this site
Sideloading of apps is not enabled on this site

It’s because the “Developer” feature is not activated by default and you need to activate it manually, but since it’s an online version of SharePoint things are a little bit different that you local development environment (a good article on how to prepare your local development environment) and you need to use CSOM (Client Side Object Model). I have just translated the c# equivalent to a few lines of PowerShell code so you can type it into your SharePoint Online Management Shell (if you have not installed it, you can download it from here). Here is the code:

<br />$siteurl = "https://yourwebsite.sharepoint.com"<br />$username = "yourusername"<br />$password = ConvertTo-SecureString -String 'yourpassword!' -AsPlainText -Force<br />[Microsoft.SharePoint.Client.ClientContext] $context = New-Object Microsoft.SharePoint.Client.ClientContext($siteurl)<br />[Microsoft.SharePoint.Client.SharePointOnlineCredentials] $credentials = New-Object Microsoft.SharePoint.Client.SharePointOnlineCredentials($username, $password)<br />$context.Credentials = $credentials<br />$site = $cc.Site<br />$sideLoadingGuid = New-Object System.Guid "AE3A1339-61F5-4f8f-81A7-ABD2DA956A7D"<br />$site.Features.Add($sideLoadingGuid, $true, [Microsoft.SharePoint.Client.FeatureDefinitionScope]::None)<br />$context.ExecuteQuery();<br />
First step in developing apps for SharePoint Online – Enabling F5

Add / Remove event receivers to list / content types in SharePoint with PowerShell

Although it’s simple but it’s a little bit tricky. Adding / removing an event receiver to a list and content type is the same you just need to use the appropriate collection is an SPWeb object.

Here is how to add / remove an event receiver to / from a list:

# The following code registers an event receiver for when an item is being added to a list
$web = Get-SPWeb "http://yourwebsiteurl"
$list = $web.Lists["your list name"]
$list.EventReceivers.Add("ItemAdding", "Full Assembly Name", "Full.Class.Name")

Removing an event receiver is as easy as:

# Be careful about the index value for when you have more than one event receiver!
$list.EventReceiver[0].Delete()

As you can see below adding an event receiver to a content type is very similar:

# The following code registers an event receiver for when an item is being added to a list
$web = Get-SPWeb "http://yourwebsiteurl"
$ctype = $web.ContentTypes["your content type name"]
$ctype.EventReceivers.Add("ItemAdding", "Full Assembly Name", "Full.Class.Name")

And so is deleting it:

# Be careful about the index value for when you have more than one event receiver!
$ctype.EventReceiver[0].Delete()

Now more important is the tricky part. If you have used this content type to create other / list instances then you should also call the following command to propagate the change:

$ctype.Update($true)
Add / Remove event receivers to list / content types in SharePoint with PowerShell