Breaking Permissions Inheritance and Setting up new Permission Sets in SharePoint with PowerShell

The following snippet shows how you might create a new permission set in a subsite of SharePoint. One of the more common permission sets you might need in a production application is ‘restricted contribute’ – contribute without delete. This shows one method of doing that (there are many) – by duplicating the contribute permission set, minus the delete permission.

# Connect to SharePoint Site
$web = get-spweb "https://server/sites/site_collection/subsite"

# Break Inheritance for the subsite
$web.RoleDefinitions.BreakInheritance($false, $false) > $null
$web.Update() > $null

# Get the Contribute Definition
$contribute_role_definition = $web.RoleDefinitions["Contribute"]
$contribute_base_permissions = $contribute_role_definition.BasePermissions

# Delete the role definition if it exists
if ($web.RoleDefinitions["Restricted Contribute"]) {
    Write-Host " - Removing Existing Role Definition"
    $web.RoleDefinitions.Delete("Restricted Contribute")
    $web.Update()
}

# Create a new Role Definition, and copy the Base permissions minus Delete Items
$restricted_contribute_role_definition = New-Object Microsoft.SharePoint.SPRoleDefinition
$restricted_contribute_role_definition.BasePermissions = $contribute_base_permissions -bxor [Microsoft.SharePoint.SPBasePermissions]::DeleteListItems

# Set the name and description of the new role definition
$restricted_contribute_role_definition.Name = "Restricted Contribute"
$restricted_contribute_role_definition.Description = "Contribute without Delete Items"

# Apply the new role definition to the web
$web.RoleDefinitions.Add($restricted_contribute_role_definition);
$web.Update();

# Release Resources
$web.Close()
$web.Dispose()
Posted by Jonathan Beckett in Notes, 0 comments

Populating the QuickLaunch in SharePoint with PowerShell

The following snippet shows how you might re-write the contents of the Quick Launch within SharePoint on-prem. It’s pretty straightforward – just duplicate the parent and child lines for as many links as you need.

# Connect to Site
$web = get-spweb "https://server/sites/site_collection/subsite"

# Get the quicklaunch
$quicklaunch = $web.Navigation.QuickLaunch

# Remove all items in the quicklaunch
($quicklaunch | where {$_.Title -ne ""}).Delete() > $null

# Create a parent link
$navnode = New-Object Microsoft.SharePoint.Navigation.SPNavigationNode("Home", $web.Url, $false)
$parent_link = $quicklaunch.AddAsLast($navnode)

# Create a child link
$navnode = New-Object Microsoft.SharePoint.Navigation.SPNavigationNode("Link to a List", $($web.Url + "/lists/mylist"), $false)
$child_link = $parent_link.Children.AddAsLast($navnode)

# You can switch Quick Launch on and off entirely
$web.QuickLaunchEnabled = $true

# Write the changes to the web
$web.Update()

# Release resources
$web.Close()
$web.Update()
Posted by Jonathan Beckett in Notes, 0 comments

Creating List and Library Views in SharePoint with PowerShell

The code snippet below illustrates the creation of a view on a list. I generally leave the “All Items” views alone, and create new views to do anything specific for an application within SharePoint – it just makes life easier in the long run.

# Connect to SharePoint
$web = get-spweb "https://server/sites/site_collection/subsite"

# get the list to make a view
$list = $web.Lists["My List"]

$view_name = "My View"

# If the view already exists, remove it
if ($list.Views[$view_name] -ne $null){
    $view = $list.Views[$view_name]
    $list.Views.Delete($view.Id) > $null
    $list.Update() > $null
    $web.Update() > $null
}

# Create the view
$view_fields = New-Object System.Collections.Specialized.StringCollection
$view_fields.Add('LinkTitle') > $null
$view_fields.Add('Created') > $null
$view_fields.Add('Modified') > $null
$view_query = "<OrderBy><FieldRef Name='ID' Ascending='FALSE'/></OrderBy>"
$view_row_limit = 50
$view_paged = $true
$view_default = $true
$new_view = $list.Views.Add($view_name, $view_fields, $view_query, $view_row_limit, $view_paged, $view_default)

