Dealing with orphaned user solutions

I’m surprised this problem isn’t more common. It seems easy enough to trigger by accident, and fixing it was a puzzle.

No doubt most of us have at some point in using SharePoint 2010 created a site template, and then after gazing upon it in the Solution Gallery, determined that we’ve named it wrong, need to change one small thing, or any number of different issues. Normally, the correct thing to do in this circumstance is to deactivate and then delete the solution.

What if you don’t deactivate it?

Create a site.
Save it as a template to the Solution Gallery.
Download the WSP to your desktop.
Delete the solution from the Solution Gallery *without* deactivating it. To do this, click the Edit button and then click Delete from there.
Upload the WSP back to the Solution Gallery.

You’ll find that you’re not able to activate the WSP you just uploaded, or deactivate it. And now you’re just kinda stuck with a site template that’s visible when you try to create a new site, but nothing that can be done about it!

So, first off, user solution WSPs still contain features. We *can* deactivate the feature that installs this site template (via PowerShell).

1
2
3
$site = Get-SPSite http://my.site.com
$site.Features | Where-Object {$_.FeatureDefinitionScope -eq "Site"}
Disable-SPFeature $feature -url http://my.site.com

But that’s only hiding the problem, it’s not actually fixing it. So, we should try to identify the user solution and remove it instead.

1
Uninstall-SPUserSolution -Identity "BasicProjectSite.wsp" -Site http://my.site.com

But this tells me that there is no solution with that name. But when I list $site.Solutions, it’s there. Even running Get-SPUserSolution lists 0 solutions. What to do? Wait, does the object model still work?

1
2
3
4
5
6
Name                           SolutionId                           Status
----                           ----------                           ------
BasicProjectSite.wsp           af9fc924-26b1-4c4f-9250-57b26c81316f Activated
 
$solution = $site.Solutions[[guid]"af9fc924-26b1-4c4f-9250-57b26c81316f"]
$site.Solutions.Remove($solution)

And it’s finally gone!

Disable Mobile Acces for Sharepoint

If you have access to the SharePoint file system on your front-end servers, you can disable the mobile
view for all sites in a specific web application’s zone by adding the following in the zone’s web.config
file, inside the <system.web> section:
<browserCaps>
<result type=”System.Web.Mobile.MobileCapabilities, System.Web.Mobile, Version=4.0.0
.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a” />
<filter>isMobileDevice=false</filter>
</browserCaps>

People Picker to add users to SharePoint 2010 – Namespace prefix ‘xsd’ is not defined

Recently I’ve encountered multiple issues at different client sites that all led back to SharePoint / Internet Explorer compatibility problems. On two entirely separate farms, SharePoint 2010 was generating a correlation error when someone attempted to select a user from the People Picker:

System.InvalidOperationException: Namespace prefix ‘xsd’ is not defined. At System.Xml.Serialization.XmlSerializationReader.ToXmlQualifiedName(String value, Boolean decodeName) at Microsoft.Xml.Serialization.GeneratedAssembly.XmlSerializationReaderDictionaryEntryArray.Read1_Object(Boolean isNullable, Boolean checkType) at Microsoft.Xml.Serialization.GeneratedAssembly.XmlSerializationReaderDictionaryEntryArray.Read2_DictionaryEntry(Boolean checkType) at Microsoft.Xml.Serialization.GeneratedAssembly.XmlSerializationReaderDictioaryEntryArray.Read3_ArrayOfDictionaryEntry()

Additionally, a number of weird, unexplainable problems were occurring. These ended up disappearing when users changed the browser mode from IE9/IE10 to IE8 in F12 developer tools. Obviously, then, the source of the problem lay in some sort of compatibility issue between SharePoint and Internet Explorer 9 and/or Internet Explorer 10.

To fix browser incompatibility problems, I found a number of people on forums and blog posts recommending the use of the “X-UA-Compatible” declaration inside a meta tag placed inside the head. For example:

<meta http-equiv=”x-ua-compatible” content=”IE=8″ >

As best effort and how the problem is in the pickerdialog.master and the People Picker is using the pickerdialog.master file, you need to add the following line in the head element.

meta http-equiv="X-UA-Compatible" content="IE=EmulateIE8"  

Find the pickerdialog.master file in C:Program FilesCommon FilesMicrosoft SharedWeb Server Extensions14TEMPLATELAYOUTS and make a backup.
Now open it and insert the line at the start of the head element.

<head>
<meta name="GENERATOR" content="Microsoft SharePoint" />
<meta http-equiv="X-UA-Compatible" content="IE=EmulateIE8" />
....
</head>

Followed by iisreset this should solve the problem in People Picker

Setting the Super User account

By default after installing SharePoint 2010/2013 you will probably soon encounter the following two error messages in the Application log:

Object Cache: The super user account utilized by the cache is not configured. This can increase the number of cache misses, which causes the page requests to consume unneccesary system resources.
To configure the account use the following command ‘stsadm -o setproperty -propertyname portalsuperuseraccount -propertyvalue account -url webappurl’. The account should be any account that has Full Control access to the SharePoint databases but is not an application pool account.
Additional Data:
Current default super user account: SHAREPOINTsystem

Object Cache: The super reader account utilized by the cache does not have sufficient permissions to SharePoint databases.
To configure the account use the following command ‘stsadm -o setproperty -propertyname portalsuperreaderaccount -propertyvalue account -url webappurl’. It should be configured to be an account that has Read access to the SharePoint databases.
Additional Data:
Current default super reader account: NT AUTHORITYLOCAL SERVICE

Source of the error is as the Technet documentation says:

By default, the Portal Super User account is the site’s System Account, and the Portal Super Reader account is NT AuthorityLocal Service. There are two main issues with using the out-of-box accounts.

  1. The first issue is that some items get checked out to System Account, so when a query that includes these items is made, the checked out version of the item is returned instead of the latest published version. This is a problem because it is not what a user would expect to have returned, so the cache has to make a second query to fetch the correct version of the file. This negatively affects server performance for every request that includes these items. The same problem would occur for any user who has items checked out, if that user’s account was set to be the Portal Super User account. This is why the accounts configured to be the Portal Super User and the Portal Super Reader should not be user accounts that are used to log into the site. This ensures that the user does not inadvertently check items out and cause problems with performance.
  2. The default Portal Super Reader account is NT AuthorityLocal Service, which is not correctly resolved in a claims authentication application. As a result, if the Portal Super Reader account is not explicitly configured for a claims authentication application, browsing to site collections under this application will result in an “Access Denied” error, even for the site administrator. This error will occur on any site that uses any feature that explicitly uses the object cache, such as the SharePoint Server Publishing Infrastructure, metadata navigation, the Content Query Web Part, or navigation.

So keeping these values on their default value on an intranet/extranet portal is not such a good idea. Let’s go ahead and set these two, according to the suggestions in the error message!

stsadm -o setproperty -pn portalsuperuseraccount -pv DOMAINuser -url http://webappurl
stsadm -o setproperty -pn portalsuperreaderaccount -pv DOMAINuser -url http://webappurl
iisreset

After doing so, you’re either done, or – in case you are in claims mode – will see Access Denied on all pages on the webapplication you set the accounts.

