Wednesday, 27 September 2017

Sitecore Powershell - New-Item with specific ID (ForceId not working)

I am writing some Sitecore Powershell scripts to migrate content from an old site to a new re-designed site with different set of templates.

As you would imagine, we should keep the old item IDs instead of creating new IDs in case we also want to maintain the references between the items (if any). If you have used the New-Item cmdlet before, you might have noticed that it supports a parameter: -ForceId.

I noticed that most of the items I created with the ForceId parameter set are having the same ID as the original item however some of them are not. And then I realised that those items were created using a branch template.

While Sitecore PSE does use the ItemManager.AddFromTemplate() method that has several overloads to support creating item with a specific ID, it's logic only works for normal template and not for the branch template. In the current version (4.6) of PSE, it has logic below (shortened to show the point):

// iD is the ID passed to the ForceId parameter

if (type != TemplateItemType.Template)
{
    // Logic to check if it is branch template removed for simplicity
    newItem = parentItem.Add(name, fromPath);
}
else
{
    newItem = ((iD != ID.Null) ? ItemManager.AddFromTemplate(name, fromPath.ID, item, iD) : ItemManager.AddFromTemplate(name, fromPath.ID, item));
}
As you can see from above code, when it is using branch template, it does not actually use the ID we passed to the ForceId parameter.

To make it work, I have written a function to help, lets call it New-ItemCustom:



function New-ItemCustom
{
    <#
        .SYNOPSIS
            Create a new Sitecore item based on template/branch ID. Specify
            the NewItemID to create the item with the specific ID.
    #>
    [CmdletBinding()]
    param 
    (
        [Parameter(Mandatory=$True)]
        $Name,
        [Parameter(Mandatory=$True)]
        [string]$TemplateID,
        [Parameter(Mandatory=$True)]
        $ParentItem,
        [string]$NewItemID = ""
    )
    
    $scTemplateID = New-Object -TypeName "Sitecore.Data.ID" -ArgumentList $TemplateID
    $newItem = $null
    
    if ($NewItemID -ne "") 
    {
        $scItemID = New-Object -TypeName "Sitecore.Data.ID" -ArgumentList $NewItemID
        $newItem = [Sitecore.Data.Managers.ItemManager]::AddFromTemplate($Name, $scTemplateID, $ParentItem, $scItemID)
    }
    else 
    {
        $newItem = [Sitecore.Data.Managers.ItemManager]::AddFromTemplate($Name, $scTemplateID, $ParentItem)
    }
    
    return $newItem
}


Usage:


New-ItemCustom -Name "new item name" -TemplateID "template/branch ID" -ParentItem (Get-Item -Path: .) -NewItemID "Sitecore Item ID here"



Hope this helps.