Using Powershell to Add Permission Levels in SharePoint 2010

Besides using PowerShell to modify or adding list permissions, you can also add new Permission Levels. As permission levels don’t persist within site templates, this can be handy when creating deployment scripts for new sites.

Here’s how you do it:

# Add Permission Level to a site
# (c) 2011 Morgan de Jonge

$spSite = Get-SPSite "http://portal.contoso.com"
# We'll assume the list is in the top-level site in the site collection
$spWeb = $spSite | Get-SPWeb

# In this example, we add a new Permission Level labelled "Add Only" to the site, which will allow users to only add new items (no editing or removing)
if($spWeb.RoleDefinitions["Add Only"] -eq $null)
{
    # Role Definition named "Add Only" does not yet exist
    $spRoleDefinition = New-Object Microsoft.SharePoint.SPRoleDefinition
    $spRoleDefinition.Name = "Add Only"
    $spRoleDefinition.Description = "Can only Add items. Use this Permission Level for List or Library Permissions."
    # .Type is a ReadOnly property, hence it'll remain on "None".

    # Use the command [System.Enum]::GetNames("Microsoft.SharePoint.SPBasePermissions") to get a list of possible BasePermission values
    # For this Permission Level, we'll add four base permissions:
    $spRoleDefinition.BasePermissions = "ViewListItems, AddListItems, Open, ViewPages"
    $spWeb.RoleDefinitions.Add($spRoleDefinition)
}

#Display the properties for our new Permission level
$spWeb.RoleDefinitions["Add Only"] | Out-Host

$spWeb.Dispose()
$spSite.Dispose()

Unfortunately, the RoleDefinition.Type property, which contains a RoleType Enum value,  is Read-Only. Hence, it’ll get the default value “None”.

The .BasePermissions Property is a flags attribute which contains the actual permissions granted to users and groups assigned with the permission level. See MSDN for a description of these Permissions, or use the following command to enumerate them in PowerShell:

# Enumerate through SPBasePermissions
PS > [System.Enum]::GetNames("Microsoft.SharePoint.SPBasePermissions")
EmptyMask
ViewListItems
AddListItems
EditListItems
DeleteListItems
ApproveItems
OpenItems
ViewVersions
DeleteVersions
CancelCheckout
ManagePersonalViews
ManageLists
ViewFormPages
Open
ViewPages
AddAndCustomizePages
ApplyThemeAndBorder
ApplyStyleSheets
ViewUsageData
CreateSSCSite
ManageSubwebs
CreateGroups
ManagePermissions
BrowseDirectories
BrowseUserInfo
AddDelPrivateWebParts
UpdatePersonalWebParts
ManageWeb
UseClientIntegration
UseRemoteAPIs
ManageAlerts
CreateAlerts
EditMyUserInfo
EnumeratePermissions
FullMask

See the modify or adding list permissions article for instructions on how to assign this new Permission Level to a user or group.

Modifying list permissions from Powershell

There can be cases where you need to make changes to list permissions or list behaviour regarding security from PowerShell. One case may be where a saved site template does not contain all settings for a list, such as Item-level permission settings (found in List Settings → Advanced Settings). Another case may be a list with unique permissions.

This post contains two examples for making changes to these kind of list settings and permissions from Powershell. These are taken from a deployment script I created for a client.

This script will alter the Item-level Permissions for a list called “Questions” so that users can only access and edit list items they themselves created:

Furthermore, it adds Contribute permissions to the Visitors group for the list, providing unique list permissions (breaking inheritance).

# Alter Item-Level Permission settings and assign "Contribute" role definition to the visitors group
# (c) 2011 Morgan de Jonge

# Specify the name of the visitors SharePoint group
$visitorsSPGroupName = "Example Site Visitors"

$spSite = Get-SPSite "http://portal.contoso.com"
# We'll assume the list is in the top-level site in the site collection
$spWeb = $spSite | Get-SPWeb
# Look up the list named "Questions"
$questionsList = $spWeb.Lists["Questions"]