Moral of the story: if you are in claims mode, you will need to use the claims user name (i:0#.w|domainuser).

Relevant sections of the Technet article:

14. Make note of how the names for the Object Cache Super Reader and Object Cache Super User accounts are displayed in the User Name column. The displayed strings will be different depending on whether you are using claims authentication for the Web application.

Copy the following code and paste it into a text editor, such as Notepad:

  1. $wa = Get-SPWebApplication -Identity "<WebApplication>" 
    $wa.Properties["portalsuperuseraccount"] = "<SuperUser>" 
    $wa.Properties["portalsuperreaderaccount"] = "<SuperReader>" 
    $wa.Update()
  2. Replace the following placeholders with values:
    • <WebApplication> is the name of the Web application to which the accounts will be added.
    • <SuperUser> is the account to use for the Portal Super User account as you saw it displayed in the User Column field mentioned in Step 14 of the previous procedure.
    • <SuperReader> is account to use for the Portal Super Reader account as you saw it displayed in the User Column field mentioned in Step 14 of the previous procedure.

Restore a deleted Site Collection in SharePoint

Today I will post about a problem that happen in one of our development farms. My colleagues sent me emails about the can’t Access to a site collection, and I was very surprised when I accessed to Central Administration and saw that the ste collection has been dissapeared.

So, If you have deleted a site collection and you want it back again it really is quite straight forward. It’s the same process for both SharePoint 2010 and 2013.

In case, you are using Office 365 then it’s all through the admin interface for SharePoint. Under the section where you manage your site collections there is a recycle bin icon on the ribbon, just go in there and restore!

If you have SharePoint on-site fire up PowerShell on the server (make sure it’s either the Management shell or you have the SharePoint modules loaded)

Then run the following:

Get-SPDeletedSite

This will list all the deleted site collections, only you have to localize the SC that has been deleted and copy the ID (SiteID) which is is necessary for the following Powershell command

Restore-SPDeletedSite –Identity <siteId>

It will ask if you sure, so just say yes.

There is no output to say “success” but if you browse to your site it will now exist again!

HTH!

How To Create the UPA from Powershell

Creating the User Profile Service Application (UPA) via Powershell is a fairly straightforward process. We only have to follow these steps:

  1. Set Parameters
  2. Create the Service Application
  3. Create the Service Application Proxy and associate it to the Proxy Group
  1. Set Parameters: First of all we have to set the parameters we will use for the service application.
  • Name for your User Profile Service Application
  • $UPAName = “70331_UserProfile”
  • Application Pool: You can create a specific one or use an existing one. I recommend to use the same Application Pool for all service applications. In my case, I am assigning the existing application pool called “ServiceApplications” to the $appPool variable:
  • $AppPool = Get-SPServiceApplicationPool –Identity “ServiceApplications”
  • Database Names: UPA uses three distinct databases: Profile, Social and Profile. Try to follow the convention rule you have for your farm databases. $SocialDB = “70331_UserProfile_SocialDB”
  • $SyncDB = “70331_UserProfile_SyncDB”
  • $ProfileDB = “70331_UserProfile_ProfileDB”
  • Proxy Name: Type a name for the Proxy/connection of the UPA
  • $UPAProxy = “70331_UPA_Proxy”
  1. Create the Service Application: Use the New-SPProfileServiceApplication cmdlet for this purpose and use the recently created parameters and collect the result in the $UPA variable so as to use it later in the Proxy creation.

$UPA=New-SPProfileServiceApplication -Name $UPAName -ApplicationPool $appPool -ProfileDBName $ProfileDB -SocialDBName $SocialDB -ProfileSyncDBName $SyncDB

  1. Create the Service Application Proxy: Use the New-SPProfileServiceApplicationProxy cmdlet and the parameters configured above. Use the option DefaultProxyGroup if you want to include the proxy into the default group.

New-SPProfileServiceApplicationProxy -Name $UPAProxy -ServiceApplication $UPA –DefaultProxyGroup

  1. If you did not associate the user profile proxy to the default proxy group and you want to associate it to a custom one, do the following:

#Get the list of Proxy Groups and copy the Friendly Name of the Proxy group you need.

Get-SPServiceApplicationProxyGroup

$proxyGroup=Get-SPServiceApplicationProxyGroup -Identity “Intranet Only”

#Get the list of proxies/connections, copy the typename of the UPA proxy and use it for assigning it to the $proxy variable

$proxy=Get-SPServiceApplicationProxy | ? {$_.TypeName -eq “User Profile Service Application Proxy”}

#Use the Add-SPServiceApplicationProxyGroupMember cmdlet to add the UPA proxy to your custom ProxyGroup

Add-SPServiceApplicationProxyGroupMember -Identity $proxygroup -Member $Proxy

That´s all, hope it helps!

Merging multiple CSV Files with Powershell

Powershell is a great tool for managing CSV files, specially with the cmdlets Export-Csv and Import-Csv. Let´s use it to merge multiples several CSV files. The process is:

  • Get the list of CSV files
  • Import the content of every CSV file into the same variable
  • Export the content of the variable to a final CSV file

GET THE LIST OF CSV FILES

First we get the list of CSV files, which are located in a folder using the Get-ChildItem cmdlet:

$csvfiles=Get-ChildItem -Path C:CSVFiles*

If there are other files with other extensions we can use wildcards like this:

$csvfiles=Get-ChildItem -Path C:CSVFiles* -Include *.csv

Or, if there are more CSV files than you are intested on you can still use wildcards to filter by title for example:

$csvfiles=Get-ChildItem -Path C:CSVFiles* -Include *<word_of_interest>*.csv

IMPORT THE CONTENT TO POWERSHELL

Once we got the list of CSV files to merge, we process each file importing the content of each file to a $content variable

foreach ($file in $csvfiles) {

$content += Import-Csv -Path $file;

}

EXPORT THE CONTENT

Last step is export the content of the $content variable to a CSV file using the Export-Csv cmdlet

$content | Export-Csv -Path C:CSVFilesMerged.csv

And that’s all…

Note: this method is very simple but we need to have the same structure in the CSV files (same columns), since the declaration of columns is found in the first line of a CSV.

Hope it helps!