Monday, May 14, 2018

SharePoint TIP: quickly and recoverably remove sites in bulk using a single line of PowerShell

To quickly and recoverably remove sites in bulk, using piping.  For example, if a content database has hundreds of MySite sites that you do not want to upgrade, you can quickly remove them from the content database(s) like so:
Get-SPSite -WebApplication "[webappurl]" -LimitAll | Where-Object {$_.URL -Like "*MySites*"} | Remove-SPSite -GradualDelete -Confirm:$False
That's it. Execute this in an elevated SharePoint Management Shell (SMS). The -GradualDelete parameter moves the deleted sites into the SPDeletedSite collection in the content database, and the -Confirm:$False parameter ensures that you are not prompted hundreds of times for each site to be removed.

References

  • I use this when testing content databases to be migrated.  After making a copy of the production version backup, I sometimes need to remove legacy sites and want to do this in bulk, such as removing old MySite sites.  You can even do this in parts by filtering for MySite sites starting with "a", or "b", etc, like "*MySites/a* or "*MySites/b*".  I then do a quick check by interrogating the SPDeletedSites collection to ensure that what I expected to delete was in fact deleted.

Monday, May 7, 2018

SharePoint 2013: Add-SPSolution : The solution cannot be deployed.

Problem

You are a new admin engaged in upgrade testing of a customer SharePoint 2010 farm to SharePoint 2016.  You have mounted a copy of the production SharePoint 2010 content database to the development 2013 farm and reviewed the upgrade report.  No upgrading blocking issues were found, but there are many warnings involving third party solutions.  One third party solution, let's call it TPS1, is your focus in this test. Reviewing the installed farm solutions in Central Administration on the development farm, you find that a version of TPS1 was uploaded but unsuccessfully deployed to any web applications in the development farm.  You want to remove all traces of the solution so that you can start fresh.

The upgrade path you are engaging is like so:
SharePoint 2010 Farm   >   SharePoint 2013 Farm   >   SharePoint 2016 Farm
Content DB   >   Content DB   >    Content DB
TPS1 (2010)   >   TPS1 (2010) > TPS1 (2013)   >   TPS1 (2013) > TPS1 (2016)

You need to install the 2010 version of TPS1 to the 2013 farm so that when you perform the mount of the 2010 content database, any features and web parts deployed in the 2010 content database will sync with the solution and not generate any upgrade warnings.  Once the 2010 content database is mounted successfully to the 2013 farm, you intend to upgrade the solution prior to mounting the upgraded 2010 content database to the development 2016 farm.

Since it didn't seem to ever have been actually deployed, you simply perform a remove of solution using:
Remove-SPSolution -Identity "TPS1.wsp"
and it is unloaded without issue. You then download the latest build of the SharePoint 2010 version of TPS1.wsp, and then attempt to add it by executing:
Add-SPSolution -LiteralPath "D:\Temp\TPSA1.wsp"
You then see the following error message presented in the shell:
Add-SPSolution : The solution cannot be deployed.  The feature '[SomeFeatureID]' uses the directory "[SomeDirectory2]" in the solution.  However, it is currently installed in the farm to the directory "[SomeDirectory1]". Uninstall the existing feature before you install a new version of
the solution.
You commence troubleshooting.

Troubleshooting

  1. Looked in ...15\TEMPLATE\FEATURES folder for [SomeDirectory1].
    1. Not found
  2. Performed search in ...\15\TEMPLATE for [SomeDirectory1].
    1. Found it under ...\15\TEMPLATE\FEATURES\ADMIN.  The folder is empty.
  3. Pulled a listing of all features across the farm using Get-SPFeature | sort-object DisplayName | ft Displayname,ID -auto.
    1. Found a listing for "SomeDirectory1  SomeFeatureID"
  4. Pulled listing of all orphaned features using Get-SPFeature | ? { $_.Scope -eq $null }.
    1. Found a listing for "SomeDirectory1  SomeFeatureID".
  5. Attempted to get a handle on the orphaned feature using Get-SPFeature -Identity  '[SomeFeatureID]'.
    1. Returned error message:
      Get-SPFeature : Cannot find a Feature object with Path or Id:
      '[SomeFeatureID]'
      in scope Local farm.
  6. Attempted to get handle on the orphaned feature using its display name using $feature = Get-SPFeature | ? {$_.DisplayName -eq "SomeFeature"} followed by $feature.
    1. Feature information is displayed.
  7. Attempted to delete the feature using $feature.delete.
    1. Returned nothing.
  8. Pulled listing of all orphaned features using Get-SPFeature | ? { $_.Scope -eq $null }.
    1. Feature is not listed.
  9. Now attempted to add the most recent build of the solution using Add-SPSolution -Path "D:\2010\TPS1.wsp"
    1. Succeeded.

Solution

  • Check for orphaned features if unable to install updated versions of third-party solutions.

References

  • Thanks to Anatoly Mironov for pointing the way to the solution.  His clear description helped me quickly identify and resolve the problem.