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)



  1. Sean Moran (Reply) on Monday 28, 2009

    Very nice. I’m new to PowerShell for manipulating SharePoint. Thanks for paving the way.

  2. [...] 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 [...]

  3. Sandeep (Reply) on Monday 28, 2009

    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

  4. [...] 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. [...]

  5. Trappist (Reply) on Monday 28, 2009

    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,

    • Mattias Karlsson (Reply) on Monday 28, 2009

      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

  6. Trappist (Reply) on Monday 28, 2009

    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

    • Mattias Karlsson (Reply) on Monday 28, 2009

      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

  7. Trappist (Reply) on Monday 28, 2009

    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

    • Mattias Karlsson (Reply) on Monday 28, 2009

      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

  8. Mattias Karlsson (Reply) on Monday 28, 2009

    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

  9. Trappist (Reply) on Monday 28, 2009

    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

  10. Patrick (Reply) on Monday 28, 2009

    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

    • Mattias Karlsson (Reply) on Monday 28, 2009

      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

  11. Steve Lloyd (Reply) on Monday 28, 2009

    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.

  12. [...] Copy Items From One List to Another Using PowerShell [...]

  13. Gayathri (Reply) on Monday 28, 2009

    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

    • Mattias Karlsson (Reply) on Monday 28, 2009

      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

  14. Gayathri (Reply) on Monday 28, 2009

    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