# Set the Read access Item-level permissions settings to "Read items that were created by the user"
$questionsList.ReadSecurity = 2
# Set the Create and Edit access Item-level permissions to "Create items and edit items that were created by the user
$questionsList.WriteSecurity = 2

# Assign the "Contribute" RoleDefition to the site's visitors group
$visitorsSPGroup = $spWeb.Groups[$visitorsSPGroupName]
$questionsList.BreakRoleInheritance($true)
$assignment = New-Object Microsoft.SharePoint.SPRoleAssignment($visitorsSPGroup)
# Assuming this is a default site, we'll look for a role definition of the type "Contributer".
# This way, the script will also work with SharePoint sites created in languages besides English.
$assignment.RoleDefinitionBindings.Add(($spWeb.RoleDefinitions | Where-Object { $_.Type -eq "Contributor" }))
$questionsList.RoleAssignments.Add($assignment)

$questionsList.Update()

$spWeb.Dispose()
$spSite.Dispose()
(To copy this code, double-click the anywhere in the code and press CTRL/Cmd+C to copy it)

In line 24, you could’ve also looked up the role using $spWeb.RoleDefinitions[“Contribute”], but selecting it based on type will ensure it also works with SharePoint sites in different languages.

See MSDN for the possible values for a list’s ReadSecurity and WriteSecurity.

Count all lists and list items in a site collection

I was recently asked how to inventorize all lists and list items for all sites in a site collection.

Here’s a PowerShell script that does exactly that, displaying the SharePoint site and List name, with the number of items per list:

$ListsInfo = @{}
$TotalItems = 0
$SiteCollection = Get-SPSite "http://<<SiteCollectionURL>>/"
ForEach ($Site in $SiteCollection.AllWebs)
{
    ForEach ($List in $Site.Lists)
    {
        $ListsInfo.Add($Site.Url + " - " + $List.Title, $List.ItemCount)
        $TotalItems += $List.ItemCount
    }
}
$ListsInfo.GetEnumerator() | sort name | Format-Table -Autosize
Write-Host "Total number of Lists: " $ListsInfo.Count
Write-Host "Total number of ListItems: " $TotalItems
(To copy this code, double-click the anywhere in the code and press CTRL/Cmd+C to copy it)

Replace the http://<<SiteCollectionURL>>/ string with the URL for your site collection.

How to find the SharePoint Server 2010 version

In some cases, i.e. installing a language pack, it’s handy to know which version of SharePoint you’re running exactly.

One way is to use Central Administration, go to System SettingsManage servers in this farm.

Or you can use PowerShell:

(Get-SPFarm).buildversion

The most common build numbers are:

  • 14.0.4762.1000 – RTM
  • 14.0.6029.1000 – SP1
  • 14.0.6109.5000 / .5002 – August 2011 CU

For a full list of build numbers, see Todd Klindt’s SharePoint Admin Blog.

Step-by-step Forms-Based Authentication (FBA) on SharePoint 2010

This is an A-Z guide that helps you setup a web application with Forms-Based Authentication (FBA) in SharePoint Foundation 2010, using Claims-Based authentication. It uses MS SQL Server to store users. The SharePoint server is running in Windows Server 2008 R2. Although this guide uses SharePoint Foundation 2010, the same steps apply to SharePoint Server 2010.

In this guide, you’ll create a SQL Server database to hold users and roles, create a SharePoint Web Application that uses FBA, configure IIS and the web.config files for the Web App, Central Admin and the Security Token Service, create a test user in the database and test your setup.

Click here to read the entire article →

List of all databases used by a SharePoint 2010 farm

Someone recently asked me how to get a listing of databases used by a farm, with the server instance name and database names.

There are ways to retrieve this info from Central Administration, but PowerShell makes your life much easier:

Get-SPDatabase | select name, databaseconnectionstring

Where the Data Source element in the Connection String contains the exact DB server instance used by the farm.

Using SharePoint Powershell from PowerShell ISE

Whoever has worked with PowerShell probably came to the same conclusion: this stuff is potent and powerful!

The ‘standard’ SharePoint 2010 Management Shell does have some drawbacks.

