Last active
May 14, 2025 08:19
-
-
Save akashdborkar/54e599667a109f3a7b5bc2bd1f211430 to your computer and use it in GitHub Desktop.
A PowerShell script that uses Sitecore PowerShell Extensions to extract Sitecore items data to CSV and then use CSV to import data into Sitecore Items.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| <# | |
| .SYNOPSIS | |
| Generic Page data extraction | |
| .DESCRIPTION | |
| Gets Sitecore Items from legacy database and extracts field values. | |
| List could be exported to csv by OOTB feature of List View in SPE. | |
| .NOTES | |
| Akash Borkar | |
| #> | |
| function Write-LogExtended { | |
| param( | |
| [string]$Message, | |
| [System.ConsoleColor]$ForegroundColor = $host.UI.RawUI.ForegroundColor, | |
| [System.ConsoleColor]$BackgroundColor = $host.UI.RawUI.BackgroundColor | |
| ) | |
| Write-Log -Object $message | |
| Write-Host -Object $message -ForegroundColor $ForegroundColor -BackgroundColor $backgroundColor | |
| } | |
| # Function for getting item names from pipe-separated item ids | |
| function GetItemNamesFromIds { | |
| param( | |
| [System.String] $ids | |
| ) | |
| if($ids.Contains("|")) | |
| { | |
| # Split the string by pipe and clean up each GUID | |
| $guids = $ids.Split("|")| ForEach-Object { $_.Trim(' {}')} | |
| [Sitecore.Text.ListString]$nameArr = "" | |
| foreach($id in $guids){ | |
| $formattedId = "{0}{1}{2}" -f '{', $id, '}' | |
| $Id = [Sitecore.Data.ID]::Parse($formattedId) | |
| $item = Get-Item -Path xyz: -ID $Id | |
| if($item -ne $null -and !$nameArr.Contains($item.Name)){ | |
| $nameArr.Add($item.Name)| Out-Null | |
| } | |
| } | |
| # Join the names with pipe separator and return the result | |
| $names = [System.String]::Join("|", $nameArr) | |
| return $names | |
| } | |
| else | |
| { | |
| $item = Get-Item -Path xyz: -ID $ids | |
| return $item.Name | |
| } | |
| } | |
| #Function for getting datasource item, which is further used for extracting field value & assigning to new rendering | |
| function Get-DatasourceItem{ | |
| param( | |
| [System.String] $path | |
| ) | |
| $datasourceItem = $sourceDatabase.GetItem($path) | |
| return $datasourceItem | |
| } | |
| Write-LogExtended "Generic Pages Data Extraction" | |
| Write-LogExtended "-----------------------------------------------------------------" | |
| $processedItems = [System.Collections.Generic.List[PSCustomObject]]::new() | |
| $nonprocessedItems = [System.Collections.Generic.List[PSCustomObject]]::new() | |
| $sourceDatabase = Get-Database "xyz" | |
| $parentPath = Show-Input -Prompt "Please enter the Sitecore item path for getting children" | |
| if($parentPath -ne $null) | |
| { | |
| Write-Host "Selected path: $parentPath" | |
| #Get all child items based on provided path. /sitecore/content/XYZ/Home/Generic | |
| $nodePath = "xyz:" + $parentPath | |
| $items = Get-ChildItem -Path $nodePath -Recurse | Where-Object { $_.TemplateName -eq 'Generic Page'} | |
| Write-LogExtended "Total child items: $($items.Count) Path: $($nodePath)" -ForegroundColor Green | |
| foreach($sourceItem in $items) | |
| { | |
| if($sourceItem -ne $null){ | |
| #Retrieve RTE | |
| $rts = Get-Rendering -Item $sourceItem -Device $defaultLayout -FinalLayout | Where-Object { $_.ItemID -eq "{278F7B0D-98F4-4873-9B7B-940082158E4A}"} | |
| [Sitecore.Text.ListString]$rtArr = "" | |
| if($rts -ne $null) | |
| { | |
| foreach($rt in $rts) | |
| { | |
| $item = $sourceDatabase.GetItem($rt.Datasource) | |
| if($item -ne $null -and $item["Text"] -ne "") | |
| { | |
| $rtArr.Add($item["Text"])| Out-Null | |
| } | |
| } | |
| } | |
| #Retrieve Accordion | |
| $accordion = Get-Rendering -Item $sourceItem -Device $defaultLayout -FinalLayout | Where-Object { $_.ItemID -eq "{165B5ECC-E6A0-4B41-AA23-D28FA5A9BF68}"} | |
| $accordionCount = 0 | |
| [Sitecore.Text.ListString]$titleArr = "" | |
| [Sitecore.Text.ListString]$descArr = "" | |
| if($accordion -ne $null) | |
| { | |
| foreach($renderingItem in $accordion) | |
| { | |
| if($renderingItem.Datasource -ne "") | |
| { | |
| $rendering = Get-Item -Path xyz: -Id $renderingItem.Datasource | |
| if($rendering.HasChildren) | |
| { | |
| $accdChildItems = Get-ChildItem -Path xyz: -ID $rendering.ID | |
| foreach($item in $accdChildItems) | |
| { | |
| if($item["Title"] -ne "" -and $item["Description"] -ne "") | |
| { | |
| $titleArr.Add($item["Title"])| Out-Null | |
| $descArr.Add($item["Description"])| Out-Null | |
| } | |
| } | |
| $accordionCount++; | |
| } | |
| } | |
| } | |
| } | |
| #Retrieve values of multilist field named Categories | |
| $categories = $sourceitem["Categories"] | |
| $categoriesnames = "" | |
| if($categories -ne "" -and $categories -ne $null) | |
| { | |
| $categoriesnames = GetItemNamesFromIds -ids $categories | |
| } | |
| try{ | |
| $processedItems.Add( | |
| [PSCustomObject]@{ | |
| Name = $sourceItem.Name | |
| Id = $sourceItem.Id | |
| Path = $sourceItem.Paths.FullPath | |
| Title = $sourceItem["Title"] | |
| HeaderTitle = $sourceItem["Header Title"] | |
| Summary = $sourceItem["Summary"] | |
| Image = $sourceItem["Image"] | |
| OGImage = $sourceItem["Media Image"] | |
| Categories = $categoriesnames | |
| HasRTE = $rtArr.Count | |
| RichText1 = $richText | |
| RichText2 = $rtArr[1] | |
| RichText3 = $rtArr[2] | |
| HasAccordion = $accordionCount | |
| AccTitle1 = $titleArr[0] | |
| AccDesc1 = $descArr[0] | |
| AccTitle2 = $titleArr[1] | |
| AccDesc2 = $descArr[1] | |
| AccTitle3 = $titleArr[2] | |
| AccDesc3 = $descArr[2] | |
| AccTitle4 = $titleArr[3] | |
| AccDesc4 = $descArr[3] | |
| } | |
| ) | |
| Write-LogExtended "Added data for $($sourceItem.Name), Path: $($sourceItem.Paths.FullPath) " -ForegroundColor Green | |
| } | |
| catch{ | |
| Write-Host "Error occured" -BackgroundColor DarkRed | |
| $nonprocessedItems.Add( | |
| [PSCustomObject]@{ | |
| Name = $sourceItem.Name | |
| Id = $sourceItem.Id | |
| Path = $sourceItem.Paths.FullPath | |
| } | |
| ) | |
| } | |
| } | |
| else | |
| { | |
| Write-LogExtended "No Item found in csv for SourceURL: $($row.SourceURL)" -ForegroundColor RED | |
| } | |
| } | |
| $processedItems | Show-ListView -PageSize 15000 -Property Name, Id, Path, Title, HeaderTitle, Summary, Categories, Image, OGImage, | |
| HasRTE, RichText1, RichText2, RichText3, HasAccordion, AccTitle1, AccDesc1, AccTitle2, AccDesc2, AccTitle3, | |
| AccDesc3, AccTitle4, AccDesc4 | |
| $processedItems | export-csv -Path "C:\inetpub\wwwroot\App_Data\Process.csv" -NoTypeInformation | |
| $nonprocessedItems | Show-ListView -PageSize 15000 -Property Name, Id, Path | |
| } | |
| else | |
| { | |
| Write-Host "Path is not provided : $parentPath" | |
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| <# | |
| .SYNOPSIS | |
| Generic Pages Import | |
| .DESCRIPTION | |
| Iterate through CSV, create siteore items for generic pages and Populate fields. Generate List of processed and Non processed items. | |
| By default, packages are saved to disk at C:\inetpub\wwwroot\App_Data\packages. Thus C:\inetpub\wwwroot\App_Data\GenericPages.csv will be | |
| path | |
| .NOTES | |
| Akash Borkar | |
| #> | |
| functionWrite-LogExtended{ | |
| param( | |
| [string]$Message, | |
| [System.ConsoleColor]$ForegroundColor = $host.UI.RawUI.ForegroundColor, | |
| [System.ConsoleColor]$BackgroundColor = $host.UI.RawUI.BackgroundColor | |
| ) | |
| Write-Log -Object $message | |
| Write-Host -Object $message -ForegroundColor $ForegroundColor -BackgroundColor $backgroundColor | |
| } | |
| Write-LogExtended"Generic Pages Import" | |
| Write-LogExtended"-----------------------------------------------------------------" | |
| # Prompt for the file path | |
| $filePath = Show-Input -Prompt "Please enter the full path to the CSV file" | |
| if($filePath -ne $null) | |
| { | |
| Write-Host"Selected file: $filePath" | |
| # Import the CSV file | |
| $csvData = Import-Csv -Path $filePath | Where-Object{ -join $_.psobject.Properties.Value } | |
| Write-LogExtended"CSV file read successfully" -ForegroundColor Green | |
| if($csvData -ne $null) | |
| { | |
| $processedItems = [System.Collections.Generic.List[PSCustomObject]]::new() | |
| $NonProcessedItems = [System.Collections.Generic.List[PSCustomObject]]::new() | |
| $database = Get-Database"master" | |
| $placeholder = "/headless-main/container-1" | |
| foreach($rowin$csvData){ | |
| #Generic Page branch | |
| $branchTemplateId = [Sitecore.Data.ID]::Parse("{8032FE9E-3CD1-4E80-8377-66BBF74F839E}") | |
| # Extract the desired item name, parent item and template id from the URL | |
| $itemName = $row.Name | |
| $parentItemPath = $row.Path -Replace $itemName, "" | |
| # Get the parent item | |
| $parentItem = $database.GetItem($parentItemPath) | |
| if($parentItem) | |
| { | |
| # Check if the item already exists | |
| $existingItemPath = "$($parentItem.Paths.FullPath)/$itemName" | |
| $itemExists = Test-Path -Path $existingItemPath | |
| if(-not $itemExists) | |
| { | |
| $item = [Sitecore.Data.Managers.ItemManager]::AddFromTemplate($itemName, $branchTemplateId, $parentItem) | |
| if($item -eq $null) | |
| { | |
| Write-LogExtended"Unable to create new item - $($itemName) - in Language en" -ForegroundColor Red | |
| $NonProcessedItems.Add( | |
| [PSCustomObject]@{ | |
| ID = $row.ID | |
| Name = $row.Name | |
| Path = $row.Path | |
| }) | |
| } | |
| if($item -ne $null){ | |
| $item.Editing.BeginEdit() | |
| $item["Title"] = $row.Title | |
| #Meta Properties/OG | |
| $item["OpenGraphTitle"] = $row.Title | |
| $item["OpenGraphDescription"] = $row.Summary | |
| $item["MetaDescription"] = $row.Summary | |
| $item["TwitterDescription"] = $row.Summary | |
| $item["TwitterImage"] = $row.OGImage | |
| $item.Editing.EndEdit() | Out-Null | |
| $datasourcePath = $item.Paths.FullPath + "/Data/" | |
| #Create and Populate Rich Text (Max RT are 3 as we had extracted 3 RTEs) | |
| if($row.RichText1 -ne "") | |
| { | |
| For($i=1; $i -lt 4; $i++) | |
| { | |
| $propname = "RichText$i" | |
| if($row.$propname -ne "") | |
| { | |
| $dsitem = New-Item -Path $datasourcePath -Name "Text $i" -ItemType "{4FBDBF79-C7D6-42F1-8048-D5E70D6167D5}" | |
| $dsitem.Editing.BeginEdit() | |
| $dsitem.Text = $row.$propname | |
| $dsitem.Editing.EndEdit() | Out-Null | |
| #Create and Set Rich text Rendering | |
| $rendering = get-item -path master: -id {EF82E4AE-C274-40D4-837C-B3E1BF180CCC} | |
| $renderinginstance = $rendering | new-rendering -placeholder $placeholder | |
| $renderinginstance.datasource = $dsitem.id | |
| Add-Rendering -Item $item -placeholder $placeholder -instance $renderinginstance -finallayout | |
| $item.Editing.beginedit() | |
| $item.Editing.endedit() | out-null | |
| } | |
| } | |
| } | |
| #Create and Populate Accordion datasource item (Max Acc are 4) | |
| if($row.AccTitle1 -ne "" -and $row.AccDesc1 -ne "") | |
| { | |
| $accDatasourcePath = $item.Paths.FullPath + "/Data/" | |
| #Accordion | |
| $Accitem = New-Item -Path $accDatasourcePath -Name "Accordion" -ItemType "{D482D45C-4248-46C8-BDD5-DE7C2255C52A}" | |
| $Accitem.Editing.BeginEdit() | |
| $Accitem.Title = "Accordion" | |
| $Accitem.Editing.EndEdit() | Out-Null | |
| #Create and Set Acc rendering | |
| $rendering = Get-Item -Path master: -ID {3341A94D-42C9-4EE3-8A25-51D8B437982B}#Accordion | |
| $renderingInstance = $rendering | New-Rendering -Placeholder $placeholder | |
| $renderingInstance.Datasource = $Accitem.ID | |
| Add-Rendering -Item $item -PlaceHolder $placeholder -Instance $renderingInstance -FinalLayout | |
| For($i=1; $i -lt 5; $i++) | |
| { | |
| $titlename = "AccTitle$i" | |
| $descname = "AccDesc$i" | |
| if($row.$titlename -ne "" -and $row.$descname -ne "") | |
| { | |
| #Acc Panel | |
| $dsitem = New-Item -Path $Accitem.Paths.FullPath -Name $row.$titlename -ItemType "{B50C502C-2740-44C8-A63E-E9E4AF4BAA4B}" | |
| $dsitem.Editing.BeginEdit() | |
| $dsitem.Title = $row.$titlename | |
| $dsitem.Content = $row.$descname | |
| $dsitem.Editing.EndEdit() | Out-Null | |
| #Create and Set Acc panel rendering | |
| $rendering = Get-Item -Path master: -ID {7614DFFF-6735-4BA5-929A-A82FBC91DB25}#Acc Panel | |
| $renderingInstance = $rendering | New-Rendering -Placeholder "/headless-main/container-1/accordion-panels-1" | |
| $renderingInstance.Datasource = $dsitem.ID | |
| Add-Rendering -Item $item -PlaceHolder "/headless-main/container-1/accordion-panels-1" -Instance $renderingInstance -FinalLayout | |
| $item.Editing.BeginEdit() | |
| $item.Editing.EndEdit() | Out-Null | |
| Write-LogExtended"Added Accordion datasource to New Item - $($item.Name) at $($dsitem.Paths.FullPath)" -ForegroundColor Green | |
| } | |
| } | |
| } | |
| $ManualWork = "No" | |
| if(($row.HasRTE -gt 3) -or($row.HasAccordion -gt 4)) | |
| { | |
| $ManualWork = "Yes" | |
| } | |
| Write-LogExtended"Created New Item - $($itemName) at $($parentItemPath)" -ForegroundColor Green | |
| $processedItems.Add( | |
| [PSCustomObject]@{ | |
| Name = $item.Name | |
| Id = $item.ID | |
| NewPath = $item.Paths.FullPath | |
| HasRTE = $row.HasRTE | |
| HasAccordion = $row.HasAccordion | |
| ManualWork = $ManualWork | |
| }) | |
| } | |
| } | |
| else | |
| { | |
| Write-LogExtended"Item $($itemName) already exists at $($parentItemPath) " -ForegroundColor Yellow | |
| } | |
| } | |
| else | |
| { | |
| Write-LogExtended"Parent item not found: $parentItemPath" -ForegroundColor Red | |
| } | |
| } | |
| $processedItems | Show-ListView -PageSize 2000 -InfoTitle "Processed Items" -Property Name, Id, NewPath, HasRTE, HasAccordion, ManualWork | |
| $processedItems | export-csv -Path "C:\inetpub\wwwroot\App_Data\GenericPagesReport.csv" -NoTypeInformation | |
| $NonProcessedItems | Show-ListView -PageSize 2000 -InfoTitle "Non Processed Items" -Property ID, Name, Path | |
| } | |
| } | |
| else | |
| { | |
| Write-Host"No file selected : $filePath" | |
| } |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment