If you have a list with items that you want to copy to another list or lists you can easily do that using PowerShell. In the scenario I faced, we had one custom source list and we wanted to copy all items to multiple target lists on a regular basis.
If you have used PowerShell before you might be familiar with the .CopyTo and .CopyFrom functions, or at least know that they exist. Well so did I and therefore I thought that the script should be the simplest thing. It turned out thou that the .CopyTo and .CopyFrom functions doesn’t work that well. So what I did was to create a function that handles all types of lists and even copy the attachments.
When I got started I also realised that it would be good if you could specify if you want to update items and not just copy new items, and then you might want to point out what identifier (Column) to look for when you do that update. It could also be useful if you could decide if you wanted to keep existing list items in the target lists or if you want to delete them.
I ended up with the following function:
Copy-SPItem -SourceSite – SourceList -TargetSite -TargetList -UniqueID -Overwrite -DeleteExisting
| -SourceSite | The site where the Source list is located. ex. http://SharePointSite/SourceSite |
| -SourceList | The name of the list to use as Source ex. Templates |
| -TargetSite | The target site or sites, if you want to copy to more then one destination separate the sites with “;” ex. http://SharePointSite/Sites/TargetSite ex. http://SharePointSite/Sites/TargetSite1; http://SharePointSite/Sites/TargetSite2 |
| -TargetList | The name of the list to use as Target Ex SubTemplates |
| -UniqueID | This is used when overwriting items to distinguish what item to update. ex. TampleName |
| -OverWrite | If items exist in the target list should be overwritten. |
| -DeleteExisting | If set to true all items in the target list will first be deleted before the items in the source list is copyed to the target list or lists. Default set to false. |
If you want to download the whole script you can do that from my download sectionor by clicking [Download not found].
Updated 2010-04-19.
- The -overwrite and -deleteExisting parameters are now switch parameters so you don’t specify yes or no anymore.
- The UniqueID is now a mandatory field
- -OverWrite is now default set to false
- Updated Delete function to correct bug found by “Trappist” (see comments for more details)







