Question

The purpose of my script is to copy all elements from one discussion board to another.

I do it via powershell.

All works great on my test server, but when we tried to test the script on another server there was the following problem: Theme of discussion is copied perfectly, but all reply on this topic is copied like a new topic in parent topic.

Here is the source list Source List

And here is previous discussion after copying into destination list

Discussion after coping

So, here is how I copy all replyes

        foreach ($sourceMessage in $sourceMessages) {
        $ParentItem = $NewItem
        if ($sourceMessage['ParentItemID'] -ne $_.ID)
        {
            foreach ($item in $ArrayOfReplys) 
            {
                if ($sourceMessages.GetItemById($sourceMessage['ParentItemID'])['Body'] -eq $item['Body'])
                {
                    $ParentItem = $item
                }
            }                
        }
        $destinationMessage = [Microsoft.SharePoint.Utilities.SPUtility]::CreateNewDiscussionReply($ParentItem)

        $destinationMessage["Body"] = $sourceMessage["Body"]
        $destinationMessage["TrimmedBody"] = $sourceMessage["TrimmedBody"]
        $destinationMessage["Author"] = $sourceMessage["Author"]
        $destinationMessage["Editor"] = $sourceMessage["Editor"]
        $destinationMessage["Modified"] = $sourceMessage["Modified"]
        $destinationMessage["Created"] = $sourceMessage["Created"]
        # == Solution ==
        $destinationMessage["ContentTypeId"] = $spdestinationList.ContentTypes["Message"]

        for ($i = 0; $i -le $table.Rows.Count - 1; $i++)
        {
            if (($table.Rows[$i].destination_Column_Title -eq "") -or ($table.Rows[$i].Source_Column_Title -eq ""))
            {
           
            }
            else
            {
                $destinationMessage[$table.Rows[$i].destination_Column_Title] = $sourceMessage[$table.Rows[$i].Source_Column_Title]
            }
        }

        $attachmentCollection = $sourceMessage.Attachments
        $folder = $spSourceWeb.GetFolder($attachmentCollection.UrlPrefix);
        foreach ($file in $folder.Files) {
            $fileName = $file.Name
            $bytes = $file.OpenBinary() 
            $filePath = "$webURL/$folder/$fileName"
            $destinationMessage.Attachments.Add([System.IO.Path]::GetFileName($filePath), $bytes);
        }

        $destinationMessage.SystemUpdate($false)
        $ArrayOfReplys += $destinationMessage
    }

And what did not work correctly is [Microsoft.SharePoint.Utilities.SPUtility]::CreateNewDiscussionReply($ParentItem) because this method does not create a new reply.

I think that it is necessary to establish some kind of an update that corrects the operation of this method, but I can not find the right information.

Was it helpful?

Solution

Try below code:

#Copy discussions to a new discussion board

$web = Get-SPWeb "https://sitecollectionurl"
$sourceList = $web.Lists["OldDiscussions"]
$destinationList = $web.Lists["NewDiscussion"]

$sourceListItems = $sourceList.Folders

foreach($item in $sourceListItems)
{
 $title = $item['Title']
 write-host "Copying $title"
 #Get desired discussion by ID
 $sourceDiscussion = $sourceList.Folders | Where-Object {$_.ID -eq $item['ID']}

 #Add new discussion to destination list
 $destinationDiscussion = [Microsoft.SharePoint.Utilities.SPUtility]::CreateNewDiscussion($destinationList.Items, $sourceDiscussion.Title)

 #Copy field values
 $destinationDiscussion["Body"] = $sourceDiscussion["Body"]
 $destinationDiscussion["Author"] = $sourceDiscussion["Author"]
 $destinationDiscussion["Editor"] = $sourceDiscussion["Editor"]
 $destinationDiscussion["Modified"] = $sourceDiscussion["Modified"]
 $destinationDiscussion["Created"] = $sourceDiscussion["Created"]

 #Copy attachments
 $attachmentCollection = $sourceDiscussion.Attachments
 $folder = $web.GetFolder($attachmentCollection.UrlPrefix);
 foreach ($file in $folder.Files) {
  $fileName = $file.Name
  $bytes = $file.OpenBinary() 
  $filePath = "$webURL/$folder/$fileName"
  $destinationDiscussion.Attachments.Add([System.IO.Path]::GetFileName($filePath), $bytes);
 }  

 #Add discussion
 $destinationDiscussion.SystemUpdate($false)

 #Get all discussion messages
 $caml='<Where><Eq><FieldRef Name="ParentFolderId" /><Value Type="Integer">{0}</Value></Eq></Where>' -f $sourceDiscussion.ID
 $query = new-object Microsoft.SharePoint.SPQuery
 $query.Query = $caml
 $query.ViewAttributes = "Scope='Recursive'";
 $sourceMessages = $sourceList.GetItems($query)

 foreach ($sourceMessage in $sourceMessages) {
  #Add new message to discussion
  $destinationMessage = [Microsoft.SharePoint.Utilities.SPUtility]::CreateNewDiscussionReply($destinationDiscussion)

  #Copy field values
  $destinationMessage["Body"] = $sourceMessage["Body"]
  $destinationMessage["TrimmedBody"] = $sourceMessage["TrimmedBody"]
  $destinationMessage["Author"] = $sourceMessage["Author"]
  $destinationMessage["Editor"] = $sourceMessage["Editor"]
  $destinationMessage["Modified"] = $sourceMessage["Modified"]
  $destinationMessage["Created"] = $sourceMessage["Created"]
  $destinationMessage["ContentTypeId"] = $destinationList.ContentTypes["Message"]

  #Copy attachments
  $attachmentCollection = $sourceMessage.Attachments
  $folder = $web.GetFolder($attachmentCollection.UrlPrefix);
  foreach ($file in $folder.Files) {
   $fileName = $file.Name
   $bytes = $file.OpenBinary() 
   $filePath = "$webURL/$folder/$fileName"
   $destinationMessage.Attachments.Add([System.IO.Path]::GetFileName($filePath), $bytes);
  }

  #Add message
  $destinationMessage.SystemUpdate($false)

 }

}
write-host 'Done'

Reference - Copy discussion board

Licensed under: CC-BY-SA with attribution
Not affiliated with sharepoint.stackexchange
scroll top