Saturday, May 16, 2015

SharePoint 2013: Cannot Filter Task List after March 2015 CU

Print this posting
Problem

You have a SharePoint 2013 farm patched through the March 2015 CU.  You have a list of type Tasks.  You add a List web part to a page pointing to this task list.  You attempt to edit the web part's default view in order to configure a simple column filter (for example, setting Task Status not equal to "Completed").  This doesn't work.  You try to configure a different column filter, but this doesn't work either.  You then go to the list itself and configure a custom view with a simple column filter.  This also doesn't work.  Through further testing, you discover that you cannot get any column filter to work on this Task list.  You were able to configure column filters without issue prior to installing the March 2015 CU.

The problem results from a bug introduced by the March 2015 CU.  It is resolved by the May 2015 CU.  There are two simple workarounds you can implement if you do not install the May 2015 CU.

Solution
  • Install the May 2015 CU.
  • Enable the Server Render property of the web part - find it in the Miscellaneous property group.
  • Change the View Style property of the Task list to any other style except Default.
References
Notes
  • Though I couldn't find any explicit reference to this bug fix in the May 2015 SharePoint updates (maybe I missed it?), Stefan Grossner confirmed that it was resolved in this CU.
  • Changing the View Style of a task list view impacts the functionality made available.  For example, the quick links to different views and the Find an item list search box no longer appear.

Tuesday, May 12, 2015

Active Directory 2012 Tip: how to import users in bulk from a CSV

Here's a sample PowerShell script for importing users in bulk into Active Directory (AD).  It configures these AD fields:
  • SamAccountName
  • UserPrincipalName
  • GivenName
  • Initials
  • Surname
  • DisplayName
  • Name
  • Description
  • Company
  • StreetAddress
  • City
  • State
  • PostalCode
  • OfficePhone
  • Fax
  • EmailAddress
  • AccountPassword
  • ChangePasswordAtLogon
  • PasswordNeverExpires
  • Enabled
  • PassThru
And then here's the script that I use to perform the import:
import-csv c:\temp\100.csv | foreach-object {New-ADUser -SamAccountName $_.SAMAccountName -UserPrincipalName $_.SAMAccountName -GivenName $_.givenName -Initials $_.Initials -Surname $_.Surname -DisplayName $_.DisplayName -Name ($_.givenName + $_.Initials + $_.Surname) -Description $_.Description -Company $_.Company -StreetAddress $_.StreetAddress -City $_.City -State $_.State -PostalCode $_.PostalCode -OfficePhone $_.OfficePhone -Fax $_.Fax -EmailAddress $_.EmailAddress -AccountPassword (ConvertTo-SecureString "P@ssw0rd" -AsPlainText -Force) -ChangePasswordAtLogon $False -PasswordNeverExpires $True -Enabled $True -PassThru -WhatIf}
References
Notes

SharePoint 2013 Tip: how get list of site collection URLs and their lengths

Use this SQL script below.  In SSMS, right-click on the database name the site collection resides in, choose New Query, and then just paste and execute the script.
SELECT CONCAT([DirName], N'/', [LeafName]) AS [FullRelativePath], LEN(CONCAT([DirName], N'/', [LeafName])) AS [Length] FROM [dbo].[AllDocs] ORDER BY [Length] DESC
References
Notes

Saturday, May 9, 2015

SharePoint 2013: This content database has a schema version which is not supported in this farm.

Problem

You are attempting to migrate a content database from one farm to another.  You restore the content database in SQL Server and then attempt to mount the database to a web application on the destination farm.  When you execute Mount-SPContentDatabase, you see the following error appear in the shell:
Mount-SPContentDatabase :  This content database has a schema version which is not supported in this farm.
Checking ULS logs, you see messages like these:
Database '[content database]' on SQL Server instance '[name]' is not empty and does not match current database schema.
You then check the patch status on the destination farm, 15.0.4420.1017, and compare it with the patch status on the source farm, 15.0.4701.1001.

Solution
  • Upgrade the destination farm to at least the same patch level as the source farm.
References

Notes
  • In this case, the issue had nothing to do with permissions.
  • A similar issue occurs if you attempt to perform Restore-SPSite on the destination site in the destination farm, after using Backup-SPSite on the source farm.  If you attempt to restore a back up from a source site with a higher patch number than the destination site, you'll see this error:
    Restore-SPSite : <nativehr>0x80070003</nativehr><nativestack></nativestack>
    At line:1 char:1
    + Restore-SPSite "[URL of destination site]" -Path "[to backup file]"...
    + CategoryInfo          : InvalidData: (Microsoft.Share...dletRestoreSite:SPCmdletRestoreSite) [Restore-SPSite], D
    rectoryNotFoundException
    + FullyQualifiedErrorId : Microsoft.SharePoint.PowerShell.SPCmdletRestoreSite
    which is unhelpful and even misleading; and then in the ULS log, you'll see something like this:
    Could not deserialize site from [path to backup file] . Microsoft.SharePoint.SPException: Schema version of backup 15.0.4711.1000 does not match current schema version 15.0.4420.1017     at Microsoft.SharePoint.SPSite.Restore(String filename, Boolean isADMode, Boolean& readOnlyMode, Boolean& hadWriteLock)
    Review this error message, the problem is immediately apparent.  The source farm in this case (different than the one discussed in the posting) is patched through April 2015 CU, while the destination farm is patched through March 2015 CU.  Again, its a situation of restoring a higher version backup to a lower version farm, and again the solution is simple: upgrade the destination farm to at least the same level as the source farm.

