PowerShell: Getting Sandbox Solutions in a SharePoint Web Application


Introduction

Like all good SharePoint developers we have been using Sandbox Solutions where we can. Of course one of the problems with Sandbox solutions is that its difficult to find out what you have installed and where.
This is particularly important if you have a Sandbox solution that is used for branding and is installed into a number of site collections.
Therefore I built a script which will retrieve sandbox solutions in a web application.
You can filter which sandbox solutions by the name.
Please fill free to use and modify the script, though make sure you test it before using in Production.
If you do make some enhancement that you think is useful, please let me know as would love to see what additional functionality is useful.

How does the script works

The script is a PowerShell script which works in the following way:
  • The script is run by providing the Url for the Web Application
  • The script will enumerate through all the site collections in the web application and creates an array object which has two properties, SiteCollection and Solution
  • Once all site collections have been enumerated then the array will be outputted.
This way you can use the output for further processing steps. For example, to filter the results for one solution and upgrade the solutions in all the site collections returned.
The script is shown below:

param
(
[Parameter(Mandatory=$false, HelpMessage='Solution Name')]
[string]$SolutionName="",
[Parameter(Mandatory=$false, HelpMessage='Solution Name')]
[string]$WebApplicationUrl="")$memoryAssignment = Start-SPAssignment;
$numberOfSolutionsFound = 0;
$webApplication = Get-SPWebApplication -Identity $WebApplicationUrl -ErrorAction SilentlyContinue -AssignmentCollection $memoryAssignment;
if($webApplication -ne $null)
{
#enumerate through site collections in web application
$allSites = Get-SPSite -WebApplication $webApplication -Limit ALL -Confirm:$false -AssignmentCollection $memoryAssignment;
foreach($checkSite in $allSites)
{
#Write-Output "Checking Site " $checkSite.Url " for solution " $SolutionName;
if($SolutionName -eq "")
{
$checkSolutions = Get-SPUserSolution -Site $checkSite -AssignmentCollection $memoryAssignment;
foreach($solution in $checkSolutions)
{
$output = New-Object -TypeName "System.Object";
Add-Member -InputObject $output -MemberType NoteProperty -Name "Solution" -Value "";
Add-Member -InputObject $output -MemberType NoteProperty -Name "SiteCollection" -Value "";
$output.Solution = $solution;
$output.SiteCollection = $checkSite;
Write-Output -InputObject $output;
$numberOfSolutionsFound++
}
}
else
{
$checkSolution = Get-SPUserSolution -Identity $SolutionName -Site $checkSite -ErrorAction SilentlyContinue -AssignmentCollection $memoryAssignment;
if($checkSolution -ne $null)
{
$output = New-Object -TypeName "System.Object";
Add-Member -InputObject $output -MemberType NoteProperty -Name "Solution" -Value "";
Add-Member -InputObject $output -MemberType NoteProperty -Name "SiteCollection" -Value "";
$output.Solution = $checkSolution;
$output.SiteCollection = $checkSite;
Write-Output -InputObject $output;
$numberOfSolutionsFound++
}
}
}
}</p>
<p style="direction: ltr; margin-top: 0; margin-left: 0; width: 7.5875in;">Write-Output "Found $numberOfSolutionsFound Instances of Solution $SolutionName";
Stop-SPAssignment $memoryAssignment;</p>
<p style="direction: ltr; margin-top: 0; margin-left: 0; width: 7.5875in;">

 

How to execute the script

 To execute the script do the following:
  • Logon to SharePoint 2013 server
  • Run the SharePoint Management Shell
    • .\Get-SPUserSolutionInWebApplication -WebApplicationUrl https://sharepoint
    • There is an optional parameter -SolutionName which allows you to only return the solutions with a particular name

The script will output an array of Solution Objects with an associated Site Collection object.

We can assign a value to the output and then do some further processing using that value.

Here is an example of the output from the script without assigning the result to a variable.

getusersolutionsfromwebapp

To do something more useful then assign the output to a variable. You can then enumerate through the variable array.

For example, the following screenshot shows the output being assigned to a variable $solutions and then it is being enumerated using the following:

$solutions | %{Write-Host $_.Solution.Name “in” $_.SiteCollection.Url}

enumerate-usersolutionarray

Downloads

If you would like to try out the PowerShell script, then you can download the script here:

Get-SPUserSolutionInWebApplication.zip