# Release Resources
$web.Close()
$web.Dispose()

Note that if you try to remove the only view existing on a list or library, it will fail – there must always be at least one view. Also note that fields must be identified by their internal names. Oh – finally – the view query is expressed in CAML – you can look that up elsewhere (it’s a special kind of hell).

Posted by Jonathan Beckett in Notes, 0 comments

Creating a Lookup Site Column on SharePoint with PowerShell

The following snippet creates a Lookup Site Column in SharePoint on-prem. Notice that the code checks for the existence of the site column before creating it – because typically you will be using this in a larger provisioning script, and it makes sense to let your code run more than once – so as you build a solution, you can just add new elements and run it again.

# Connect to SharePoint Site
$web = get-spweb "https://server/sites/sitecollection/site"

# Set Site Column name etc
$site_column_internal_name = "MySiteColumn"
$site_column_display_name  = "My Site Column"
$site_column_group         = "My Site Columns"
$site_column_description   = "Simple example of site column"

if ($web.Fields.ContainsField($site_column_internal_name)){

    # Get Existing Site Column
    $site_column = $web.Fields.GetField($site_column_internal_name)
 
} else {

    # Create new site column
    $lookup_list = $web.Lists["Title of Lookup List"]
    $web.Fields.AddLookup($site_column_internal_name,$lookup_list.ID,$false) > $null
    $field = $web.Fields.GetField($site_column_internal_name)
    $field.LookupField = $lookup_list.Fields["Title"]
    $field.Title = $site_column_display_name
    $field.Group = $site_column_group
    $field.Description = $site_column_description
    $field.Update() > $null
}

# instantiate field link object for field
$field_link = new-object Microsoft.SharePoint.SPFieldLink($field)

# add field link to existing content type
$content_type = $web.ContentTypes["My Content Type"]
$content_type.FieldLinks.Add($field_link) > $null
$content_type.Update() > $null

# release resources
$web.Close()
$web.Dispose()

Also notice that the site column will be provisioned in the web you connect to – but must be uniquely named across the entire site collection.

Posted by Jonathan Beckett in Notes, 0 comments

Creating a Multi Value Site Column in SharePoint with PowerShell

The following snippet creates a Multi Value Site Column in SharePoint on-prem. Notice that the code checks for the existence of the site column before creating it – because typically you will be using this in a larger provisioning script, and it makes sense to let your code run more than once – so as you build a solution, you can just add new elements and run it again.

# Connect to SharePoint Site
$web = get-spweb "https://server/sites/sitecollection/site"

# Set Site Column name etc
$site_column_internal_name = "MySiteColumn"
$site_column_display_name  = "My Site Column"
$site_column_group         = "My Site Columns"
$site_column_description   = "Simple example of site column"

if ($web.Fields.ContainsField($site_column_internal_name)){

    # Get Existing Site Column
    $site_column = $web.Fields.GetField($site_column_internal_name)
 
} else {

    # Create new site column
    $choices = New-Object System.Collections.Specialized.StringCollection
    $choices.Add("Yes") > $null
    $choices.Add("No") > $null
    $web.Fields.Add($site_column_internal_name,[Microsoft.SharePoint.SPFieldType]::Choice,$false,$false,$choices) > $null
    $field = $web.Fields.GetField($site_column_internal_name)
    $field.Title = $site_column_display_name
    $field.Group = $site_column_group
    $field.Description = $site_column_description
    $field.Update() > $null
}

# instantiate field link object for field
$field_link = new-object Microsoft.SharePoint.SPFieldLink($field)

# add field link to existing content type
$content_type = $web.ContentTypes["My Content Type"]
$content_type.FieldLinks.Add($field_link) > $null
$content_type.Update() > $null

# release resources
$web.Close()
$web.Dispose()

Also notice that the site column will be provisioned in the web you connect to – but must be uniquely named across the entire site collection.

Posted by Jonathan Beckett in Notes, 0 comments