Working with a Command-Prompt-like environment does not appeal to everyone, especially those used to visual IDE’s like Visual Studio. Fortunately, PowerShell v2 comes with PowerShell ISE, a more visual experience that makes it much easier to work with scripts. This is available by default on Windows 7 and can be enabled as a feature on Windows Server 2008, using the following PowerShell command:

Add-WindowsFeature PowerShell-ISE

You can now find PowerShell ISE shortcuts in the Start Menu.

However, when you start PowerShell ISE, you’ll find that it only works with Windows cmdlets. For PowerShell ISE to work with SharePoint cmdlets, you’ll only need to add a PowerShell Snapin, using the following command.

Add-PSSnapin Microsoft.SharePoint.PowerShell

After this, you’ll be able to access the SharePoint commandlets, whose noun all start with “sp”.

Now if you’re like me, you’ll always want these SharePoint cmdlets available from PowerShell ISE. Zubair Alexander posted a way of doing this earlier this year on his blog.

  1. You can check if a PowerShell profile is available for your current identity using the Test-Path $profile command. This will return true if a profile is present and false if not.
  2. You can create a new profile for your identity by using the following command:
    Test-Path $profile
    if (!(test-path $profile)) {new-item -type file -path $profile -force}

    This will perform a “Create Directory” operation on the target destination folder C:\Users\<username>\Documents\WindowsPowerShell, and add a file titled “Microsoft.PowerShellISE_profile.ps1” to this folder.

  3. Now, use PowerShell ISE to open the newly created .ps1 file
  4. Add the command
    Add-PSSnapIn Microsoft.SharePoint.PowerShell

    (and any other commands you want to automatically run when you open PowerShell ISE) to the file and press Save.

  5. Restart PowerShell ISE. You’ll now find you’ll be able to access all SharePoint cmdlets directly, each time you run PowerShell ISE on this machine.

Adding filters to System.Nullable types in BCS

It took me a while to find the solution for this problem, which was eventually handed to me by Dmitry Kaloshin, so I’ll share it here:

Filters in BCS are very handy, and often necessary, for reducing the amount of items when working with External Data, such as an External Data Column based on an External Content Type.

When you’re working with an external content type that has input parameters of the .NET Type System.Nullable<System.Int32>, you may run into the same problems I had.

A sample input parameter for a Read List operation, i.e. from a WCF Service, that has the System.Nullable .NET Type, may look like this:

Initial paramtere properties

If you’d want to add a Comparison filter for this input parameter, you’d probably set it up like this:

Comparison Filter

When you click OK, you’d see an Error message in the Errors and Warning list at the bottom of the page.

Error message with Filter on System.Nullable input parameter

The error reads “The filter field data type System.Nullable<System.Int32> does not match data type System.Int32 on data source element [[Element name]]“.

It seems like SharePoint BCS is unable to cope with Nullable Int .NET data types, which would be odd, as they’ve been around in the .NET Framework since version 2.0.

The solution is to set the Filter Field property of the Filter to <<none>>. Since the Filter Configuration dialog is started from the Element properties panel, the Element to filter is still linked to this filter.

Solution: Set Filter Field to None

Press OK to close the Dialog and press Finish to close the Read List dialog.

Save your changes to the Business Data Connectivity Metadata Store, and you’re done.

Changing the identity for a SharePoint 2010 Application Pool

There might be a situation where you want to alter the identity for the IIS application pool under which your SharePoint 2010 web applications are running.

You might be tempted to navigate to the IIS settings and alter the identity in there:

This is not recommended.

It’s best practice to run application pools under a domain user account, i.e. SP_ServiceApps. This account is best managed using Managed Accounts.

To change the identity for an application pool, log into Central Administration and follow these steps:

  1. Go to Security and under General Security, click Configure Service Accounts.
  2. Select the application pool from the components drop-down listbox (1)
  3. Select the managed account (2) that you want to use as
    the identity for this application pool, or register a new managed
    account in SharePoint 2010, using the Register a new managed account link.
  4. Click the OK button.
  5. You’ll be warned that this action requires an IIS reset on all servers, click OK.
  6. Perform a iisreset /noforce on all WFE servers in the farm.