Please fill free to use and modify the script, though make sure you test it before using in Production.

Also let me know if you find it useful and if you have made some cool changes let me know as always looking for ways to make things better!

SharePoint 2013/Online Attachment Viewer Enhancement


Introduction

Update: 22nd January 2016 – Further updates to fix an issue with Minimal Download Strategy (MDS) and works correctly when used in multiple list view app parts on the same page.

Recently I had a client that wanted a better way to get to the attachments that were linked to a SharePoint list item from a list view web part. This request had me thinking and I didn’t think it would be too difficult to achieve using SharePoint 2013’s Client Side Rendering (CSR) user interface components. Anyway one night I decided on an approach and put the following together. attachment-viewer-example

Solution

The solution uses client side rendering to override the output that the field displays in a list view. This is achieved using a list template override to change the Attachment’s field rendering. The solution makes use of the SharePoint Callout Manager which is used to display links to the attachment. I found a set of articles which have been posted in the Resources section below really good for getting to grips with using the Callout Manager. The implementation works on both SharePoint 2013 and SharePoint Online. The one issue with the approach is that you have to reference the JavaScript file for each view, so if you create a new view then that view needs to be setup. This isn’t a problem if you are creating a custom list with a schema.xml as you can reference the JavaScript in the list’s schema. The solution makes use of the SharePoint 2013 JSOM API and the list of attachments is only created one the user has clicked on the paperclip icon to see the list of attachments. This is to try and keep the load down on the server when there are lots of attachments for a particular list item.

Resources

The following websites provided a great resource in getting the Callout Manager and SharePoint JSOM working. http://blog.alexboev.com/2012/07/custom-callouts-in-sharepoint-2013.html

http://www.learningsharepoint.com/2013/05/09/sharepoint-2013-callout-popup-tutorial/

SharePoint 2013 – Custom CallOut with File Preview – Obilogic

http://msdn.microsoft.com/en-us/library/office/dn268594(v=office.15).aspx

Setup

Watch the video showing you how to setup the attachment viewer.

To take advantage of the list attachment viewer and set it up for a particular list view, do the following:-

  • Download the zipfile, found at the bottom of the post
  • Unzip the zip file to extract the ITSP.SP.AttachmentField.js file.
  • Upload the ITSP.SP.AttachmentField.js into a suitable location, I would suggest the Site Assets library.
    • Create a folder called Scripts within the Site Assets library
    • Upload the ITSP.SP.AttachmentField.js into this folder, this keeps your content organised.
    • Alternatively you could package up the JS file to deploy the files by using a Module into a site collection.
  • Browse to the SharePoint list that you wish to enable the viewer on.
    • Make sure that the list has the Attachment field showing as this is the column that is going to be overridden
  • Click “Edit Page”

attachment-viewer-stepone-editpage

  • Click on the List Viewer Web Part, choose Edit Web Part

attachment-viewer-steptwo-editwebpart

  • The web part properties will appear on the right hand side
  • Expand the miscellaneous section
  • In the JSLink field type in the location of the ITSP.SP.AttachmentField.js file
  • E.g ~site/SiteAssets/Scripts/ITSP.SP.AttachmentField.js
  • Use the ~site token to substitute for the local site url

attachment-viewer-stepthree-jslink

  • Click Apply
  • Click Ok
  • Save the Page

Now create a list item and add some attachments to it. When you click on the paperclip icon you will get a callout which will display all the attachments for that list item. attachment-viewer-paperclip attachment-viewer-example Please let me know if you find it useful, I have tested the script with 5/6 attachments, it should scale with 20 or so documents as the list of documents is built each time you click on a particular document.

Update 21st May 2014

A new version of the script has been released to add support for the Minimal Download Strategy feature. This helps to reduce the amount of bytes being downloaded to the client. For more information please read this MSDN Blog Post.

The behaviour that you would start seeing is that the attachment callout would appear once and then never again. More information can be found here:-

Update 17th November 2015

A new version of the script has been released to add support for being used in multiple list view app parts on the same page.
Please use this version instead.

Thanks to Dar for reporting this issue.

Update 4th January 2016

It seems that I did not do enough testing and a further issue was discovered by Ken when having multiple list view web parts on the page.

Update 22nd January 2016

There still seemed to be an issue with MDS and also the control was polluting the global JavaScript pool, this update fixed those has been tested on SharePoint Online.

Download:
ITSP.SP.AttachmentField-20160122.zip