Monday, October 29, 2012

Introduction to SharePoint 2013 App Model - A Primer

SharePoint 2013 introduces the new App Model that adds another dimension to the kinds of solutions you can build on the SharePoint technology platform in addition to Full Trust Solutions and Sandboxed solutions.

Lets take a deep dive on the App Model and understand the fundamental building blocks. 

I. SharePoint 2013 App Model Highlights:
  1. SharePoint applications no longer live in SharePoint
  2. Custom code executes in the client, cloud or on-prem
  3. Apps are granted permissions to SharePoint via OAuth
  4. Apps communicate with SharePoint via REST / CSOM
  5. Acquire apps via centralized Marketplace, Corporate Marketplace, Public Marketplace (via submission process)
  6. APIs for manual deployment
  7. Everything in a SharePoint site is an app: Contact form, Travel request, Shared Documents library, Contacts list
  8. Apps for SharePoint mimics Facebook Apps to an extent.
II. SharePoint 2013 App Model Benefits:
  1. No custom code on the SharePoint server
  2. Easier to upgrade to future versions of SharePoint
  3. Works in hosted environments w/o limitations
  4. Reduces the ramp-up time for those building apps
  5. Don’t need to know/be as familiar with SharePoint “-isms”
  6. Leverage hosting platform features in new apps
  7. Enables taking SharePoint apps to different levels – further than what can be done with farm / sandbox solutions
  8. Isolation – private vs. public clouds
III. SharePoint 2013 Application Architecture: The diagram below talks about the SP 2013 Application Architecture and its components.

REST / CSOM - are the programmatic approaches available to access SP 2013 data from Apps.
Remote Event Receivers - To handle events in an app for SharePoint remotely, you create remote event receivers and app event receivers.
BCS - Apps can perform CRUD operations on external data store using ODATA by leveraging External Content Types and External Lists.

IV. SharePoint 2013 App URL:
V. SharePoint 2013 Application Comparison Chart: Lets see what programming options we have while creating Apps for SharePoint.
VI. Different kinds of Apps for SharePoint 2013:  Here are 3 different kinds architecture approaches available for creating SharePoint 2013 Apps.
 
 1. SharePoint-Hosted App:
  •     SharePoint hosted apps wholly reside in SharePoint
  •     Uses SharePoint artifacts (lists/libraries)
  •     Business logic executes or on the client
  •     HTML5
  •     JavaScript using CSOM or REST API's
 2. Cloud based Apps:
  •     Cloud hosted apps primarily execute outside of SharePoint
  •     May use SharePoint artifacts (lists/libraries)
  •     Communicate via CSOM / REST
  •     Granted permission to SharePoint via OAuth
  •     Business logic lives & executes outside of SharePoint
  •     On-Premise hosted web application
  •     Windows Azure
  •     3rd party host
  •     Managed CSOM (Client Side Object Model) can be adopted as a programming model for both     these kinds of Apps.   
  •     Within cloud based apps, we have a further bifurcation between:  
  •     Provider-Hosted Apps- Apps developed/maintained on Premises or a Private Cloud.  
  •     Auto-Hosted Apps - Apps provisioned using Windows Azure Auto-Hosting. SharePoint deploys ASP.NET application & SQL Azure DB to Azure automatically when SharePoint app is installed.
VII. SharePoint 2013 Application UX (User Experience):

VIII. SharePoint 2013 Application Scopes:
i. Web scope - By default all SharePoint 2013 SharePoint apps are scoped to Web.
ii. Tenant scope - Cloud based apps can have their Apps as tenant scoped. For e.g.: Apps hosted on Office 365 can have a Tenant scope for privacy and security. Not Applicable to SharePoint Hosted Apps.

IX. SharePoint 2013 App Hosting Options: Cloud v/s SharePoint
 
 X. SharePoint 2013 Application Isolation:
  • When apps are provisioned, new SPWeb (AppWeb) created within hosting SPWeb
  • Each app resides within it’s own SPWeb for isolation
  • Special DNS address configured by administrators
  • App SPWeb’s live in separate domain (DNS)
  • Each App hosted on it’s own unique URL because:
  • Blocks XSS: isolation to special SPWeb under special domain blocks cross site scripting
  • Enforces App Permissions: apps communicate with sites via CSOM /API & must be granted to do so
XI. Obtaining SharePoint 2013 Applications:
 Applications can be acquired multiple ways:
  • Public Marketplace
  • Similar Windows Phone Marketplace
Subject to submission process & approval
  • App Catalog
  • Apps developed internally
Apps acquired and approved for internal use
  • Custom Deployment Process
  • Developers can use remote / local SharePoint & Windows Azure APIs to deploy apps with custom code. These APIs are restricted to the developer site for tooling scenarios

Thursday, September 13, 2012

Powershell script to Export and Import Managed Metadata Termstore across SharePoint farms while still retaining its GUIDs

While migrating your site collections from one farm to the other, Managed Metadata termsets being used and stored in lists and libraries for various site collections would reference to the GUID’s of the original managed metadata term store. The site columns themselves, would reference the GUID of the term sets of the source managed metadata service. Hence, it becomes difficult to migrate the various site collections to the new farm. In this situation, we run the risk of making the existing managed metadata columns being orphaned for the source site collection to be migrated.

Below mentioned PowerShell script Exports and Imports Managed Metadata termstore still retaining its GUID's (sspId's- used internally by the Termstore) and referred by Managed metadata columns in list/library.

#Export Managed Metadata Taxonomy Name

$managedMetadataAppSource = “4a867ce5-d9ee-4051-8e73-c5eca4158bcd”; #this sets the exporting MMS ID
$mmSourceProxy = Get-SPServiceApplicationProxy | ?{$_.TypeName -eq "Managed Metadata Service Connection"};
Export-SPMetadataWebServicePartitionData -Identity $managedMetadataAppSource -ServiceProxy $mmSourceProxy -Path "C:\ExportManagedMetadata\locationexportfile.bak";

#Import Managed Metadata Taxonomy Name

$managedMetadataAppTarget = "d045d3ce-e947-4465-b039-0dfbbe24fb22"   #this sets the importing MMS ID
$mmTargetProxy = Get-SPServiceApplicationProxy | ?{$_.TypeName -eq "Managed Metadata Service Connection"};
Import-SPMetadataWebServicePartitionData -Identity $managedMetadataAppTarget -ServiceProxy $mmTargetProxy -Path "C:\ImportManagedMetadata\locationexportfile.bak" -OverwriteExisting;

Friday, September 7, 2012

Powershell Script to query and export Workflow History List Items across a Site Collection using CrossListQueryInfo in a .csv file

This Power Shell script queries across a given Site Collection using CrossListQueryInfo and CrossListQueryCache objects available in SharePoint 2010 OM. The script also generates a CSV file report of all Workflow History List items across the given site collection.

Add-PsSnapin Microsoft.SharePoint.PowerShell

## SharePoint DLL
[void][System.Reflection.Assembly]::LoadWithPartialName("Microsoft.SharePoint")
[void][System.Reflection.Assembly]::LoadWithPartialName("Microsoft.SharePoint.Publishing")
   
    $SiteCollUrl = "https://sharepointfix.com/sites/crosslistquerycache"
 
    $site = new-object Microsoft.SharePoint.SPSite($SiteCollUrl)
    $web = $site.OpenWeb()
   
    try
       {
        #Specify your CAML query here
        $caml = "" #You can specify your <Where/> clause here
        $lists= "<Lists ServerTemplate='140' Hidden='True'/>"
        $viewFields = "" #You can specify your <ViewFields/> here
        $webs = "<Webs Scope='SiteCollection' />"
        $queryInfo = new-object Microsoft.SharePoint.Publishing.CrossListQueryInfo
        $queryInfo.Webs = $webs
        $queryInfo.Lists = $lists
        $queryInfo.ViewFields = $viewFields
        $queryInfo.Query =$caml
        $crossListCache =  new-object Microsoft.SharePoint.Publishing.CrossListQueryCache –ArgumentList $queryInfo
        $allow= "TRUE"
        $results = $crossListCache.GetSiteDataResults($web, $allow)
        Write-Host "There are $($results.Data.Rows.Count) items."
        $results.Data | Export-Csv -Path "F:\WorkflowHistoryListItemReport.csv" -NoTypeInformation -Force       
       }
    catch
    {
        "Error encountered:" | Out-Default
        $_.Exception | Write-Error
    }
    finally
    {
        $web.Dispose()
        $site.Dispose()
    }
   
