TaxonomyService GetTermSets Failed to compare two elements in the array

December 23, 2016 - 16:36, by Steven Van de Craen - 0 Comments

This issue happed on a SharePoint 2013 environment that got upgraded from SharePoint 2010 and the farm includes Language Packs (Dutch in our case). When navigating to the Term Store Management Tool it is impossible to expand the Term Group “Search Dictionaries” for the non-English language. This system group is created for the Search Service Application and contains dictionaries for Company Inclusions, Company Exclusions, Query Spelling Inclusions and Query Spelling Exclusions, but the Term Sets are only provisioned for LCID 1033 (English) and that’s causing the issue.

Search Dictionaries Term Group


When Dutch is selected we get ‘Deze bewerking kan niet worden voltooid. Het termenarchief is mogelijk niet beschikbaar’.

Message from webpage – Deze bewerking kan niet worden voltooid. Het termenarchief is mogelijk niet beschikbaar

Failed to compare two elements in the array. 
at System.Collections.Generic.ArraySortHelper`1.Sort(T[] keys, Int32 index, Int32 length, IComparer`1 comparer)   
at System.Collections.Generic.List`1.Sort(Int32 index, Int32 count, IComparer`1 comparer)   
at Microsoft.SharePoint.Taxonomy.TermSetCollection.CreateTermSetCollection(List`1 sharedTermSets, TermStore termStore)   
at Microsoft.SharePoint.Taxonomy.WebServices.TaxonomyInternalService.GetTermSets(Guid sspId, Guid guid, Boolean includeNoneTaggableTermset, Guid webId, Guid listId, Int32 lcid)



There seems to be no easy way to rename or add a localized name for a system Term Set, but we can make use of reflection and call Microsoft.SharePoint.Taxonomy.TermSet.SetName(string value, int lcid)

In a PowerShell script that might look like this:

asnp Microsoft.SharePoint.PowerShell -ea 0 | Out-Null cls # Functions function Get-InstanceFieldNonPublic($obj, $name) { $t = $obj.GetType() $result = $t.InvokeMember($name, 'GetField, Instance, NonPublic', $null, $obj, $null) return $result } function Invoke-InstanceMethodNonPublic($obj, $name, $params) { $t = $obj.GetType() $result = $t.InvokeMember($name, 'InvokeMethod, Instance, NonPublic', $null, $obj, $params) return $result } ### INIT $tSession = Get-SPTaxonomySession -Site "http://intranet" $tStore = $tSession.TermStores[0] $tGroup = $tStore.Groups["Search Dictionaries"] $tGroup.TermSets | % { $tSet = $_ # 'Add' another language label for TermSet -- 1043 is Dutch Invoke-InstanceMethodNonPublic -obj $tSet -name "SetName" -params @($tSet.Name, 1043) # Query known language labels for TermSet Get-InstanceFieldNonPublic -obj $tSet -name "names" } # Commit changnes -- uncomment to apply # $tStore.CommitAll()

As always; be careful with reflection as it is not supported and allows you to harm your environment beyond repair. That said it did nicely resolve the issue.

Revisited - Upgrading SharePoint - Some views not upgraded to XsltListViewWebPart

August 24, 2016 - 15:03, by Steven Van de Craen - 2 Comments

The old

Back in 2013 when I was a regular blogger I posted about a tool/logic that would assist you in SharePoint migrations where some Views of Lists and Libraries would remain in the ‘old’ display mode. This issue happens with all version upgrades (2007 > 2010 > 2013/2016) and is actually still present.


The tool I wrote back then would recreate the view with exact same settings but I found it still wouldn’t do a 100% conversion of views.

The new

With the release of SharePoint 2016 I’m doing a lot of upgrade projects from 2007/2010 to 2016 and I decided to have a second look at the mechanism behind all this. I inspected the (Xslt)ListViewWebPart with ILSpy/Reflector to see the logic involved. I then converted that logic into a set of Powershell functions that can be called on various levels.

Note that I’m making calls to internal code using Reflection, I’ve used this script with success at all migration projects, but the necessary disclaimers apply since we’re dealing with reflection here.

The details

Here’s the main function that checks an individual Web Part Page for “upgradeable” Web Parts and if applicable will perform the upgrade of ListViewWebParts. It also handles any check-out/check-in that may be required.

function Upgrade-ListViewWebPartsOnPage([Microsoft.SharePoint.SPFile]$page, [bool]$checkOnly)
if ($page.Exists) {

if ($checkOnly)
$man = $page.GetLimitedWebPartManager('Shared')
$lvWps = @($man.WebParts) | ? { ($_ -is [Microsoft.SharePoint.WebPartPages.ListViewWebPart]) -and (Check-ListViewWebPartNeedsUpgrade -lvwp $_) }

if ($lvWps.Count -gt 0) {
Write-Host ("Page " + $page.Web.Url + "/" + $page.Url + " contains upgradeable ListViewWebParts") -ForeGroundColor Yellow
if ($page.RequiresCheckout) {
if ($page.CheckOutStatus -ne 'None') {
try { $page.UndoCheckOut() } catch { $page.CheckIn("SYSTEM"); }


$man = $page.GetLimitedWebPartManager('Shared')

if ($man -ne $null) {
try {
$lvWps = @($man.WebParts) | ? { ($_ -is [Microsoft.SharePoint.WebPartPages.ListViewWebPart]) -and (Check-ListViewWebPartNeedsUpgrade -lvwp $_) }

if ($lvWps.Count -gt 0) {
Write-Host ("Processed " + $page.Web.Url + "/" + $page.Url + " for ListViewWebParts") -ForeGroundColor Green

$lvWps | % {
$wp = $_

$view = [Microsoft.SharePoint.WebPartPages.ListViewWebPart].InvokeMember("View", 'GetProperty, Instance, NonPublic', $null, $wp, $null)
$wpType = Get-WebPartTypeId -view $view

[Microsoft.SharePoint.WebPartPages.ListViewWebPart].InvokeMember("NewWebPartTypeId", 'SetProperty, Instance, NonPublic', $null, $wp, $wpType)


if ($page.RequiresCheckout) {

if ($page.Item.ParentList.EnableMinorVersions) {
} else {
if ($page.RequiresCheckout) {
try { $page.UndoCheckOut() } catch { $page.CheckIn("SYSTEM"); }
} catch {
Write-Host ("Manually check " + $page.Web.Url + "/" + $page.Url + " for ListViewWebParts WebParts - Error: " + $_) -ForeGroundColor DarkYellow

Then there are various functions that do the same thing but on View, List or Web scope. They essentially all make calls to the above function in a loop of that particular scope.

function Upgrade-ListViewWebPartsOnView([Microsoft.SharePoint.SPView]$view, [bool]$checkOnly)
$web = $view.ParentList.ParentWeb
$page = $web.GetFile($web.Url + "/" + $view.Url)

Upgrade-ListViewWebPartsOnPage -page $page -checkOnly $checkOnly

function Upgrade-ListViewWebPartsOnList([Microsoft.SharePoint.SPList]$list, [bool]$checkOnly)
@($list.Views) | % {
$view = $_

Upgrade-ListViewWebPartsOnView -view $view -checkOnly $checkOnly

function Upgrade-ListViewWebPartsOnWeb([Microsoft.SharePoint.SPWeb]$web, [bool]$checkOnly)
@($web.Lists) | % {
$list = $_

Upgrade-ListViewWebPartsOnList -list $list -checkOnly $checkOnly

Finally there are the base functions that handle the checking and upgrading of the Web Parts similar to how the API handles it. They use reflection for methods that are marked internal.

function Check-ListViewWebPartNeedsUpgrade([Microsoft.SharePoint.WebPartPages.ListViewWebPart]$lvwp)
$view = [Microsoft.SharePoint.WebPartPages.ListViewWebPart].InvokeMember("View", 'GetProperty, Instance, NonPublic', $null, $lvwp, $null)
$rh = [Microsoft.SharePoint.SPFile].Assembly.GetType("Microsoft.SharePoint.WebPartPages.SPWebPartReflectionHelper")

$g1 = $rh.InvokeMember("GetWebPartTypeID", 'InvokeMethod, Static, NonPublic', $null, $null, ([Microsoft.SharePoint.WebPartPages.XsltListViewWebPart]))
$g2 = Get-WebPartTypeId -view $view

# If ids are identical it needs to upgrade
return ($g1 -eq $g2)

function Get-WebPartTypeId([Microsoft.SharePoint.SPView]$view)
## Note: Logic taken from Microsoft.SharePoint.WebPartPages.BaseListViewToolPart.ApplyChanges()

$list = $view.ParentList
$rh = [Microsoft.SharePoint.SPFile].Assembly.GetType("Microsoft.SharePoint.WebPartPages.SPWebPartReflectionHelper")
$result1 = $rh.InvokeMember("GetWebPartTypeID", 'InvokeMethod, Static, NonPublic', $null, $null, ([Microsoft.SharePoint.WebPartPages.ListViewWebPart]))
$result2 = $rh.InvokeMember("GetWebPartTypeID", 'InvokeMethod, Static, NonPublic', $null, $null, ([Microsoft.SharePoint.WebPartPages.XsltListViewWebPart]))

if (($view -ne $null) -and ($view.Type -ne "HTML"))
if (($view.Type -eq "GRID") -and ([Microsoft.SharePoint.Utilities.SPUtility]::ContextCompatibilityLevel -ge 15))
$result = $result2
$result = $result1
if ($view -eq $null)
$result = $result2
$useDV = [Microsoft.SharePoint.WebPartPages.SPWebPartManager].InvokeMember('UseDataView', 'InvokeMethod, Static, NonPublic', $null, $null, @($list, $view))

if ($useDV)
$result = $result2
$result = $result1

return $result

The goods

Here’s a nice little download that contains all functions in a single file, ready for you to use – if you dare….


If you have any feedback let me know in the comments!

SharePoint 2013: InfoPath client forms may open twice [Oct15CU bug]

December 16, 2015 - 20:47, by Steven Van de Craen - 2 Comments


After a recent Patch Night one of my customers had pulled in SharePoint updates along with Windows Updates and people started complaining about changed behavior

  1. PDF files no longer immediately open in the browser. Instead the PDF client (Adobe Reader) opens up and provides rich integration with options to check-out and such
  2. InfoPath client forms would open twice; meaning the form opens when clicking the link, but also an extra dialog appears to open the form. Users click this and receive messages about the form already being locked (by themselves!)

Hello little bug

We traced it to core.js (and core.debug.js) having a modified date of “15/09/2015 14:45” where functionality to provide “Acrobat Pro X integration” was introduced.

The function OpenDocWithClient is called in two different locations but the return value is ignored. This makes the page refresh that occurs when clicking the InfoPath form link execute more than desired.

Here’s the original (bugged) and modified (fixed by me) versions:

Original (bugged) core.js image

As you can see I added the “return” keyword for the function call, so the event cancelling can continue to bubble up.

For the minified version (core.js) you’ll have to do some digging but if you look for static strings you can find the function call. I think it was “m()” in my case.

Here ya go

You can download this archive which contains both my original and modified versions. If you modify your environment you have to update all web front ends and users will have to clear the browser cache, but no iisreset is required.

Note that later patches may overwrite the system files again and undo your manual changes.

End credits

This bug is introduced with the October 2015 updates, including the full Cumulative Update package. We escalated the case to Microsoft and they confirmed the issue and our workaround. It will probably remain present in the upcoming Cumulative Updates (November, December, …) because it’s not wide-spread and also the PG needs to fit it in into their schedule.

SharePoint 2013: Programmatically set crawl cookies for forms authenticated web sites

August 29, 2015 - 07:54, by Steven Van de Craen - 0 Comments

Last week I was having difficulties in crawling forms authenticated web sites. When configuring a crawl rule to store the authentication cookies the login page was returning multiple cookies with same name but different domain.

Add Crawl Rule

This gave issues in a later stage (during crawl) because all cookies would be sent along with the request, the target system had issues correctly identifying us due to these “duplicate” cookies.

You can easily check the request information that is sent during crawl by starting fiddler on the crawl server and configuring the proxy settings to http://localhost:8888 (default Fiddler settings).

 Search Proxy Setting

In the end we chose for an alternate method of configuring the cookies, namely through PowerShell. This gave us the ultimate flexibility to configure exactly the cookies we wanted to pass along with the crawl requests.

asnp microsoft.sharepoint.powershell -ea 0 | Out-Null $ssa = get-spenterprisesearchserviceapplication $crPath = 'http://authenticatedwebsite*' # Get or create crawl rule $cr = Get-SPEnterpriseSearchCrawlRule -SearchApplication $ssa | ? { $_.Path -eq $crPath } if ($cr -eq $null) { $cr = New-SPEnterpriseSearchCrawlRule -Path $crPath -SearchApplication $ssa -Type InclusionRule -AuthenticationType CookieRuleAccess -FollowComplexUrls $true } # Set cookie credentials $cr.SetCredentials('CookieRuleAccess', 'myUser=crawlUser; myPwd=crawlPassword', 'http://cookie-set-via-powershell')


SharePoint 2013: Some observations on Enterprise Search

August 13, 2015 - 16:44, by Steven Van de Craen - 0 Comments

I’m doing some testing with the Enterprise Search in SharePoint 2013 for a customer scenario and here are some observations…

Content Source as Crawled Property

The “Content Source” name is out of the box available as Managed Property on all content in the search index

This makes it possible to create Result Sources that aggregate content from different Content Sources similar to Search Scopes back in the old days.

SharePoint 2013 Search Query Tool #1

Meta elements (HTML <meta> tags) as Crawled Properties

Information from meta elements in web pages is extracted into crawled properties

Consider the following example:

Simple website with meta tags

After crawling this website with SharePoint 2013 Search it will create (if new) or use (if existing) a Crawled Property and store the content from the meta element. The Crawled Property can then be mapped to Managed Properties to return, filter or sort query results.

SharePoint 2013 Search Query Tool #2

Query string parameters as Crawled Properties

Query string parameters are not extracted into Crawled Properties

This was actually a request from the customer in order to be able to provide additional information regarding documents (on their website) into the search index. As I suspected it isn’t possible out of the box but you could definitely do it using Content Enrichment.

The “OriginalPath” is available as an input property for Content Enrichment and contains the exact url used for indexing the document:

Content Enrichment Input Properties

With Content Enrichment it is pretty straightforward to look for predefined query string parameters and then map them to output properties.

$ssa = Get-SPEnterpriseSearchServiceApplication $config = New-SPEnterpriseSearchContentEnrichmentConfiguration $config.Endpoint = 'http://cews:818/ContentEnrichmentService2.svc' $config.InputProperties = 'OriginalPath', 'ContentSource' $config.OutputProperties = 'MyParam1', 'MyParam2' $config.DebugMode = $false $config.SendRawData = $false Set-SPEnterpriseSearchContentEnrichmentConfiguration –SearchApplication $ssa –ContentEnrichmentConfiguration $config

More information on Content Enrichment from my SharePoint Saturday presentation:


SharePoint: Portal navigation limited to 50 dynamic items

August 12, 2015 - 11:07, by Steven Van de Craen - 0 Comments

I was looking into an issue where the Navigation Settings page wouldn’t show all subsites in the treeview. When reproducing it was limited to 50 dynamic items.

Navigation Settings

The treeview component is a Microsoft.SharePoint.Publishing.Internal.WebControls.HierarchicalListBox which connects to the active Microsoft.SharePoint.Publishing.Navigation.PortalSiteMapProvider. This has a property “DynamicChildLimit” that can be explicitly configured in the web.config.

// Microsoft.SharePoint.Publishing.Navigation.PortalSiteMapProvider public int DynamicChildLimit { get { int? num = this.dynamicChildLimit; if (num.HasValue) { return num.GetValueOrDefault(); } if (this.Version < 14) { return 50; } return 0; } set { this.dynamicChildLimit = new int?(value); } }

The active provider used is “GlobalNavSiteMapProvider”, defined in web.config as

<add name="GlobalNavSiteMapProvider" description="CMS provider for Global navigation" type="Microsoft.SharePoint.Publishing.Navigation.PortalSiteMapProvider, Microsoft.SharePoint.Publishing, Version=, Culture=neutral, PublicKeyToken=71e9bce111e9429c" NavigationType="Global" EncodeOutput="true" />

I tried specifying Version=”14” but then it defaulted to 20 items, a path I didn’t further investigate. So I just explicitly specified the DynamicChildLimit=”100” and that fixed the issue.

<add name="GlobalNavSiteMapProvider" description="CMS provider for Global navigation" type="Microsoft.SharePoint.Publishing.Navigation.PortalSiteMapProvider, Microsoft.SharePoint.Publishing, Version=, Culture=neutral, PublicKeyToken=71e9bce111e9429c" NavigationType="Global" EncodeOutput="true" DynamicChildLimit="100" />

SharePoint: Users cannot create new subsites

July 13, 2015 - 17:02, by Steven Van de Craen - 0 Comments


First day after my vacation and I got presented with a nice situation at one of our clients. Most users trying to create new subsites would get “Sorry, this site hasn’t been shared with you” and the site would NOT get created. Troubleshooting this showed that during site provisioning the “SiteFeed” Feature would throw an exception which would roll back the site creation. The relevant lines in the ULS logs pointed towards the “Following” (Social) of the newly created site:

FollowedContent.FollowItem:Exception:Microsoft.Office.Server.UserProfiles.FollowedContentException: ItemDoesNotExist : Item does not exist.     at Microsoft.Office.Server.UserProfiles.SPS2SAppUtility.GetPersonalUrl(UserProfile& profile)     at Microsoft.Office.Server.UserProfiles.SPS2SAppExecutionContext.InitializeForProfile()     at Microsoft.Office.Server.UserProfiles.SPS2SAppExecutionContext.EnsureInitialized()     at Microsoft.Office.Server.UserProfiles.FollowedContent.FollowItem(FollowedItem item, Boolean isInternal)

Could not follow the url https://sharepoint/newsub

Leaving Monitored Scope (Event Receiver (Microsoft.Office.Server.UserProfiles, Version=, Culture=neutral, PublicKeyToken=71e9bce111e9429c, Microsoft.Office.Server.UserProfiles.ContentFollowingWebEventReceiver)).


The newly created site could not be added to the user’s Social list on his MySite due to an Access Denied on adding the item to the list.


The MySites were recently migrated from SharePoint 2010 (classic mode) to SharePoint 2013 (claims mode). MySites work by setting the ‘owner’ as Primary Site Collection Administrator, but the conversion to claims had erased all the classic-mode Site Collection Administrators from the migrated site collections. Querying for the Site Collection Administrators would just return empty which is of course not good.

(Blank) Site Collection Administrators


I whipped up a PowerShell script that would loop all MySites and report any sites with missing or non-matching Site Collection Administrator. Toggling the ‘report only’ flag in the script will correct the situation.

asnp Microsoft.SharePoint.PowerShell -ea 0 | Out-Null cls $reportOnly = $false Write-Host "ReportOnly:" $reportOnly $mySites = Get-SPSite -Limit ALL | ? { $_.RootWeb.WebTemplate -eq "SPSPERS" } Write-Host "Found" ($mySites.Count) "MySites" $mySites | % { $s = $_ $w = $s.RootWeb $owner = $w.EnsureUser($w.Title) $primaryAdmin = $w.SiteAdministrators | Select -First 1 if ($primaryAdmin -eq $null) { Write-Host -ForegroundColor Red ($s.ServerRelativeUrl) ": no primary SC admin. Owner should be" $owner if ($reportOnly -eq $false) { $owner.IsSiteAdmin = $true $owner.Update() } } elseif ($owner.IsSiteAdmin -eq $false) { Write-Host -ForegroundColor Yellow ($s.ServerRelativeUrl) ": primary SC admin (" $primaryAdmin ") does NOT match owner (" $owner ")" if ($reportOnly -eq $false) { $owner.IsSiteAdmin = $true $owner.Update() } } else { Write-Host -ForegroundColor Green ($s.ServerRelativeUrl) ": primary SC admin (" $primaryAdmin ") matches owner (" $owner ")" } $s.Close() }

After correcting all sites should turn up green.

 All MySites corrected


SharePoint 2013: Open PDF files in client application

June 26, 2015 - 16:23, by Steven Van de Craen - 0 Comments

SharePoint 2013 has this quirk going for quite some time where clicking on a PDF file opens it in the browser no matter what you configure in the list settings or client application. One of our customers migrated to SharePoint 2013 and suddenly they lost this functionality. Together with my colleague Elio Struyf we proposed a small customization that would add the “Open in client” option to the fly out menu for PDF documents.

Open in client in fly out menu

The customization itself is devised as a SharePoint Sandboxed Solution that can be installed and activated per Site Collection on either an on-premises environment or Office 365.

Activate (Sandboxed) Solution

The functionality can be enabled or disabled via the corresponding Site Collection Feature.

Site Collection Features

The customisation can be found on GitHub: Ventigrate/SharePoint_PDFOpenInClient

SharePoint 2013: Enable 'Change Item Order' Ribbon Action

June 4, 2015 - 17:00, by Steven Van de Craen - 0 Comments

My customer reported an issue where a ‘Links’ List didn’t have the option ‘Change Item Order’ enabled. This was for a list created in SharePoint 2007 and migrated to SharePoint 2013.

When creating a new Links List in SharePoint 2013 it would have this enabled, so it wasn’t related to Site or Site Collection Features. Creating new views in the migrated list showed the same ‘issue’.


With PowerShell it quickly becomes obvious that the View didn’t have the ‘Orderable’ flag set. It is not possible to change this through SPView.OrderedView because it is read-only, however you can set this ‘property’ on the XsltListViewWebPart that’s on the View Form as follows:

asnp Microsoft.SharePoint.PowerShell -ea 0 | Out-Null cls # Get the View page $w = get-spweb http://sharepoint/site/site $f = $w.GetFile("http://sharepoint/site/site/Lists/Links/AllItems.aspx") Write-Host "STARTING" $f.ServerRelativeUrl if ($f.Exists) { $man = $f.GetLimitedWebPartManager('Shared') $wp = $man.WebParts | ? { $_ -is [Microsoft.SharePoint.WebPartPages.XsltListViewWebPart] } | Select -First 1 if ($wp -ne $null) { # Make the view 'Ordered' by expanding the ViewFlags enum $wp.ViewFlags = [Microsoft.SharePoint.SPViewFlags]($wp.ViewFlags.ToString() + ', Ordered') $man.SaveChanges($wp) } else { Write-Host "Web Part not found on page" } $man.Dispose() } else { Write-Host "Page not found" } Write-Host "DONE"

Afterwards users will be able to set the order of the items…


When you create new Views either base them on an existing (‘fixed’ View) or run the above script on them to enable the functionality.

Moving site collections from explicit managed path to wildcard managed path

March 14, 2015 - 07:41, by Steven Van de Craen - 1 Comments

At my current project where we’re upgrading from SharePoint 2007 to SharePoint 2013 we’re running into a high number of managed paths on a Web Application. The recommended limit according to TechNet is 20 but they’re well above that with around 70 managed paths. An internal study showed that a lot of them were Explicit Managed Paths where there was no real requirement to have it that way and they could easily be transformed into a (single) Wildcard Managed Path.

Explicit Managed Path Wildcard Managed Path


It turns out that it is a rather painless operation to do:

  1. Unmount the Content Database with the Site Collection on the Explicit Managed Path
  2. Delete the Explicit Managed Path (ensure that a corresponding Wildcard Managed Path exists)
  3. Mount the Content Database with the Site Collection and it will make use of the Wildcard Managed Path

With this in mind the following PowerShell script automated this. It doesn’t ensure the Wildcard Managed Path since I wanted to control if the Explicit Managed Path should be transformed or not. In this case it will log a warning and skip that one.

### Script will loop explicit managed paths and restructure so the site collections are inside a wildcard managed path in order to reduce # (explicit) managed paths cls asnp Microsoft.SharePoint.PowerShell -ea 0 | Out-Null $logFile = "C:\temp\managedpath_restructure.txt" $trial = $false $waUrl = "http://intranet" $emps = Get-SPManagedPath -WebApplication $waUrl | ? { ($_.Type -eq "ExplicitInclusion") -and ($_.Name -like "*/*") } $emps | % { $emp = $_ $wmpName = $emp.Name.Split("/")[0] $wmp = Get-SPManagedPath -WebApplication $waUrl | ? { ($_.Type -eq "WildcardInclusion") -and ($_.Name -eq $wmpName) } if ($wmp -eq $null) { # SKIP $log = [string]::Format("{0} - {1} - No wildcard MP '{2}'. Skipping.", (Get-Date), $emp.Name, $wmpName) Write-Host -ForegroundColor Yellow $log $log >> $logFile } else { # RESTRUCTURE $log = [string]::Format("{0} - {1} - Restructuring explict MP to wildcard MP '{2}'.", (Get-Date), $emp.Name, $wmpName) Write-Host -ForegroundColor Green $log $log >> $logFile # Get matching sites' content database $cdbs = @() Get-SPWebApplication $waUrl | Get-SPSite -Limit ALL | ? { $_.Url -like ("*/" + $emp.Name) } | % { $s = $_ $cdb = $s.ContentDatabase if (-not($cdbs.Contains($cdb))) { $cdbs += $cdb } $s.Close() } # Dismount content databases $cdbs | % { $cdb = $_ $log = [string]::Format("{0} - {1} - Dismounting content database '{2}'.", (Get-Date), $emp.Name, ($cdb.Name + " @ " + $cdb.Server)) Write-Host -ForegroundColor Green $log $log >> $logFile if (-not($trial)) { Dismount-SPContentDatabase $cdb -Confirm:0 } } # Remove explicit managed patch $log = [string]::Format("{0} - {1} - Removing explict MP.", (Get-Date), $emp.Name, $wmpName) Write-Host -ForegroundColor Green $log $log >> $logFile if (-not($trial)) { Remove-SPManagedPath $emp -WebApplication $waUrl -Confirm:0 } # Mount content databases $log = [string]::Format("{0} - {1} - Mounting content database '{2}'.", (Get-Date), $emp.Name, ($cdb.Name + ' @ ' + $cdb.Server)) Write-Host -ForegroundColor Green $log $log >> $logFile if (-not($trial)) { $db = Mount-SPContentDatabase ($cdb.Name) -DatabaseServer ($cdb.Server) -WebApplication $waUrl -Confirm:0 } } } Write-Host "DONE"


 Next >>