Archive

I’m currently working on a document management project, which holds 10+ million documents. During a full crawl we had a temporary network issue, which resulted in 340.000 crawl errors. I didn’t want to do a new full crawl again, since the full crawl did finish with all documents. Instead, I want those items to be picked up in the next incremental crawl. Using Central Administration you can select the option “Recrawl the item in the next crawl” for each item which caused an error, but I obviously didn’t want to manually select this option for all errors.

To automate this, I’ve created a PowerShell script which can list the errors, but can also mark all errors automatically for the recrawl. The explanation of the script can be found in the comments of the script.

#——————————————————————————# Provide parameters#——————————————————————————param (# Name of the search service application is mandatory [string] $SearchServiceApplicationName = $(throw “Please specify a search service application”), # By default, use all available content sources[string] $ContentSourceName=“”, # By default only a list of the errors is shown [switch] $RecrawlErrors = $false)

#——————————————————————————# Set some constant values#——————————————————————————# The id of the error stating a document will be processed in the next crawl[int] $errorIdRetryNextCrawl = 437# The number of documents which should be retrieved per batch from the ssa[int] $batchSize = 1000# 2 stands for Errors[int] $errorLevel = 2

Today I found a site collection on a customer environment which gave a completely blank page when you opened it via a browser. It didn’t gave a 404 (Not Found) error, it was just a blank page. I decided to figure out what was happening and found that during the creation of the site collection, an IISRESET had taken place. Because of this, the site wasn’t completely provisioned. Well, if it wasn’t completely provisioned, I don’t need it… Nobody could have added content.

I found out that I couldn’t remove the site using Central Administration. When you navigate to the site collection using the “Delete a site collection” page, the details (right hand site of the page) where not loaded and you cannot select the site collection. So… I wanted to delete the site using PowerShell, but this gave me an error:

Apparently, the normal remove-spsite cmdlet cannot delete a site collection which is not fully provisioned, and this cmdlet doesn’t have a force flag. To forcefully delete the site collection, I used the SPContentDatabase.ForceDeleteSite method:

For our projects we always try to avoid manual configurations. This is because it is a tedious and error prone process if you work with a DTAP environment. To avoid this, we also try to script as much as possible for SharePoint Online projects. Lately we worked with creating lookup fields in SharePoint online, using PowerShell and CSOM. Creating fields this way is pretty easy, but connecting lookup fields forced us to think about casting the Microsoft.SharePoint.Client.Field object to a Microsoft.SharePoint.Client.FieldLookup object.

Within CSOM this can be done by leveraging the ClientRuntimeContext.CastTo method, but… This is a generic method (object of type T). This is something which is not easily supported by PowerShell. To use this method, you can use reflection using the MakeGenericMethod method.

For SharePoint On Premise platforms it’s a good practice to use a warm-up script to avoid long loading times in the morning. By default IIS recycles the web application pools every night to clean up the memory and this is a good practice. Todd Klindt written a nice post about using the Invoke-WebRequest cmdlet which is available in PowerShell v3 and how to use this as basis for your warm-up script.

I used it as a basis and created the script you find below. Important notes:

The script will load the start page of the root site collection of every web application.

Different types of web templates, use different assemblies. If you want to preload all assemblies, ensure you load the different types of sites. The additionalUrls array is used for that in the script.

When you use multiple front-end servers, you want schedule the script on all front-end servers. Also make sure the server doesn’t use a load balancer when you are on the server itself, you can do this by updating the hosts file.

#——————————————————# Since the root of web applications use different templates then other site collections, also load other sites of different# types. This ensures their assemblies also get loaded in memory#——————————————————$additionalUrls= @(“http://developmentserver/sites/search&#8221;,“http://developmentserver/site/teamsite&#8221;)$additionalUrls|ForEach-Object {write-host ([string]::Format(“Additional web request fired for Url: {0}… “,$_)) -NoNewlineWrite-Status-response (Invoke-WebRequest$_-UseDefaultCredentials-UseBasicParsing)}

One of my projects is a huge SharePoint 2013 On-Premise platform with 200.000+ (sub) sites. I’ve created a custom web template to ensure all sites are created the same way, with the same settings. A web template works very well for these environments, but when you update the template, the changes will not be made in all existing sites. The web template will only be applied when creating new sites.

I will not throw away all sites when we have new updates to re-create the sites, but I will re-active certain features to ensure the updates are applied.

For now the last section about generating documentation for your custom SharePoint solution. The following PowerShell scripts will provide you with an overview of activated features on your Farm, WebApplication and Site Collections. Since this script is meant for custom solutions, I assume you have used a prefix (Visual Studio adds the solution name by default as a prefix to all features).

Sometimes you want an overview of your custom farm solutions which are deployed on your farm. Normally I prefix all my solutions to make it clear who created them. Using this prefix you can easily run a PowerShell script which provides you with a list of installed solutions and the web applications to which these solutions are deployed: