Sunday, 26 February 2012

Managing, creating and deleting SharePoint list views with PowerShell

Due to the number of configuration options available, manipulating list views through PowerShell can be quite involved and I certainly wouldn’t recommend it if you only have a few lists to change. However, when there are a large number of views and lists involved, PowerShell can significantly reduce the amount of time needed to manage and configure them.

Manage List Views

The first stage is looking at the commands to manage available views on a list. For this example, I am going to get the “Shared Documents” document library from a root site and assign it to a variable called $list:

$web = Get-SPWeb http://portal
$list = $web.GetList(($web.ServerRelativeUrl.TrimEnd("/") + "/Shared Documents"))

To find the title and URL of the current default view, type the following command:

$list.DefaultView | select Title, Url

DefaultView

If you want to show one of the non-default views then you can call it with the display name, as follows:

$list.Views["Test View"]

To change the default view for the list, type the following set of commands for the view you want to configure as the new default:

$view = $list.Views["Test View"]
$view.DefaultView = $true
$view.Update()

Create New List Views

The easiest way to create a list view using PowerShell is to create one in the UI first with all the settings you need. You can then use the properties of the view you have created to define the parameters required for the view creation script we use later in this section.

For this example, I have created a new view called “Sort by modified date”, which is effectively the same as the default “All Documents” view but with the items ordered by modified date in descending order. I have also added the “File Size” column to the view and specified a limit of 50 items per page.

Once this is done, type the following set of commands to display the properties of the new view:

$web = Get-SPWeb http://portal
$list = $web.GetList(($web.ServerRelativeUrl.TrimEnd("/") + "/Shared Documents"))
$newview = $list.Views["Sort by modified date"]
$newview

ViewPropertiesAndValues

You should now see a long list of property names and associated values for this view, including Title, Query, RowLimit and ViewFields (i.e., columns). You can also take a look at the value of any one of these properties individually by typing $newview.PropertyName and hitting Enter. For example, to get a full list of ViewFields, type $newview.ViewFields.

When creating the view in PowerShell, you will need to use some of these properties as mandatory parameters in the script. These mandatory properties are listed below:

Property Name Description How it looks in the UI
Title Display name of the view in the UI image
ViewFields The columns you wish to show in the view image
Query The CAML query used to sort and filter list items in the view image
RowLimit The number of items shown per page image
Paged Used with the RowLimit to either display the number of items in batches ($true) or limit the number of items shown in total ($false) image
DefaultView The default view for the list being configured ($true or $false) image

You can now start writing the script to create the view in another list. The example below creates the view with the parameters shown in the UI examples above into the Shared Documents library on the site http://portal/sites/testsite. The values were simply copied from the property list displayed using the script earlier in this section:

#Get destination site and list
$web = Get-SPWeb "http://portal/sites/testsite"
$list = $web.GetList(($web.ServerRelativeUrl.TrimEnd("/") + "/Shared Documents"))

$viewTitle = "Sort by modified date" #Title property
#Add the column names from the ViewField property to a string collection
$viewFields = New-Object System.Collections.Specialized.StringCollection
$viewFields.Add("DocIcon") > $null
$viewFields.Add("LinkFilename") > $null
$viewFields.Add("Modified") > $null
$viewFields.Add("Editor") > $null
$viewFields.Add("FileSizeDisplay") > $null
#Query property
$viewQuery = "<OrderBy><FieldRef Name='Modified' Ascending='FALSE'/></OrderBy>"
#RowLimit property
$viewRowLimit = 50
#Paged property
$viewPaged = $true
#DefaultView property
$viewDefaultView = $false

#Create the view in the destination list
$newview = $list.Views.Add($viewTitle, $viewFields, $viewQuery, $viewRowLimit, $viewPaged, $viewDefaultView)
Write-Host ("View '" + $newview.Title + "' created in list '" + $list.Title + "' on site " + $web.Url)
$web.Dispose()

You may have a requirement to add this list view to the “Shared Documents” library on every site in a site collection. To do this, we need to wrap the Add method in a ForEach-Object condition for every site in a specified site collection. This script will also report an issue if the Shared Documents library does not exist on one or more sites:

#Title property
$viewTitle = "Sort by modified date"
#Add the column names from the ViewField property to a string collection
$viewFields = New-Object System.Collections.Specialized.StringCollection
$viewFields.Add("DocIcon") > $null
$viewFields.Add("LinkFilename") > $null
$viewFields.Add("Modified") > $null
$viewFields.Add("Editor") > $null
$viewFields.Add("FileSizeDisplay") > $null
#Query property
$viewQuery = "<OrderBy><FieldRef Name='Modified' Ascending='FALSE'/></OrderBy>"
#RowLimit property
$viewRowLimit = 50
#Paged property
$viewPaged = $true
#DefaultView property
$viewDefaultView = $false

#Get the site collection
Get-SPSite "http://portal/sites/testsite" | Get-SPWeb -Limit All | ForEach-Object {
    $webUrl = $_.Url
    try
    {
        #Get the Shared Documents library
        $list = $_.GetList(($_.ServerRelativeUrl.TrimEnd("/") + "/Shared Documents"))
       
        #Create the view in the destination list
        $newview = $list.Views.Add($viewTitle, $viewFields, $viewQuery, $viewRowLimit, $viewPaged, $viewDefaultView)
        Write-Host ("View '" + $newview.Title + "' created in list '" + $list.Title + "' on site " + $webUrl)
    }
    catch
    {
        Write-Host ("There was a problem trying to create the view in the site " + $webUrl + ": " + $_)
    }
}

By the way, if you create a new view with the same title as one that already exists on a list, it will create an extra view in that list with the same title – not overwrite the previous one.

Modify Existing List Views

The scripts above create list views with a limited set of mandatory properties, but there are probably some extra properties that you will also want to set on views. As mentioned earlier, to help you decide which settings you need to configure on a view using PowerShell, create a view in the UI first and list its properties and values by running this script:

$web = Get-SPWeb http://portal
$list = $web.GetList(($web.ServerRelativeUrl.TrimEnd("/") + "/Shared Documents"))
$newview = $list.Views["Sort by modified date"]
$newview

For a full description of the properties and methods available for configuring views, please see this article on MSDN. Once you have decided which properties you wish to set, look up the values of the view you created in the UI and use this script to modify a view’s settings using PowerShell. In this example, we will be changing the “Sort by modified date” view configured on the Shared Documents library in site http://portal/sites/testsite so that it can be accessed as a mobile view and is set as the default mobile view for the list:

#Get the site and list
$web = Get-SPWeb "http://portal/sites/testsite"
$list = $web.GetList(($web.ServerRelativeUrl.TrimEnd("/") + "/Shared Documents"))
#Get the list view to be changed
$newview = $list.Views["Sort by modified date"]
#Set the mobile and default mobile view properties
$newview.MobileView = $true
$newview.MobileDefaultView = $true
#Update the view configuration
$newview.Update()
$web.Dispose()

Delete List Views

Finally, here is a script to delete a list view. The obvious thing to mention here is being careful not to delete the default view on a list, or if you want to, ensure that you change the default view to another one first before doing so. The name of the view we are going to delete in this example is “Sort by modified date” in the Shared Documents library on site http://portal/sites/testsite:

#Get the site and list
$web = Get-SPWeb "http://portal/sites/testsite"
$list = $web.GetList(($web.ServerRelativeUrl.TrimEnd("/") + "/Shared Documents"))
#Get the list view to be changed
$newview = $list.Views["Sort by modified date"]
#Delete this view from the list
$list.Views.Delete($newview.ID)
$web.Dispose()

20 comments:

  1. Awesome stuff as always, Phil. You've saved me considerable time as this was coming onto my radar as a definite gap in our automated builds. Cheers!

    ReplyDelete
  2. Nice one Phil. Good clear instructions that made it easy to alow me to design and build the script I needed to make some changes.
    Cheers.
    Patrick.

    ReplyDelete
  3. hello first of all great post
    i tried ur script and it worked like a charm.
    i changed the query
    $viewQuery = "








    "
    i off course have an id column in my list.
    the script no longer works.
    what am i doing wrong ??
    Thank u for ur help :)

    ReplyDelete
  4. Hi Phil,

    We are just getting started with PS to manage SharePoint. Our team is under the impression that in order to do the management of lists/meta-data, we would have to give an account such high level of privileges on the server it would leave a hole open for exploitation.

    Can you speak to this, or provide some insight as to how we could reduce our exposure while utilizing these techniques? - Thanks!

    ReplyDelete
    Replies
    1. I don't think using SPFarmAD or similar leads to weakness. It is as secure as your NAT firewall makes your intranet. Then the hacker would need to know the password etc. Seems fine. If you run timer jobs you almost have to use SPFarm type accounts because these are the only ones which have the access required to run automatically.

      Delete
  5. Thanks for Great post.. It saved lots of Time

    ReplyDelete
  6. Great post. I wonder if you know how we might be able to copy an existing view from one list in a site collection to another list in the same site collection that is identical using powershell.
    Thanks

    ReplyDelete
  7. I'm trying to use the delete view script to go through an entire collection of sites and subsites, but keep encountering the error: "Collection was modified; enumeration operation may not execute."

    It will delete the first match found and then "not find" any other instances even though they are present.
    I have tried collecting all of the view ID's and placing them into an array and then process the delete at the end, but the data does not seem to populate into the array.

    Structure is basically: pass collection URL into function that checks for matching lists and libraries on the site. Matching lists and libraries then calls another function to delete the any views that match the specified name.

    Any advice on how to apply this script for every site\subsite?

    ReplyDelete
    Replies
    1. You need to use a For each site in farm type of loop. e.g

      $site = Get-SPSite -identity
      foreach ($web in $site.AllWebs) {

      $Libraries = $web.Lists | where {$_.BaseType -eq "DocumentLibrary"}

      Delete
  8. Great article! How do I set the display order number for each field? Thanks.

    ReplyDelete
  9. Wow really I liked this blog your explanation about Managing, creating and deleting SharePoint list views with PowerShell is good.
    SharePoint 2013 Online Training

    ReplyDelete
  10. i want only personal views of all users, per list. how do i achieve this?

    ReplyDelete
  11. I have discussion board list and in view there is folders property. I want to set to to top level. Please help.

    ReplyDelete