(this applies to MOSS / WSS 2007) Scroll to the bottom for a script that will work with SharePoint 2010.
How do you move all the fires from library A to library B?
Easy answer is to open both libraries in Explorer View and copy them over.
Doing this is quick and easy, but your metadata will be lost (if you care).
In my case I had to maintain the metadata when moving a bunch of files to a library in another site.
[System.Reflection.Assembly]::LoadWithPartialName(”Microsoft.SharePoint”) $siteUrl = "http://sharepoint" $webName = "" $spSite = new-object Microsoft.SharePoint.SPSite($siteurl) $spWeb = $spSite.OpenWeb($webName) $spList = $spWeb.Lists["Documents"] $listItems = $spList.Items $listTotal = $listItems.Count for ($x=$listTotal-1;$x -ge 0; $x--) { try { $listItems[$x].CopyTo("http://sharepoint/Docs/Documents/"+ $listItems[$x].name) Write-Host("DELETED: " + $listItems[$x].name) $listItems[$x].Recycle() } Catch { Write-Host $_.Exception.ToString() } } $spSite.Dispose $spWeb.Dispose$listItems[$x].Recycle() can be replaced with $listItems[$x].Delete()
I wanted to move the items to the Recycle Bin for safe keeping.If the file already exists in the destination library, the file will not be moved or deleted.
*if you wanted to deal with this scenario, you could simply create a new file name in the Catch event, and copy the file over.*Foreach does not work if are wanting to loop through the library and delete items.
UPDATE
In this example, I’m using a CAML query to find all documents created before 01/01/2014. This example will also process the items in batches, cutting down on server load. When working with CAML queries, be mindful of the ‘ and ” characters.
$web = Get-SPWeb "http://sharepointed.com/" $list = $web.Lists["Shared Documents"] $spQuery = New-Object Microsoft.SharePoint.SPQuery $spQuery.ViewAttributes = "Scope='Recursive'"; $spQuery.RowLimit = 2000 $caml = '<Where><Lt><FieldRef Name="Created" /><Value IncludeTimeValue="TRUE" Type="DateTime">2014-01-01T04:06:45Z</Value></Lt></Where> ' $spQuery.Query = $caml do { $listItems = $list.GetItems($spQuery) $spQuery.ListItemCollectionPosition = $listItems.ListItemCollectionPosition $listTotal = $listItems.Count for ($x=$listTotal-1;$x -ge 0; $x--) { try { $listItems[$x].CopyTo("http://sharepoint/Docs/Documents/"+ $listItems[$x].name) Write-Host("DELETED: " + $listItems[$x].name) $listItems[$x].Recycle() } catch { Write-Host $_.Exception.ToString() } } } while ($spQuery.ListItemCollectionPosition -ne $null)
Great script!
Is there an easy way to put in a date delay? For example, only delete/move items greater than X days.
David,
The post below will get you in the write track.
link
You would want to add something like this:
$y = ((Get-Date) – $listItems[$x].Created).Days
if ($y -gt 90)
{Delete or move documents code would go here}
The script is saying, if your date difference is greater than 90, do something.
Hi Ian,
Very useful script. How would one modify it for SP2010 including that date range filter?
Thanks.
shilezi, you can try something like this:
# if needed, add SP snapin
$web = Get-SPWeb “http://sharepoint”
$list = $web.Lists[“Shared Documents”]
foreach($item in $list.items)
{
if($item[“Modified”] -gt ‘3/1/2014’ -AND $item[“Modified”] -lt ‘4/1/2014’)
{
Write-Host $item[“Name”]
}
}
The script I provided is a simple example, but doing a CAML query to get the list items is better answer.
PowerShell Conditional Logic: http://www.powershellpro.com/powershell-tutorial-introduction/powershell-tutorial-conditional-logic/
Also, if you are dealing with a large list / library, you want to process items in batch. Example:
http://blogs.msdn.com/b/kaevans/archive/2012/02/13/iterating-large-sharepoint-lists-with-powershell.aspx
Thanks Ian,
Tried to modify using some of the suggestions but im stuck on an error.
Add-PSSnapin Microsoft.SharePoint.PowerShell -erroraction SilentlyContinue
$web = Get-SPWeb “http://mysite.com”
$list = $web.Lists[“aSource”]
$spQuery = New-Object Microsoft.SharePoint.SPQuery
$spQuery.ViewAttributes = “Scope=’Recursive'”;
$spQuery.RowLimit = 2000
$caml=’
2014-01-01T00:00:00Z
‘
$spQuery.Query = $caml
do
{
$listItems = $list.GetItems($spQuery)
$spQuery.ListItemCollectionPosition = $listItems.ListItemCollectionPosition
foreach($item in $listItems.items)
{
try
{
$listItems.CopyTo(“http://mysite.com/aDestination/”+ $listItems.name)
Write-Host(“DELETED: ” + $listItems.name + ” from $listItems”)
$listItems.Recycle()
}
Catch
{
Write-Host $_.Exception.ToString()
}
}
}
while ($spQuery.ListItemCollectionPosition -ne $null)
Heres my error.
System.Management.Automation.RuntimeException: Method invocation failed because [Microsoft.SharePoint.SPListItemCollection] doesn’t contain a method named ‘MoveTo’.
at System.Management.Automation.ParserOps.CallMethod(Token token, Object target, String methodName, Object[] paramArray, Boolean callStatic, Object valueToSet)
at System.Management.Automation.MethodCallNode.InvokeMethod(Object target, Object[] arguments, Object value)
at System.Management.Automation.MethodCallNode.Execute(Array input, Pipe outputPipe, ExecutionContext context)
at System.Management.Automation.ParseTreeNode.Execute(Array input, Pipe outputPipe, ArrayList& resultList, ExecutionContext context)
at System.Management.Automation.StatementListNode.ExecuteStatement(ParseTreeNode statement, Array input, Pipe outputPipe, ArrayList& resultList, ExecutionContext context)
Basically, your initial method is preferable for me since it copies the metadata but i also have like 20k files to archive based on their created date.
Your help is appreciated.
Thanks.
Dunno why the caml didnt come out looking like this on my previous comment
$caml=’
2014-01-01T00:00:00Z
‘
sorry for posting over and over, just realized the reply does not take indentation. Heres the caml query part
$caml=’2014-01-01T00:00:00Z’
happened again! maybe its the tags it didnt like, my apologies. took a screenshot
http://imgur.com/sYZOnti
shilezi, I updated the blog post to include a working example.
In your script, you are trying to move all them items when you use $listItems.CopyTo. You should be using $item.CoptTo.
$listItems is a collection of the items returned from the query.
Using a CAML query builder is a handy tool to have on your desktop:
http://www.u2u.be/Software
Thanks again Ian,
I am close to getting it right ;-). Thanks for the caml generator. I installed it, but prior, I used Bamboo alerts caml generator.
Heres my current script
Add-PSSnapin Microsoft.SharePoint.PowerShell -erroraction SilentlyContinue
$web = Get-SPWeb “http://sharepointed.com/sites/pointed”
$list = $web.Lists[“aSource”]
$spQuery = New-Object Microsoft.SharePoint.SPQuery
$spQuery.ViewAttributes = “Scope=’Recursive'”;
$spQuery.RowLimit = 2000
$caml=’2014-04-10T00:00:00Z’
$spQuery.Query = $caml
do
{
$listItems = $list.GetItems($spQuery)
$spQuery.ListItemCollectionPosition = $listItems.ListItemCollectionPosition
foreach($item in $listItems)
{
try
{
#Write-Host $item.Name
$Item.CopyTo(“http://sharepointed.com/sites/pointed/aDestination/”+ $Item.name)
Write-Host(“DELETED: ” + $Item.name + ” from $Items”)
$Item.Recycle()
}
Catch
{
Write-Host $_.Exception.ToString()
}
}
}
while ($spQuery.ListItemCollectionPosition -ne $null)
Now, it does write to host all those files within the date scope but when i include the $item.Copyto method, the first file gets copied and spits out this error.
DELETED: 50 Slides – Royal Blue.pptx from aSource
Guid
—-
db6fc45b-fa89-4c9c-8a0e-913da8cec1ca
An error occurred while enumerating through a collection: Collection was modified; enumeration operation may not execute..
At line:27 char:12
+ foreach <<<< ($item in $listItems)
+ CategoryInfo : InvalidOperation: (Microsoft.Share…on+SPEnumerator:SPEnumerator) [], RuntimeException
+ FullyQualifiedErrorId : BadEnumeration
Thanks again.
shilezi, I updated the post to fix the issue you are having.
You sir, are the best. Works now. Thanks very much!
Hi Ian,
I noticed the “$listItems[$x].Recycle()” does not send to my recycle bin, i dont see them there so i believe its deleting them. How do get it to move to the recycle bin?
Also, for manually created columns that be created similar to source library columns, the metadata are not copied. When copying worked, it was because i saved the source library template and created destination library using that.
Any ideas?
Thanks.