The following script was written to organize list items into yearly folders, e.g. 2012, 2013 etc. based on a list item's created date and status (using a CAML query). The script also captures an item's modified by date and modified by user and resets these values once the item is moved.
Background
Though we typically avoid using folders and rely on metadata, we had to use folders to deal with the 5,000 item list items threshold. At first, we tried creating views that were filtered by indexed columns, and though this helped when viewing data, we still ran into the list threshold issue when attempting to further filter items using the view column filters. Also, we did not want to override the list threshold in Central Admin given potential performance implications (and it's not recommended!). Using folders solved this issue for us.
# Script to move list items to Year sub folders, e.g. 2012, 2013.
# Add SharePoint PowerShell Snap-in if missing
if((Get-PSSnapin | Where {$_.Name -eq "Microsoft.SharePoint.PowerShell"}) -eq $null) {
Add-PSSnapin Microsoft.SharePoint.PowerShell;
}
Start-SPAssignment -Global
# Get Site
$Site = Get-SPSite -Identity "<Site Collection URL>";
## Get Web
$Web = $Site.OpenWeb("<Web Name>");
## Get List
$List = $Web.Lists["<List Name>"];
## Initialize Counts
$Count = 0;
$ErrorCount = 0;
## Set Query
$Query = New-Object Microsoft.SharePoint.SPQuery;
$Query.Folder = $List.RootFolder;
$camlQuery = "<CAML Query>";
$Query.Query = $camlQuery;
$Query.RowLimit = 10;
# Get all list items that match the query and where the item content type is not a folder
$List.GetItems($Query) | Where {$_.ContentType.Name -ne "Folder"} | foreach-object {
# Get the data we need to work with and update
$ItemID = $_["ID"];
$ItemTitle = $_["Title"];
$Year = ([System.DateTime] $_["Created"]).Year;
$ModifiedDate = [System.DateTime] $_["Modified"];
$ModifiedBy = New-Object Microsoft.SharePoint.SPFieldUserValue($Web, [string]$_["Modified By"]);
$ListPath = $Web.ServerRelativeUrl + "/" + $List.RootFolder.Url + "/";
$FolderPath = $ListPath + $Year;
$Folder = $Web.GetFolder($FolderPath);
# Create the Year folder if it does not already exist
if (-not $Folder.Exists)
{
$Folder = $List.Folders.Add("", [Microsoft.SharePoint.SPFileSystemObjectType]::Folder, $Year);
$Folder.Update();
}
Write-Host ("Moving: " + $ItemTitle);
# Try moving the file to the subfolder setting the modified and modified date fields
Try
{
$Web.GetFile($_.Url).MoveTo([System.String]::format("{0}/{1}", $Folder, $ItemID.ToString()+"_.000"));
$Count = $Count + 1;
$ListItem = $List.GetItemByID($ItemID);
$ListItem["Editor"] = $ModifiedBy;
$ListItem["Modified"] = $ModifiedDate;
$ListItem.Update();
}
Catch [system.exception]
{
$ErrorCount = $ErrorCount + 1;
Write-Error ("Error moving file: " + $ItemTitle);
}
};
Write-Host ("`n" + $Count.ToString() + " items moved.");
if ($ErrorCount -gt 0)
{
Write-Host ("`n" + $ErrorCount.ToString() + " errors.");
}
Stop-SPAssignment -Global
Move documents into folders in the same library using PowerShell
Move listitems programatically to sub folder in sharepoint 2010
Move SharePoint List Item (SPListItem) To Sub Folder
Script
# Script to move list items to Year sub folders, e.g. 2012, 2013.
# Add SharePoint PowerShell Snap-in if missing
if((Get-PSSnapin | Where {$_.Name -eq "Microsoft.SharePoint.PowerShell"}) -eq $null) {
Add-PSSnapin Microsoft.SharePoint.PowerShell;
}
Start-SPAssignment -Global
# Get Site
$Site = Get-SPSite -Identity "<Site Collection URL>";
## Get Web
$Web = $Site.OpenWeb("<Web Name>");
## Get List
$List = $Web.Lists["<List Name>"];
## Initialize Counts
$Count = 0;
$ErrorCount = 0;
## Set Query
$Query = New-Object Microsoft.SharePoint.SPQuery;
$Query.Folder = $List.RootFolder;
$camlQuery = "<CAML Query>";
$Query.Query = $camlQuery;
$Query.RowLimit = 10;
# Get all list items that match the query and where the item content type is not a folder
$List.GetItems($Query) | Where {$_.ContentType.Name -ne "Folder"} | foreach-object {
# Get the data we need to work with and update
$ItemID = $_["ID"];
$ItemTitle = $_["Title"];
$Year = ([System.DateTime] $_["Created"]).Year;
$ModifiedDate = [System.DateTime] $_["Modified"];
$ModifiedBy = New-Object Microsoft.SharePoint.SPFieldUserValue($Web, [string]$_["Modified By"]);
$ListPath = $Web.ServerRelativeUrl + "/" + $List.RootFolder.Url + "/";
$FolderPath = $ListPath + $Year;
$Folder = $Web.GetFolder($FolderPath);
# Create the Year folder if it does not already exist
if (-not $Folder.Exists)
{
$Folder = $List.Folders.Add("", [Microsoft.SharePoint.SPFileSystemObjectType]::Folder, $Year);
$Folder.Update();
}
Write-Host ("Moving: " + $ItemTitle);
# Try moving the file to the subfolder setting the modified and modified date fields
Try
{
$Web.GetFile($_.Url).MoveTo([System.String]::format("{0}/{1}", $Folder, $ItemID.ToString()+"_.000"));
$Count = $Count + 1;
$ListItem = $List.GetItemByID($ItemID);
$ListItem["Editor"] = $ModifiedBy;
$ListItem["Modified"] = $ModifiedDate;
$ListItem.Update();
}
Catch [system.exception]
{
$ErrorCount = $ErrorCount + 1;
Write-Error ("Error moving file: " + $ItemTitle);
}
};
Write-Host ("`n" + $Count.ToString() + " items moved.");
if ($ErrorCount -gt 0)
{
Write-Host ("`n" + $ErrorCount.ToString() + " errors.");
}
Stop-SPAssignment -Global
References
Referred to the following links:Move documents into folders in the same library using PowerShell
Move listitems programatically to sub folder in sharepoint 2010
Move SharePoint List Item (SPListItem) To Sub Folder
No comments:
Post a Comment