Creating a Currency Site Column in SharePoint with PowerShell

The following snippet creates a Currency Site Column in SharePoint on-prem. Notice that the code checks for the existence of the site column before creating it – because typically you will be using this in a larger provisioning script, and it makes sense to let your code run more than once – so as you build a solution, you can just add new elements and run it again.

#Connect to SharePoint Site
$web = get-spweb "https://server/sites/sitecollection/site"

# Set Site Column name etc
$site_column_internal_name = "MySiteColumn"
$site_column_display_name  = "My Site Column"
$site_column_group         = "My Site Columns"
$site_column_description   = "Simple example of site column"

if ($web.Fields.ContainsField($site_column_internal_name)){

    # Get Existing Site Column
    $site_column = $web.Fields.GetField($site_column_internal_name)
 
} else {

    # Create new site column
    $web.Fields.Add($site_column_internal_name, "Currency", $false) > $null
    $field = $web.Fields.GetField($site_column_internal_name)
    $field.Title = $site_column_display_name
    $field.Group = $site_column_group
    $field.Description = $site_column_description
    $field.Currency = [Microsoft.SharePoint.SPCurrencyFieldFormats]::EuropeanUnion2;
    $field.DisplayFormat = [Microsoft.SharePoint.SPNumberFormatTypes]::TwoDecimals;
    $field.Update() > $null
}

# instantiate field link object for field
$field_link = new-object Microsoft.SharePoint.SPFieldLink($field)

# add field link to existing content type
$content_type = $web.ContentTypes["My Content Type"]
$content_type.FieldLinks.Add($field_link) > $null
$content_type.Update()

# release resources
$web.Close()
$web.Dispose()

Also notice that the site column will be provisioned in the web you connect to – but must be uniquely named across the entire site collection. Also note that the currency, and format are based on enumerations (look them up on MSDN for the various different currencies).

Posted by Jonathan Beckett in Notes, 0 comments

Creating a Multi Line Text Site Column in SharePoint with PowerShell

The following snippet creates a Multi Line Text Site Column in SharePoint on-prem. Notice that the code checks for the existence of the site column before creating it – because typically you will be using this in a larger provisioning script, and it makes sense to let your code run more than once – so as you build a solution, you can just add new elements and run it again.

# Connect to SharePoint Site
$web = get-spweb "https://server/sites/sitecollection/site"

# Set Site Column name etc
$site_column_internal_name = "MySiteColumn"
$site_column_display_name  = "My Site Column"
$site_column_group         = "My Site Columns"
$site_column_description   = "Simple example of site column"

if ($web.Fields.ContainsField($site_column_internal_name)){

    # Get Existing Site Column
    $site_column = $web.Fields.GetField($site_column_internal_name)
 
} else {

    # Create new site column
    $web.Fields.Add($site_column_internal_name, "Note", $false) > $null
    $field = $web.Fields.GetField($site_column_internal_name)
    $field.Title = $site_column_display_name
    $field.Group = $site_column_group
    $field.Description = $site_column_description
    $field.Update() > $null
}

# instantiate field link object for field
$field_link = new-object Microsoft.SharePoint.SPFieldLink($field)

# add field link to existing content type
$content_type = $web.ContentTypes["My Content Type"]
$content_type.FieldLinks.Add($field_link) > $null

# release resources
$web.Close()
$web.Dispose()

Also notice that the site column will be provisioned in the web you connect to – but must be uniquely named across the entire site collection.

Posted by Jonathan Beckett in Notes, 0 comments

Create a Single Line Text Site Column in SharePoint with PowerShell

The following snippet creates a Text Site Column in SharePoint on-prem. Notice that the code checks for the existence of the site column before creating it – because typically you will be using this in a larger provisioning script, and it makes sense to let your code run more than once – so as you build a solution, you can just add new elements and run it again.

# Connect to SharePoint Site
$web = get-spweb "https://server/sites/sitecollection/site"

# Set Site Column name etc
$site_column_internal_name = "MySiteColumn"
$site_column_display_name  = "My Site Column"
$site_column_group         = "My Site Columns"
$site_column_description   = "Simple example of site column"

