Skip to main content

Hello, programming world!
Knowledge shared is knowledge gained.

DISCLAIMER: Using the information provided here do so at your own risk. Blog may contain errors of grammar and spelling. Sorry about that. I am writing this blog in English in order to practice it. If you find a mistake I will be grateful for the information. Site is using cookies. By using site you agree to use cookies.

How to populate sitecore with test data using power shell


Sometimes you need to generate test data, for instance, to check the performance of a solution. In sitecore you can do it in different ways: you can create them by hand, which is obviously the worst option, you can write a piece of code and run it under http request, you can also use the power shell.

Following script creates 10,000 test items in a loop, set the name, price and category for each of them. In addition, at the end, it displays the run time.

cd master:\\content\home\products
$categories = @{$true="{050E9CAE-F55F-4DF1-8001-07CD4D70FC09}";$false="{8C11E41B-0CE5-4602-BB6D-5DE5B4356D25}"}

$stopwatch = new-object -type 'System.Diagnostics.Stopwatch'
$stopwatch.Start()

for($i = 1; $i -le 10000; $i++)
{
    $newProduct = new-item "product_$i" -type 'sample\product'
    
    set-itemproperty $newProduct.Paths.Path -name "Name" -value "Product $i"
    set-itemproperty $newProduct.Paths.Path -name "Price" -value $i
    set-itemproperty $newProduct.Paths.Path -name "Category" -value $categories[$i % 2 -eq 1]
}

$stopwatch.Stop()
write-host $stopwatch.Elapsed

Performance

On my test virtual machine, for 10,000 of items, the script executes from about an hour to one and a half hours. It is quite a lot of time if you want to insert a milion of products. That is why was introduced two optimizations. Here they are:

cd master:\\content\home\products

$categories = @{$true="{050E9CAE-F55F-4DF1-8001-07CD4D70FC09}";$false="{8C11E41B-0CE5-4602-BB6D-5DE5B4356D25}"}

$stopwatch = new-object -type 'System.Diagnostics.Stopwatch'
$stopwatch.Start()

$bulkupdate = new-object -type "Sitecore.Data.BulkUpdateContext"

for($i = 1; $i -le 10000; $i++)
{
    $newProduct = new-item "product_$i" -type 'sample\product'
    
    $newProduct.Editing.BeginEdit();
    $newProduct["Name"] = "Product $i";
    $newProduct["Price"] = $i;
    $newProduct["Category"] = $categories[$i % 2 -eq 1] ;
    $newProduct.Editing.EndEdit() | out-null
}

if($bulkupdate -ne $null)
{
    $bulkupdate.Dispose();
}

$stopwatch.Stop()
write-host $stopwatch.Elapsed

The use of the BulkUpdateContext forces Sitecore to not update index immediately after every save, but to do it later.

By avoiding the use of cmdlet Set-Property for the direct Sitecore API calls we managed to reduce the number of BeginEdit() and EndEdit() method calls three times, becuse Set-Property internally calls this methods every time.

Thanks to this optimizations was able to reduce the time of inserting 10,000 items to about 25 minutes.

A small note. If you are using Power Shell that is included in Sitecore Rocks, this optimizations will not work. This Power Shell is not running in application context so you need to use cmdlets.

comments powered by Disqus