
Everyone knows how to create lists via the web browser, but for developers it can often be easier and more controlled to use automation to create lists on target SharePoint sites, for custom solutions they are developing, and the easiest way to do that is often using PowerShell.
Both the approaches below use PowerShell, with one being fully defined in the script itself and the second making use of XML templates.
The advantage of the all-code approach is that developers can be sure of what is being created, including internal field names, etc. for the most part.
The advantage of the templated approach is that a generic PowerShell script can be used with individual XML templates that describe the list specifications, so the authoring task is reduced to just the XML files.
Full Script-Based Approach
The following script demonstrates how lists can be defined and created entirely in PowerShell, with comments and explanations provided inline in the script itself:
# Using script command-line parameters to make things easier!
param (
[Parameter(Mandatory=$true)][string]$WebUrl,
[Parameter(Mandatory=$false)][string]$Name="MyList"
)
Add-PSSnapin Microsoft.SharePoint.PowerShell -EA SilentlyContinue
Start-SPAssignment –Global
$ErrorActionPreference = "Stop"
# Create the list. (If Custom List isn't the correct base-type for you, change that parameter value as appropriate.)
$web = Get-SPWeb -Identity $WebUrl
$web.Lists.Add($Name, $Name, "Custom List")
# Get the newly created list.
$path = $web.Url.Trim()
$list = $web.GetList("$path/Lists/$Name")
# Add fields to the list using the $list.Fields.Add() method.
# One of these two prototypes will be used in most cases:
# (Default) $list.Fields.Add(string strDisplayName, SPFieldType type, bool bRequired)
# (Choice) $list.Fields.Add(string strDisplayName, SPFieldType type, bool bRequired, bool bCompactName, StringCollection choices)
# Define options for a choice field.
$options = New-Object System.Collections.Specialized.StringCollection
$options.Add("Choice1") | Out-Null # Out-Null stops console output of count
$options.Add("Choice2") | Out-Null
# Add the choice field to the list.
$list.Fields.Add("MyChoiceField", [Microsoft.SharePoint.SPFieldType]::Choice, $true, $false, $options)
$field = $list.Fields.GetField("MyChoiceField")
# Change a few parameters of the field. (In this case, requiring that the field has unique values.)
$field.Indexed = true;
$field.EnforceUniqueValues = true;
# Update the field to reflect the changes made.
$field.Update()
# Add a numeric field.
$list.Fields.Add("MyNumber", [Microsoft.SharePoint.SPFieldType]::Number, $false)
$field = $null # Just being extra careful we don't accidentally update the choice field
$field = $list.Fields.GetField("MyNumber")
$field.DisplayFormat = [Microsoft.SharePoint.SPNumberFormatTypes]::NoDecimal
$field.Update()
$list.Update()
$web.Dispose()
Stop-SPAssignment –Global
Code language: PowerShell (powershell)
As you can see from the above script it is relatively easy to create a custom list, add some metadata fields and configure their extended options.
Scripts With XML Template(s)
param (
[Parameter(Mandatory=$true)][string]$WebUrl, # The URL of the target
[Parameter(Mandatory=$true)][string]$Name, # The name of the new list
[Parameter(Mandatory=$false)][string]$Spec="Template.xml",
[Parameter(Mandatory=$false)][string]$ListType="Custom List",
[Parameter(Mandatory=$false)][bool]$HideTitle=$false # Controls if the Title field is hidden
)
Add-PSSnapin Microsoft.SharePoint.PowerShell -EA SilentlyContinue
Start-SPAssignment –Global
$ErrorActionPreference = "Stop"
if ($ListType-eq $null -or $ListType.Trim() -eq "")
{
$ListType = "Custom List"
}
$web = Get-SPWeb -Identity $WebUrl
$listTemplate = $web.ListTemplates[$ListType]
$web.Lists.Add($Name, $Name, $listTemplate)
$path = $web.Url.Trim()
$list = $web.GetList("$path/Lists/$Name")
# Remove the Title field from the default view!
if ($HideTitle -eq $true) {
$title = $list.Fields.GetField("Title")
$title.Required = $false
$title.Hidden = $true
$title.Update()
$view = $list.Views["All Items"]
if ($view.ViewFields.Exists("LinkTitle")) {
$view.ViewFields.Delete("LinkTitle")
}
$view.Update()
}
$templateXml = [xml](Get-Content $Spec)
ForEach ($node in $templateXml.Template.Field) {
$list.Fields.AddFieldAsXml($node.OuterXml, $true,[Microsoft.SharePoint.SPAddFieldOptions]::AddFieldToDefaultView)
}
$list.Update()
$web.Dispose()
Stop-SPAssignment -Global
Code language: PowerShell (powershell)
The list template XML file follows the standard XML Schema for SharePoint fields. Take a look at this Microsoft article for more information.
Here’s an example template, specifying a list with two fields:
<?xml version="1.0" encoding="utf-8"?>
<Template>
<Field Type="Text" DisplayName="Name" Required="False" MaxLength="255" StaticName="Name" Name="Name" />
<Field Type="Number" DisplayName="Telephone No." Required="False" MaxLength="18" StaticName="Telephone" Name="Telephone" />
<Field Type="DateTime" DisplayName="Date of Birth" Required="False" StaticName="BirthDate" Name="BirthDate" />
<Field Type="Choice" DisplayName="Gender" Required="False" Format="Dropdown" FillInChoice="False" StaticName="Gender" Name="Gender">
<Default>Male</Default>
<CHOICES>
<CHOICE>Male</CHOICE>
<CHOICE>Female</CHOICE>
<CHOICE>Other</CHOICE>
</CHOICES>
</Field>
</Template>
Code language: HTML, XML (xml)