Remove-PsSnapin Microsoft.SharePoint.PowerShell
Write-Host "Finished"

Monday, June 18, 2012

Powershell script to get Site Collection Pages and List Items count using SPSiteDataQuery object

This PowerShell script queries a given Site Collection and returns all its Pages and List Item count recursively using SPSiteDataQuery object model.

Add-PsSnapin Microsoft.SharePoint.PowerShell

## SharePoint DLL
[void][System.Reflection.Assembly]::LoadWithPartialName("Microsoft.SharePoint")
[void][System.Reflection.Assembly]::LoadWithPartialName("Microsoft.SharePoint.Publishing")

# CHANGE THE FOLLOWING LINE TO POINT TO THE DESIRED PORTAL SITE COLLECTION
$web = Get-SPWeb "http://sharepointfix/sites/spsitedataquery"

if($web -ne $null)

    # Adding fields to the view
    $viewFields = New-Object System.Collections.Specialized.StringCollection
    $viewFields.Add(“Title”)
    $viewFields.Add(“Name”)

    # Construct the query object for publishing pages
    $queryPages = New-Object Microsoft.SharePoint.SPSiteDataQuery
    $queryPages.Lists = "<Lists ServerTemplate=""850""/>"

    #Specify your clause here
    $queryPages.Query = ""
    $queryPages.RowLimit = 1000000
    $queryPages.ViewFields = $viewFields
    $queryPages.Webs = "<Webs Scope=""Recursive""/>"
   
    # Construct the query object for list items
    $queryItems = New-Object Microsoft.SharePoint.SPSiteDataQuery
    $queryItems.Lists = "<Lists ServerTemplate=""100""/>"

    #Specify your clause here
    $queryItems.Query = ""
    $queryItems.RowLimit = 1000000
    $queryItems.ViewFields = $viewFields
    $queryItems.Webs = "<Webs Scope=""Recursive""/>"
   
    # Execute both queries and display the count of the number of pages and items
    $pagesData = $web.GetSiteData($queryPages)
    $itemsData = $web.GetSiteData($queryItems)
    Write-Host "There are $($pagesData.Rows.Count) pages and $($itemsData.Rows.Count) items."
   
    $web.Dispose()
}

Remove-PsSnapin Microsoft.SharePoint.PowerShell

Write-Host "Finished"

Benefits of SPSiteDataQuery over SPQuery is that SPSiteDataQuery queries the whole site collection including all its subsites recursively and brings back the desired data.

Monday, March 19, 2012

Powershell script to get SharePoint Page Layouts inventory and its usage across site collection

I was writing a PowerShell script that needed to do 2 things primarily:

1. Get an inventory of all Page Layouts deployed across a SharePoint 2010 Farm.
2. To find out whether or not any of these Page Layouts were in use or not within its various sites/sub-sites. To simply put it the other way, did any of the sites/sub-sites had Pages created out of any of the available Page Layouts in the farm.

The first requirement was not too hard to accomplish, we have the PublishingSite.GetPageLayouts in the SharePoint OM, but I had to scratch my head a little bit for the second one though.

Iterating through Pages library within numerous site/sub-sites for approximately 20,000 site collections in the Farm, in order to find out the Page Layout usage would be too expensive and time consuming. There had to be a better/faster approach to handle this scenario.

The clue was SharePoint 2010's OOTB related resources inventory. Go to “Site Actions” -> “Site Content and Structure” and select “Master Page Gallery”. See snapshot below:



The OOTB Show Related Resources functionality allows a user to select any of the Page Layouts/resources within the Master Page and Page Layouts Gallery and mentions files that uses it across the site collection.

Now there has to be a way to achieve the same programmatically as well.
I started exploring SPFile object model and voila, I found the SPFile.BackwardLinks property, see the MSDN article: http://msdn.microsoft.com/en-us/library/microsoft.sharepoint.spfile.backwardlinks.aspx

So my sample PowerShell code snippet does 2 things:

1. Gets an Inventory of all Page Layouts for a Publishing Site, see sample PowerShell script code :

$objSite = Get-SPSite "http://sharepointfix.com/sites/PageLayoutUsageReport"

[Microsoft.Sharepoint.Publishing.PublishingSite]$publishingSite = New-Object Microsoft.SharePoint.Publishing.PublishingSite($objSite)

#Gets all Page Layouts for the current Site Collection, no need to iterate all subwebs
$pageLayouts = $publishingSite.GetPageLayouts($false)

#I can make use of Export-CSV to generate a .csv file for reporting purposes. That works like a charm.
#But Powershell also provides you with a lovely Grid View interface, try doing something like this:

$pageLayouts | Out-GridView

## Of course, I will wrap the above script in a foreach block to iterate through all web applications and site collections in the SP 2010 Farm.

2. Get Page Layout Usage - The sample code now makes the use of SPFile.BackwardLinks property in order to find whether the Layout is in use or not

## Iterate through all the Publishing Page Layouts
foreach($layout in $pageLayouts)
{
      ## Get Page Layout File object
      [Microsoft.SharePoint.SPFile]$file = $publishingSite.RootWeb.GetFile($layout.ServerRelativeUrl);

#Backward links contain the URLs of all files that link to the current file from the current site collection and its # sites/subsites.
# Pages that link to the current file from another Web site or site collection are not included in the backward
# link information.

# returns $true, if SPFile.BackwardLinks.Count is greater than 0
 $IsPageLayoutInUse = ($file -ne $null -and $file.BackwardLinks -ne $null -and       $file.BackwardLinks.Count -gt 0)
}

The above script is just a primer to the wide array of possibilities that PowerShell offers as a tool.
I hope this post has helped you in someway or the other. Happy Programming :)

Friday, February 10, 2012

Powershell script to check whether SharePoint 2010 Feature is activated for a particular Sub-site

The Powershell script below checks whether any given feature, in this case its the PublishingWeb Feature is activated or not for a particular Sub-Site.


Here I have shown 2 approaches: 1st one checks the Feature Folder Name and 2nd approach checks the FeatureID activated for that particular Sub-site. Choose the way best suitable in your case.


Add-PsSnapin Microsoft.SharePoint.PowerShell


## SharePoint DLL
[void][System.Reflection.Assembly]::LoadWithPartialName("Microsoft.SharePoint")


$featureFolderName = "PublishingWeb"
$subSiteURL = "http://sharepointfix/sites/home/USA"


#Approach 1 - Check using Feature Name
#Get Feature ID based on the Feature Name and ensure whether its already activated or not at the current sub-site scope
$FeatureID = Get-SPFeature -Web $subSiteURL | Where {$_.DisplayName -eq $featureFolderName}


if($FeatureID -ne $null)
     {
      #Approach 2 -  Check using Feature ID
      #Check whether Feature to be activated is already activated for this sub-site
      if (Get-SPFeature -Web  $subSiteURL | Where {$_.ID -eq $FeatureID.Id})
      {
       Write-Host $featureFolderName "is already activated at :" $subSiteURL 
       }
      else
      {
       Enable-SPFeature -Identity $featureFolderName -Confirm:$false -Url $subSiteURL 
       Write-Host $featureFolderName "has been activated at :" $subSiteURL
      }
     }
else
{
      Enable-SPFeature -Identity $featureFolderName -Confirm:$false -Url $subSiteURL 
      Write-Host $featureFolderName "has been activated at :" $subSiteURL 
}


Remove-PsSnapin Microsoft.SharePoint.PowerShell


Echo Finish

Thursday, February 9, 2012

PowerShell script to Enumerate Sites, Sub-sites and print them in a .csv file

The Powershell script below enumerates/iterates through all Site Collections and Sub-sites for a Web Application and prints the output in a .csv file.

1. Copy the code below and modify the variables highlighted in yellow below, save the following as IterateAllSitesSubsites.ps1 file:


Add-PsSnapin Microsoft.SharePoint.PowerShell

## SharePoint DLL
[void][System.Reflection.Assembly]::LoadWithPartialName("Microsoft.SharePoint")

$webApplicationURL = "http://dev-sp-2010:1000"
set-variable -option constant -name out -value "C:\PrintAllSitesSubsites.csv"

$webApp = Get-SPWebApplication $webApplicationURL

if($webApp -ne $null)
{
"Web Application : " + $webApp.Name | Out-File $out -Append

foreach($siteColl in $webApp.Sites)
{
   if($siteColl -ne $null)
   {
"Site Collection : " + $siteColl.Url | Out-File $out -Append

foreach($subWeb in $siteColl.AllWebs)
{
if($subWeb -ne $null)
{
#Print each Subsite
#Write-Host $subWeb.Url
"Subsite : " + $subWeb.Name + " - " + $subWeb.Url | Out-File $out -append
                 
$subWeb.Dispose()
}
else
{
Echo $subWeb "does not exist"
}
}
$siteColl.Dispose()
}
else
{
Echo $siteColl "does not exist"
}
}
}
else
{
Echo $webApplicationURL "does not exist, check the WebApplication name"
}

Remove-PsSnapin Microsoft.SharePoint.PowerShell

Echo Finish

2. To automatically run the above .ps1 script as a batch utility, Copy and paste the code below and save it with a .bat file extension

cd /d %~dp0
powershell -noexit -file ".\IterateAllSitesSubsites.ps1" "%CD%"
pause

Run the above .bat file, on the receipt of success message, traverse to the configured path and find the .csv file with all the sites/sub-sites printed.

Here is an alterante way of doing the same thing in a quick way using Powershell CMD:

Get-SPWebApplication "http://SPFix/" | Get-SPSite -Limit All | Get-SPWeb -Limit All | Select Title, URL, ID | Export-CSV C:\IterateAllSitesSubsites.ps1.csv -NoTypeInformation

Tuesday, January 17, 2012

Powershell script to modify List Item Create/Edit Permissions

Recently I came across a very interesting requirement in one of our SharePoint 2010 projects.

Requirement: Customer wanted to lock down/prevent Site wide Members/Contributors from creating, modifying/editing and deleting List Items for the first 10 days of every month.

Solution: Here are the options to meet the above requirements:

1. Write a C#.NET utility (.exe) using SP 2010 object model to Revoke and Grant List Item Permissions and schedule it using the Task Scheduler on your SharePoint farm.

2. Program against the SharePoint web service to create a utility (.exe) that Revokes/Grants List item permissions and schedule it using the Task Scheduler in your remote system.

3. Write 2 Powershell scripts to Revoke and Grant List Item Permissions and create batch file to call the .ps1, then schedule it using the Task Scheduler on your SharePoint farm.

We went for option 3, i.e. Creation of Powershell scripts, as this is one of the most preferred and easiest of all the above mentioned solutions. Also we were allowed to copy/paste scripts to our SharePoint 2010 Server Farm, so that helped additionally and we were able to meet the customers requirements without any code/utility deployments in our SharePpint farm.

We will first write the script for Revoking List Item Permissions as it needs to be scheduled on 1st of every month:

1. Copy the powershell script below and modify the variables highlighted in yellow below, save the following as RevokeListIitemEditPermissions.ps1 file:

Add-PsSnapin "Microsoft.SharePoint.PowerShell"

## SharePoint DLL Reference
[void][System.Reflection.Assembly]::LoadWithPartialName("Microsoft.SharePoint")
[void][System.Reflection.Assembly]::LoadWithPartialName("Microsoft.SharePoint.Administration")

#Change the Web URL to point to the site/subsite where your List exists and the list name
$web = Get-SPWeb "http://dev-sp-2010:1000/sites/SPFix/"
$listName = "List Security"

#Check If the Web is null
if ($web -ne $null)
{
#Get the list in this site
$list = $web.Lists[$listName]

if($list -ne $null)
{
#Revoke Create and Edit permissions for the Current List
#4 — Users cannot modify any list item.
$list.WriteSecurity = 4

#Update the list
$list.Update()

#Update the web
$web.Update()

echo "Revoked Edit Items Permissions on the list"
}
else
{
echo "List is null. Check the List Name."
}

#Dispose of the site object
$web.Dispose()
}
else
{
echo "Web is null. Check the Web URL."
}

Remove-PsSnapin "Microsoft.SharePoint.PowerShell"

2. To automatically run the above .ps1 script as a batch utility, Copy and paste code below and save it with a .bat file extension

