I got a request to move items from one library to another in SharePoint on prem. I had to piece together a few different PowerShell’s to accomplish this. The reason for this is that the source list is over the ten thousand item threshold limit. So my goal in the this case is to take all items older than a given time period and then move them to a different library.
The key variable here is the target date variable that I created. It gets placed into the CAML query and in this case the value is 7. So all items that are older than 7 days will be placed into the array. The array in question is $Items. You will also notice that I currently have the move of the file commented out. So you can run this without causing any damage as long as you keep that commented out.
#Add SharePoint PowerShell SnapIn if not already added
if ((Get-PSSnapin "Microsoft.SharePoint.PowerShell" -ErrorAction SilentlyContinue) -eq $null) {
Add-PSSnapin "Microsoft.SharePoint.PowerShell" }
#Fill in Variables
$srcListSiteUrl = "http://Contoso/SourceList"
$SourceListName = "SourceList"
$DestinationListName = "DestinationList"
$TargetDate = 7 #this is in total days
$DesListUri = $srcListSiteUrl + "/" + $DestinationListName
$SourceWeb = get-spweb $srcListSiteUrl
$SourceList = $SourceWeb.Lists[$SourceListName]
Write-Host "Source List: $SourceList" -foregroundcolor green
$DesList = $SourceWeb.Lists[$DestinationListName]
Write-Host "Destination List: $DesList" -foregroundcolor green
Write-Host $SourceList.ItemCount "total items in $SourceListName" -ForegroundColor Green
#Filtering Items based on the Date as we do not want to archive all items in the list
$filterQuery = '<Where>
<Leq>
<FieldRef Name = "Created" /> <Value IncludeTimeValue="TRUE" Type="DateTime">' +(Get-Date).AddDays($TargetDate).ToString('yyyy-MM-dd')+ '</Value>
</Leq></Where>'
$CategoryQuery = new-object Microsoft.SharePoint.SPQuery
$CategoryQuery.Query = $filterQuery
$Items = $SourceList.GetItems($CategoryQuery)
Write-host $items.Count "total items to be moved" -ForegroundColor Green
foreach($item in $Items){
write-host "Moving $($item.Name)" -ForegroundColor Green
#$item.File.MoveTo($DesListUri + "/" + $item.Name), $true #you use the destination list url here
}
Additionally if you want to do it by a specific date field instead of the created field I added the below code to the for each command. So this is using a separate date field/column in the library rather than the created column. I am adding -125 days to the script because that is what the customer wanted. Notice I still have the actual moving of the item commented out. With using this statement the $targetdate variable will be less important but its still nice to filter some items out of your query so you are working with a smaller array.
foreach($item in $Items){
$subDate = $item["FormSubmissionDate"]
$Today = Get-date
$MinusDate = $Today.AddDays(-125)
if($subdate -gt $MinusDate){
write-host "Moving $($item.Name)" -ForegroundColor Green
#$item.File.MoveTo($DesListUri + "/" + $item.Name), $true
}
}