Very nice. I’m new to PowerShell for manipulating SharePoint. Thanks for paving the way.
Great to be able to help!
If you want, you can sign up for our newsletter on http://www.sharepointandpowershell.com Then you will get updates on our comming book
[...] have been doing a small update my Copy-SPItems script that I wrote about here. The last version required that (at least if don’t want a lot of error messages) that the [...]
I posted C# code for copying the items in case sub folders exist
http://snahta.blogspot.com/2009/10/copy-existing-item-to-another-list.html
[...] You find the updated code here or in the download section. More about the script itself from earlier posts can be found in my older post: Web Application Builder. [...]
Hi,
I can copy the item from the Source to the Destination List without any issue for one time. If I add a new item in Source List and execute the command, I get the error below.
An error occurred while enumerating through a collection: Collection was modified; enumeration operation may not execut
e..
At C:Copy-SpItems.ps1:56 char:3
+ <<<< $OpenTargetList.Items | foreach {
+ CategoryInfo : InvalidOperation: (Microsoft.Share…on+SPEnumerator:SPEnumerator) [], RuntimeException
+ FullyQualifiedErrorId : BadEnumeration
How can sucesfully copy the updated version of SourceList to the Destination list.
Thank you,
Hi,
What type of list is it? Do I understand you correct if you execute the copy-SPItems command from the same shell both times but between the execution of commands the source list has been changed? What happens if you open up a new PowerShell command shell and run it from there. Do you get the same problem?
/Mattias
Hi Mattias,
If I open up a new PowerShell command shell and run it, I get the same error.
I have 2 custom lists (ListA is my Source list and ListB is my Destination list) ListA is being hosted under SiteA and ListB is under SiteB. ListA has only one column “Title” and 1 item inside and my ListB is empty initially.
Please find below the steps I follow;
Step#1: I open my PowerShell command shell from the server SharePoint has been installed.
Step#2: I execute the command “.Copy-SpItems.ps1 -SourceSite http://servername/SiteA -SourceList ListA -TargetSite http://servername/SiteB -TargetList ListB”. It successfully copies the item(s) from ListA to ListB.
Step#3: I go to my ListA and insert a new item(that makes the amount of items 2) and execute the same command above from the same command shell and I get the error I mentioned in my previous message. If I open a new command shell and execute the same command from this new command shell, I get the same error.
Step#4: If I execute the command (still I have 2 items in my ListA) “.Copy-SpItems.ps1 -SourceSite http://servername/SiteA -SourceList ListA -TargetSite http://servername/SiteB -TargetList ListB –DeleteExisting true”. I get 4 rows in my ListB which is the repeat of my list items in ListA. If I execute the same command one more time, I see 6 rows in ListB. Evertyime I run the command with DeleExisting that is set to true, my ListB gets new additional items without deleting the existing ones. So if I will have 2 items in ListA and execute the command 10 times, I will have 20 items in ListB.
Actually beside my issue above, I would also like to ask what if my SiteA is sitting on a different server that requires different credentials. So I will execute the command from the server where SiteB/ListB are located but my source list will be on a different server. Hardcoding the credentials in the code is not a concern for me.
Thank you for your help,
Trappist
Hi,
It sounds quite strange. Let me see if I can reproduce it myself and I get back to you. When it comes to your other question about moving between farms that is unfortunately not possible since we in SharePoint 2007 are not allowed to do remote scripting. So even if we hardcoded the credentials it would not be possible.
/Mattias
Hi Mattias,
Thank you for your prompt reply. Regarding the remote scripting, what if my TargetSite is SharePoint 2010 and my Source Site is SharePoint 2007, would that be possible? (I will be running the script on the TargetSite Server(SP2010).
Thanks again,
Trappist
That’s an interesting idea and worth looking into. You whould have to run the script on the Source Server though since it’s from another server you can do the remote scripting to SharePoint 2010.
We will also make sure we have the same credentials on both environments or maybe it might be possible to built that in to the script. Thanks for the idea, I will look into it as the script. I manaaged to reproduce the problem but have not been able to test so much so give me some more time and I get back to you.
Thanks
Mattias
The Script is now updated so the reported bugs are fixed and I also updated a couple of other items as shown above.
Hope this works better and if you find any problems just let me know!
/Mattias
Hi Mattias,
I have tested the updated version and it works great. Good Job and Thank you.
I tested several scenerios and I have a question for one of them.
I have 2 lists (ListA and ListB). ListA is my Source list and ListB is my destination list. I am copying from source to the destination.
My ListA has 2 rows. I execute the script and my 2 rows are copied over to ListB, that is great. If I change an item in ListA(except the UniqueID) and exeucte the script, the changes are being copied as well to the ListB with the “OverWrite” parameter, that is great.
However, when I delete a row in ListA which makes the total amount of rows 1 in ListA and execute the script, it does not delete it from ListB where I still have 2 rows in ListB. Is this behaviour expected?
My other question is, this would be wonderful if we may run this script remotely. My Destination List is on SharePoint 2010. Is there any plan on this? I am also interested in other solutions you may propose even it is not Powershell.
Again thank you for your work and making this available for us.
Trappist
Mattias good stuff really.
But if understand the script can only be used locally and not remotely to another farm isn’t it.
Just confirming
Thanks
Patrick
Hi Patrick,
It’s correct, it only works so far on one farm. I do have thoughts on updating this one to 2010 and to be able to copy between farms but have just not had the time yet. But When I do I will definately post it here or I might even create a CodePlex project of it.
/Mattias
Had to give thanks! This script just saved me a day of mind numbing tedium! Cheers!
I wonder if there’s a way to specify criteria for what gets copied. I could think of a lot of uses for a copy based on conditions.
[...] Copy Items From One List to Another Using PowerShell [...]
Hi,
I think i am too late to this place. I need help in knowing how to make your ps script to run in timer jobs so that it checks once a day to update the items in my list ListA based in another site’s list ListB?
Thanks in Advance
Hi,
The easiest way to do that is to just set up a scheduled task that will run the script on regular basis. Without developing a custom timerjob it’s not possible to execute a PS script with built in SP timer jobs
/Mattias
I have Copy-SPItem script downloaded from here. Many thanks for that. It is helpful to update items from listA from SiteA to listA of SiteB. Can i request a small help in changing the script to update selected columns from listA(SiteA) to listA(SiteB). here UniqueID helps to update only one column and second column gets updated wrongly…
Thanks in advance