使用 Sitecore PowerShell 脚本进行数据迁移
本技巧将为 Sitecore 开发人员概述如何使用 Sitecore PowerShell 脚本迁移数据。
引言
本技巧将为 Sitecore 开发人员概述如何使用 Sitecore PowerShell 脚本迁移数据。
背景
当我们的客户分享了重新设计博客站点的计划后,在与客户讨论后,我们了解到我们需要为博客站点创建新的模板,并将旧数据迁移到由新模板创建的新内容项中,因为客户不希望对现有博客站点相关的 Sitecore 项目模板进行任何更改。
我们进行了头脑风暴,并考虑通过复制现有模板和内容节点来创建一个新节点,然后开始在新节点上进行更改。挑战在于在不丢失任何数据的情况下,在新节点模板和新内容项之间建立链接。经过一些研究,我们了解到我们可以使用 Sitecore PowerShell 脚本进行数据迁移。最初,我们并不完全清楚我们需要编写多少个以及多么复杂的查询才能完成完整的迁移。我们对 Sitecore PowerShell 脚本扩展进行了更多研究,并能够编写一些非常有用的脚本,这足以让我们继续使用这种方法。
Sitecore PowerShell 扩展模块可以从 Sitecore Marketplace 下载。该模块可以像普通的 Sitecore 包一样安装,安装后,可以在开发工具下访问 Power ISE 来编写和执行脚本。
Power SEI 截图供参考
参考脚本
- 我们从旧节点复制了所有内容,从现有博客站点节点创建了一个新的模板节点和一个新的内容节点。Sitecore 本身将所有值类型数据保存在新节点中。
- 在新节点的内容中,所有引用字段仍然指向旧节点。我们编写了 Sitecore PowerShell 脚本来更改新内容项与旧模板的关系,并更新引用字段与新资产模板的关联。
示例脚本
** 在下面的示例中,我们首先在变量中声明所需的路径,创建函数来获取资产,例如“GetAuthor”、“GetContentType”、“GetTags”等,最后编写脚本来通过消费所有内容进行迁移。
*旧节点:OldBlogSite
*新节点:NewBlogSite
*设置所有必需的路径以遍历其子项
$master = [Sitecore.Configuration.Factory]::GetDatabase("master"); $oldBlogSiteAuthors = Get-ChildItem -Path "master:\content\sites\OldBlogSite\Assets\Authors" -Recurse $newBlogSiteAuthors = Get-ChildItem -Path "master:\content\sites\NewBlogSite\Assets\Authors" -Recurse $oldBlogSiteContentTypes = Get-ChildItem -Path "master:\content\sites\OldBlogSite\Metadata\Enumerations\ContentType" -Recurse $newBlogSiteContentTypes = Get-ChildItem -Path "master:\content\sites\NewBlogSite\Metadata\Enumerations\ContentType" -Recurse $oldBlogSiteTags = Get-ChildItem -Path "master:\content\sites\OldBlogSite\Assets\Tags" -Recurse $newBlogSiteTags = Get-ChildItem -Path "master:\content\sites\NewBlogSite\Assets\Tags" -Recurse
*使用旧节点作者 ID 获取新节点作者 ID 的函数,以更新文章作者 Droplink 字段
function GetAuthor($authorsGuid) { $author = $oldBlogSiteAuthors | Where-Object { $_.ID -eq $authorsGuid }; return ($newBlogSiteAuthors | Where-Object { $_.Name -eq $author.Name }).ID; }
*使用旧节点“内容类型”ID 获取新节点“内容类型”ID 的函数,以更新文章“内容类型”Droplink 字段
function GetContentType($contentItemPath) { $contentItem = Get-Item -Path $contentItemPath.Replace("NewBlogSite","OldBlogSite"); $contentType = $oldBlogSiteContentTypes | Where-Object { $_.ID -eq $contentItem.ContentType }; return ($newBlogSiteContentTypes | Where-Object { $_.Name -eq $contentType.Name }).ID; }
*使用旧节点标签 ID 获取新节点标签的函数,以更新文章标签 TreeListEx 字段
function GetTags($tags) { $tagArray = ""; $tags.Split('|') | ForEach-Object { $tagArray += "|"; $this = $_.Trim(); $tag = $oldBlogSiteTags | Where-Object { $_.ID -eq $this }; $tagArray += ($newBlogSiteTags | Where-Object { $_.Name -eq $tag.Name }).ID; } return $tagArray.TrimStart('|'); }
*用于更新特定文章类型的模板并更新内容项的引用字段关联的脚本
$articlePageTemplate = $master.Templates["{DFE29F6A-B11F-411B-BD35-0629A1B23E26}"]; cd master:\content\sites\NewBlogSite\Home\Articles; Get-ChildItem -recurse | ForEach-Object { $this = $_; switch($_.TemplateName) { "ArticlePage" { $this.ChangeTemplate($articlePageTemplate); if($this.Author -ne $null ) {$author = GetAuthor($this.Author); if($author -ne $null) { $this.Author = $author; }} $contentType = GetContentType($this.ItemPath); if($contentType -ne $null) {$this.ContentType = $contentType;} if($this.Tags -ne $null ) { $tags = GetTags($this.Tags); if($tags -ne $null) {$this.Tags = $tags}} } default {} } };
- 下一个挑战是将每篇文章的子项移动到不同的位置,并将这些项链接到新的容器项,最后将容器链接到特定文章的“
Treelist
”字段。示例脚本
*用于将文章项目移动到另一个位置的脚本
$master = [Sitecore.Configuration.Factory]::GetDatabase("master"); $listFolderTemplate = $master.Templates["{FD41B6C6-49EB-442C-BBF8-E809BB6251F6}"]; cd master:\content\sites\NewBlogSite\Home\Articles\2015; Get-ChildItem -recurse | ForEach-Object { $this = $_; switch($_.TemplateName) { "ListArticlePage" { $path = $this.ItemPath.Replace ("Home/Articles","Assets/Article Page Assets/Lists"); Copy-Item -Path $this.ItemPath -Destination $path.Replace($this.Name,""); $this | Get-ChildItem -recurse| ForEach-Object { Move-Item -Path $_.ItemPath -Destination $path ; } } default {} } };
*用于将容器项目名称重命名为文章名称并将项目与容器关联的脚本
cd "master:\content\sites\NewBlogSite\Assets\Article Page Assets\Lists\2015"; Get-ChildItem -recurse | ForEach-Object { $this = $_; switch($_.TemplateName) { "ListArticlePage" { $this.ChangeTemplate($listFolderTemplate); $listArray = ""; $this | Get-ChildItem -recurse| ForEach-Object { $listArray += "|"; $listArray += $_.ID; } $this.ContentBoxes = $listArray.TrimStart('|'); $newName = $this.Name + '-Container'; Rename-item -Path $this.ItemPath -NewName $newName } default {} } };
*用于将容器项目与特定文章类型 Treelist 字段关联的脚本
cd master:\content\sites\NewBlogSite\Home\Articles\2015; Get-ChildItem -recurse | ForEach-Object { $this = $_; switch($_.TemplateName) { "ListArticlePage" { $path = $this.ItemPath.Replace("Home/Articles", "Assets/Article Page Assets/Lists") + '-Container'; $this.ContentBoxes = (Get-Item -Path $path).ID } default {} } };
我们编写了更多脚本,所有迁移都非常轻松、高效和快速地完成。
结论
Sitecore 开发人员可以使用 Sitecore PowerShell 脚本进行大型数据迁移或任何复杂的修改,这些修改需要调用内部 Sitecore API,而无需编写任何实用程序。它是一种标准的 PowerShell 语法,易于理解和编写。