if ($web.Fields.ContainsField($site_column_internal_name)){

    # Get Existing Site Column
    $site_column = $web.Fields.GetField($site_column_internal_name)
 
} else {

    # Create new site column
    $web.Fields.Add($site_column_internal_name, "Text", $false) > $null
    $field = $web.Fields.GetField($site_column_internal_name)
    $field.Title = $site_column_display_name
    $field.Group = $site_column_group
    $field.Description = $site_column_description
    $field.Update() > $null
}

# instantiate field link object for field
$field_link = new-object Microsoft.SharePoint.SPFieldLink($field)

# add field link to existing content type
$content_type = $web.ContentTypes["My Content Type"]
$content_type.FieldLinks.Add($field_link) > $null

# release resources
$web.Close()
$web.Dispose()

Also notice that the site column will be provisioned in the web you connect to – but must be uniquely named across the entire site collection.

Posted by Jonathan Beckett in Notes, 0 comments

Create a User or Group Site Column in SharePoint with PowerShell

The following snippet creates a User Site Column in SharePoint on-prem. Notice that the code checks for the existence of the site column before creating it – because typically you will be using this in a larger provisioning script, and it makes sense to let your code run more than once – so as you build a solution, you can just add new elements and run it again.

# Connect to SharePoint Site
$web = get-spweb "https://server/sites/sitecollection/site"

# Set Site Column name etc
$site_column_internal_name = "MySiteColumn"
$site_column_display_name  = "My Site Column"
$site_column_group         = "My Site Columns"
$site_column_description   = "Simple example of site column"

if ($web.Fields.ContainsField($site_column_internal_name)){

    # Get Existing Site Column
    $site_column = $web.Fields.GetField($site_column_internal_name)
 
} else {

    # Create new site column
    $web.Fields.Add($site_column_internal_name, "User", $false) > $null
    $field = $web.Fields.GetField($site_column_internal_name)
    $field.Title = $site_column_display_name
    $field.Group = $site_column_group
    $field.Description = $site_column_description
    $field.AllowMultipleValues = $true
    $field.SelectionMode = [Microsoft.SharePoint.SPFieldUserSelectionMode]::PeopleAndGroups
    $field.Update() > $null
}

# instantiate field link object for field
$field_link = new-object Microsoft.SharePoint.SPFieldLink($field)

# add field link to existing content type
$content_type = $web.ContentTypes["My Content Type"]
$content_type.FieldLinks.Add($field_link) > $null

# release resources
$web.Close()
$web.Dispose()

Also notice that the site column will be provisioned in the web you connect to – but must be uniquely named across the entire site collection.

Posted by Jonathan Beckett in Notes, 0 comments

Creating SharePoint Content Types with PowerShell

The following snippet creates a Content Type in SharePoint on-prem. Notice that the code checks for the existence of the content type before creating it – because typically you will be using this in a larger provisioning script, and it makes sense to let your code run more than once – so as you build a solution, you can just add new elements and run it again.

# Connect to SharePoint Site
$web = Get-SPWeb "https://server/sites/sitecollection/subsite"

# Set Content Type name and group
$content_type_name = "My Content Type"
$content_type_group = "My Content Types"

if ($web.ContentTypes[$content_type_name]){
    
    # get the existing content type
    $content_type = $web.ContentTypes[$content_type_name]

} else {
    
    # create a new content type
    $content_type_parent = $web.AvailableContentTypes["Item"]
    $content_type = new-object Microsoft.SharePoint.SPContentType($content_type_parent, $web.ContentTypes, $content_type_name)
    $content_type.Group = $content_type_group
    $web.ContentTypes.Add($content_type) > $null
    $content_type = $web.ContentTypes[$content_type_name]
}

# Release resources
$web.Close()
$web.Dispose()

Also notice that the content type will be provisioned in the web you connect to – but must be uniquely named across the entire site collection.

Posted by Jonathan Beckett in Notes, 0 comments