Saturday, May 2, 2015

SharePoint 2013: Application pools recycle when memory limits are exceeded

Problem

After deploying a new SharePoint 2013 farm having three tiers (data, app, web), you stop the SharePoint Foundation Web Application service on the application server(s), since the content web applications are no longer needed on these machines.  A day or so later, you see the following in your farm's Problems and Solutions report:

TitleApplication pools recycle when memory limits are exceeded.
Severity0 - Rule Execution Failure
CategoryPerformance
ExplanationThe system cannot find the path specified.
RemedyIn the Internet Information Services Manager, uncheck any memory-based maximums set for the application pools named above. For more information about this rule, see [URL]
Failing Servers[Application Server]
Failing ServicesSPWebService (WSS_Administration)
Rule SettingsView

and

TitleApplication pools recycle when memory limits are exceeded.
Severity2 - Warning
CategoryPerformance
ExplanationThe application pools named  are configured to recycle when memory limits are exceeded.  Recycling based on memory limits is not usually necessary in a 64-bit environment and should be disabled.  Unnecessary recycling can result in dropped requests from the recycled worker process and slow performance for end users making requests to the new worker process.  If the working set of your worker process grows without bound, analyze the set of applications and components that run in the process to determine whether one of them is leaking memory..
RemedyIn the Internet Information Services Manager, uncheck any memory-based maximums set for the application pools named above. For more information about this rule, see [URL].
Failing Servers[Application Server]
Failing ServicesSPWebService
Rule SettingsView

The solution to this problem is simple, but does involve some tedious administrative steps. Basically, you need to change the web application's application pool to something different, and then remove the original application pool.

Solution
  1. Create new application pool and assign to web application
    1. Draft a name for the new application pool and determine the service account you want to run it on.  This service account should be the same one being used for the existing application pool (eg, spApp).
    2. Log into a SharePoint 2013 server using the SharePoint Setup User Administrator account (eg, spAdmin). This is the same account that you (should have) used to perform the initial farm installation and configuration.
      This is important in that the changes you will be making will be to the farm configuration database; and, by default, only this account has the privileges necessary to make such changes.
    3. Launch an elevated SharePoint Management shell.
    4. Execute the following commands, making appropriate revisions:
      $WebAppURL = "[Your site URL]" $NewAppPoolName = "[Name Of New App Pool]" $NewAppPoolIdentity = "[Identity Of New App Pool]" $Password = Read-Host -Prompt "Enter the service account password: " -AsSecureString $Service = [Microsoft.SharePoint.Administration.SPWebService]::ContentService $NewAppPool = New-Object Microsoft.SharePoint.Administration.SPApplicationPool($NewAppPoolName,$Service) $NewAppPool.CurrentIdentityType = "SpecificUser" $NewAppPool.Username = $NewAppPoolUserName $NewAppPool.SetPassword($Password) $NewAppPool.Provision() $NewAppPool.Update($true) $NewAppPool.Deploy()
      The new application pool will be set immediately.
  2. Identify the application pool to remove
    1. Using the same shell used previously, execute the following command:
      ([Microsoft.SharePoint.Administration.SPWebService]::ContentService).ApplicationPools | Sort-Object Name | Select-Object Name, ID, UserName, Status, parent | Format-Table -Auto
  3. Remove old application pool
    1. Execute the following commands, making appropriate revisions:
    2. Now, using the same management shell, execute the following command to remove the web application pool.
      $apppool = [Microsoft.SharePoint.Administration.SPWebService]::ContentService.ApplicationPools | where {$_.Name -eq "[Name of old web application pool]"} $apppool.UnProvisionGlobally()
References
  • When I originally began building the farm, the first server I built was an application server, and on this server I also deployed the primary content web application, which runs on the SharePoint Foundation Web Application service.  Once the application server was fully built out and configured, I then deployed two web front end servers.  As a part of standing up the web front end servers, the content web applications were automatically instantiated and deployed to them: I did not have to do this intentionally.  I then configured the two WFEs in a network load balanced configuration using Windows 2012 NLB.  At the end of the day, the content web applications were instantiated and running on three servers: the application server and the two WFEs.  Thus, at that time, if you looked into IIS on each of these servers, you would see the content web applications and their associated application pools running on each server.  But because the web application's domain name was associated only with the NLB IP address, when users connected to the web application, they would only connect to the web application running on one of the two WFEs and never to the instance also running on the application server, even though it too was up and running and available.

    So long as this happy state of affairs was unchanged, the rule would: 1) execute against each server, 2) find that each web application pool was associated with a running instance of a web application, and then 3) successfully complete without issue.  However, when I finally got around to stopping the SharePoint Foundation Web Application service on the application server since it was no longer serving any useful purpose, this state of affairs changed, and the rule failed when it ran against the application server.

    The rule makes no distinction as to which server the rule failed on.  You can see this when you view the rule properties: the Scope can be set to All Servers or Any Server, but not to an individual server.  The rule, if it fails, does not identify which server or servers it failed on; only that a failure in fact occurred.

  • The application pool object method UnprovisionGlobally removes all instances of the application pool from all IIS instances on the farm.  On the other hand, when you add an application pool, per the steps above, you only add the application pool to those IIS instances running the content web application.
Extras
  • Command to view all IIS application pools:
    [void] [System.Reflection.Assembly]::LoadWithPartialName("Microsoft.Web.Administration") (New-Object Microsoft.Web.Administration.ServerManager).applicationpools | sort-object name | ft name
  • Command to remove an IIS application pool: Remove-WebAppPool.