cd /d %~dp0
powershell -noexit -file ".\RevokeListIitemEditPermissions.ps1" "%CD%"
pause

We will now write the Grant List Item Edit Permissions to grant back the List Item Create, Edit and Delete privileges for all Contributors/Members for the List. This needs to be scheduled on 10th of every month.

3. Copy the powershell script below and modify the variables highlighted in yellow below, save the following as GrantListIitemEditPermissions.ps1 file:

Add-PsSnapin "Microsoft.SharePoint.PowerShell"

## SharePoint DLL Reference
[void][System.Reflection.Assembly]::LoadWithPartialName("Microsoft.SharePoint")
[void][System.Reflection.Assembly]::LoadWithPartialName("Microsoft.SharePoint.Administration")

#Change the Web URL to point to the site/subsite where your List exists and the list name
$web = Get-SPWeb "http://dev-sp-2010:1000/sites/SPFix/"
$listName = "List Security"

#Check If the Web is null
if ($web -ne $null)
{
#Get the list in this site
$list = $web.Lists[$listName]

if($list -ne $null)
{
#Grant Create and Edit permissions for the Current List
#2 — Users can modify only items that they create.
$list.WriteSecurity = 2

#Update the list
$list.Update()

#Update the web
$web.Update()

echo "Granted Edit Items Permissions on the list"
}
else
{
echo "List is null. Check the List Name."
}

#Dispose of the site object
$web.Dispose()
}
else
{
echo "Web is null. Check the Web URL."
}

Remove-PsSnapin "Microsoft.SharePoint.PowerShell"

4. To automatically run the above .ps1 script as a batch utility, Copy and paste code below and save it with a .bat file extension

cd /d %~dp0
powershell -noexit -file ".\GrantListIitemEditPermissions.ps1" "%CD%"
pause

Last but not the least schedule the 2 batch files by going to the Windows Task Scheduler and Create a Task.

You need to create 2 tasks, first one for Revoking the List Item Edit permissions that Triggers on 1st of every month and 2nd one to Grant List Item Edit Permissions that Triggers on 10th of every month. In the Actions section of the Task scheduler, give reference to the batch files created above one by one. The batch files in-turn calls the .ps1 according to the jobs scheduled every month.

Happy Programming :)

Saturday, January 14, 2012

Powershell script to print User Profile properties in a .csv file


Here is the powershell script to print all User Profile properties for a SharePoint farm and print them into a .csv file


1. Copy the code below and modify the variables highlighted in yellow below, save the following as PrintAllUserProfileProperties.ps1 file:

param
(
    $siteAddress
)

Add-PsSnapin "Microsoft.SharePoint.PowerShell"
[System.Reflection.Assembly]::LoadWithPartialName("Microsoft.SharePoint")
[System.Reflection.Assembly]::LoadWithPartialName("Microsoft.Office.Server.UserProfiles")

try
{
    $site = New-Object Microsoft.SharePoint.SPSite $siteAddress
    $context = [Microsoft.SharePoint.SPServiceContext]::GetContext($site)
    $configManager = New-Object Microsoft.Office.Server.UserProfiles.UserProfileConfigManager $context
    $propertyManager = $configManager.ProfilePropertyManager
    set-variable -option constant -name out -value "C:\PrintAllUserProfileProperties.csv"

    foreach ($codeProperty in $propertyManager.GetCoreProperties())
    {
        if (!$codeProperty.IsSection)
        {
            $codeProperty.DisplayName + " - " + $codeProperty.Name | Out-File $out -append
        }
    }
}
finally
{
    if ($site -ne $null)
    {
        $site.Dispose()
    }
}

Echo "Finished!"
Echo "User Profile properties printed at:" $out

Remove-PsSnapin "Microsoft.SharePoint.Powershell"

2. To automatically run the above .ps1 script as a batch utility, Copy and paste the code below and save it with a .bat file extension, kindly make sure you update the siteAddress switch with the relevant farm URL

cd /d %~dp0
powershell -noexit -file ".\PrintAllUserProfileProperties.ps1" -siteAddress "http://dev-sp-2010:1000/sites/SPFix" "%CD%"
pause

Run the above .bat file, on the receipt of success message, traverse to the configured path and find the .csv file with all the user profile properties printed.