A collection of Sitecore PowerShell snippets from various sources to have them in one place easy to copy, adjust and execute. Credits to Adam Najmanowicz and Michael West - you guys did a great job!
- Write to CSV
- Using link fields
- Update item presentation final layout
- Traverse tree with query
- Read from CSV
- Output all object properties
- Move item
- List cms users
- Get and edit an item
- Generate google sitemap XML
- Exclude template
- Create users from CSV
- Create an item
- Convert datetime field value to DateTime object
- Change item template
- Add base template
- Parse a Rich Text to replace elements
- Generate a hash of a media file
- Exporting the username and custom properties
- Show List View with all users' properties
- Set workflow for all items
- Unlock items of a template recursively
- Zip and download sitecore media library folder
- Zip and download logs
- Updating renderings properties to enable VaryByData
- New media item
- Update media item
- List Roles for User
- Remove unused media items
- Get items modified in last 7 days
1. Write to csv
More description - normal font
$everythingUnderHome = Get-Item master: -Query "/sitecore/content/Home//*"
$outputFilePath = "C:\temp\my-csv-file.csv"
$results = @();
$everythingUnderHome | ForEach-Object {
$properties = @{
Name = $_.Name
Template = $_.TemplateName
Path = $_.ItemPath
}
$results += New-Object psobject -Property $properties
}
$Results | Select-Object Name,Template,Path | Export-Csv -notypeinformation -Path $outputFilePath
2. Using link fields
More description - normal font
#Get an alias
$alias = = Get-Item -Path "master:/sitecore/system/Aliases/test"
#Get the link field
[Sitecore.Data.Fields.LinkField]$field = $_.Fields["Linked item"]
# the path to the target item
$field.InternalPath
# The guid if internal. Otherwise this is an Empty GUID
$field.TargetID
# 'internal' or 'external'
$field.LinkType
# Other proporties include MediaPath, QueryString and Target
3. Update item presentation final layout
$items = Get-Item master:/content/home//* | Where-Object { $_.Fields["__Final Renderings"] -like "*col-huge*" }
$items | ForEach-Object {
Write-Host $_.Fields["__Final Renderings"]
$_.Editing.BeginEdit()
$_["__Final Renderings"] = $_.Fields["__Final Renderings"].toString().replace("col-huge", "col-wide-1");
$_.Editing.EndEdit();
Write-Host $_.Fields["__Final Renderings"]
4. Traverse tree with query
$everythingUnderHome = Get-Item master: -Query "/sitecore/content/Home//*"
$everythingUnderHome | ForEach-Object {
Write-Host "Item name: " + $_.Name
}
5. Read from CSV
$csv = Import-Csv "C:\temp\my-csv-file.csv"
foreach($row in $csv)
{
if ($row -eq $csv[0])
{
#Skip the first row as it contains the column headings in your CSV
continue;
}
#Output value for Column1 and Column2
Write-Host $row."Column1";
Write-Host $row."Column2";
}
6. Output all object properties
[Sitecore.Data.Fields.LinkField]$field = $_.Fields["Linked item"]
Write-Host ($field | Format-Table | Out-String)
7. Move item
$item = Get-Item master:/content/home/old/item
#Will move and place this item under the target new
Move-Item -Path $item.ItemPath "master:\sitecore\content\Home\new";
8. List cms users
$allSitecoreUsers = Get-User -Filter "sitecore\*"
$allSitecoreUsers | ForEach-Object {
Write-Host $_.Name
}
9. Get and edit an item
$item = Get-Item master:/content/home
$item.Editing.BeginEdit();
$item["Title"] = "New title for the home item!";
$item.Editing.EndEdit();
10. Generate google sitemap XML
$xmlWriter = New-Object System.XMl.XmlTextWriter('c:\temp\sitemap.xml',$Null)
$xmlWriter.Formatting = 'Indented'
$xmlWriter.Indentation = 1
$XmlWriter.IndentChar = "`t"
$xmlWriter.WriteStartDocument()
$xmlWriter.WriteStartElement('urlset')
$XmlWriter.WriteAttributeString('xmlns', 'http://www.sitemaps.org/schemas/sitemap/0.9')
$everythingUnderHome = Get-Item master: -Query "/sitecore/content/Home//*"
$baseUrl = "https://example.com"
$everythingUnderHome | ForEach-Object {
$url = $baseUrl + [Sitecore.Links.LinkManager]::GetItemUrl($_)
$xmlWriter.WriteStartElement('url')
$xmlWriter.WriteElementString('loc',$url)
$xmlWriter.WriteEndElement()
}
$xmlWriter.WriteEndElement()
$xmlWriter.WriteEndDocument()
$xmlWriter.Flush()
$xmlWriter.Close()
11. Exclude template
$item = Get-Item -Path master: -Query "/sitecore/content//*[@@templatename !='Sample Item']"
#Or
$item = Get-Item -Path master: -Query "/sitecore/content//*" | Where-Object { $_.TemplateName -ne "Sample Item" -and $_.TemplateName -ne "Local Datasource
12. Create users from CSV
$csv = Import-Csv "C:\temp\my-csv-file.csv"
foreach($row in $csv)
{
if ($row -eq $csv[0])
{
#Skip the first row as it contains the column headings in your CSV
continue;
}
#New-User docs: https://doc.sitecorepowershell.com/appendix/commands/New-User.html
#Include domain in username to specify the target domain (e.g extranet\adam)
New-User -Identity $row."Username" -Enabled -Password $row."Password" -Email $row."Email" -FullName $row."FullName"
}
13. Create an item
$item = New-Item "master:/content/home/my new sample item" -type "Sample/Sample Item"
14. Convert datetime field value to DateTime object
$dateTime = ([sitecore.dateutil]::IsoDateToDateTime($item["My Date Field"])
Write-Host $dateTime.ToString("dd MMMM yyyy")
#Output 10 September 2016
15. Change item template
$item = Get-Item master:/content/home
$newTemplate = [Sitecore.Configuration.Factory]::GetDatabase("master").Templates["Sample/Sample Item"];
$item.ChangeTemplate($newTemplate)
16. Add base template
$targetTemplate = Get-item 'master:/sitecore/templates/User Defined/Common/Data';
$templateFilter = Get-Item "master:/sitecore/templates/System/Templates/Template";
$templateToBeAddAsBaseTemplate = Get-Item 'master:/sitecore/templates/User Defined/Common/Data/Carousel'
Get-ChildItem $targetTemplate.FullPath -recurse | Where-Object { $_.TemplateName -eq $templateFilter.Name -and $_.Name -eq "promo"} | ForEach-Object {
if(-not ($_."__Base template" -match "$($templateToBeAddAsBaseTemplate.Id)")){
#If not exist then add
$_."__Base template" = "$( $_."__Base template")|$($templateToBeAddAsBaseTemplate.Id)"
}
}
17. Parse a Rich Text to replace elements
The easiest solution is probably to find and replace characters rather than parse all of the html:
# Home Item
$rootId = "{110D559F-DEA5-42EA-9C1C-8A5DF7E70EF9}"
# Get only the immediate children
$items = @((Get-ChildItem -Path "master:" -ID $rootId))
foreach($item in $items) {
$html = $item.Text
if([String]::IsNullOrEmpty($html)) { continue }
$newText = $html.Replace("
", "")
$item.Text = $newText
}
18. Generate a hash of a media file
#Generate MD5 Hash of item
function To-Byte-Array
{
param (
[CmdletBinding()]
[Parameter(Mandatory = $true)]
[AllowEmptyString()]
[AllowEmptyCollection()]
[AllowNull()]
[Object]
$InputStream)
$InputStream.Position = 0
$buffer = New-Object byte[] $InputStream.Length
$i = 0
For ($totalBytesCopied=0; $totalBytesCopied -lt $InputStream.Length; $i++) {
$totalBytesCopied += $InputStream.Read($buffer, $totalBytesCopied, $InputStream.Length - $totalBytesCopied)
}
$buffer
}
$item = Get-Item master: -ID "{20AA9D26-F1D6-43DB-B8A8-21EC04A5A4CB}" -Language de-DE
$mediaItem = New-Object Sitecore.Data.Items.MediaItem($item)
$media = [Sitecore.Resources.Media.MediaManager]::GetMedia($mediaItem)
$stream = $media.GetStream().Stream
try {
$bytes = To-Byte-Array $stream
}
finally
{
if ($null -ne $stream -and $stream -is [System.IDisposable])
{
$stream.Dispose()
}
}
$md5 = new-object -TypeName System.Security.Cryptography.MD5CryptoServiceProvider
$hash = [System.BitConverter]::ToString($md5.ComputeHash($bytes))
Write-Host $hash
19. Exporting the username and custom properties
$property = @(
"Name",
@{Name='Email';Expression={ $PSItem.Profile.GetCustomProperty('Email') }},
@{Name='FirstName';Expression={ $PSItem.Profile.GetCustomProperty('FirstName') }},
@{Name='LastName';Expression={ $PSItem.Profile.GetCustomProperty('LastName') }},
@{Name='Title';Expression={ $PSItem.Profile.GetCustomProperty('Title') }},
@{Name='Company';Expression={ $PSItem.Profile.GetCustomProperty('Company') }},
@{Name='Country';Expression={ $PSItem.Profile.GetCustomProperty('Country') }},
@{Name='ZipCode';Expression={ $PSItem.Profile.GetCustomProperty('ZipCode') }},
@{Name='Department';Expression={ $PSItem.Profile.GetCustomProperty('Department') }},
@{Name='Street';Expression={ $PSItem.Profile.GetCustomProperty('Street') }},
@{Name='City';Expression={ $PSItem.Profile.GetCustomProperty('City') }},
@{Name='Phone';Expression={ $PSItem.Profile.GetCustomProperty('Phone') }},
@{Name='Username';Expression={ $PSItem.Profile.GetCustomProperty('Username') }},
)
# Gets not disabled extranet users, next select all customer properties and save all properties to CSV file
Get-User -Filter 'extranet\*' `
| Where-Object { $_.Profile.State -ne 'Disabled' } `
| Select-Object -Property $property `
| Export-CSV -Path "$apppath\extranet-enabled-uc.csv" -notype -encoding "unicode"
Download-File "$apppath\extranet-enabled-uc.csv"
20. Show List View with all users' properties
[System.Web.Security.Membership]::GetAllUsers() |
Show-ListView -Property @{Label="User"; Expression={ $_.UserName} },
@{Label="Is Online"; Expression={ $_.IsOnline} },
@{Label="Creation Date"; Expression={ $_.CreationDate} },
@{Label="Last Login Date"; Expression={ $_.LastLoginDate} },
@{Label="Last Activity Date"; Expression={ $_.LastActivityDate } }
21. Set workflow for all items
## 1. Set default workflow state in template’s standard value ##
## 2. Before running script, must set correct Context Item ##
##################################################################
function SetWorkflow($item)
{
## Update only items assigned __Default workflow
if ($item.”__Default workflow” -eq “{A5BC37E7-ED96-4C1E-8590-A26E64DB55EA}”) {
$item.__Workflow = “{A5BC37E7-ED96-4C1E-8590-A26E64DB55EA}”;
$item.”__Workflow state” = “{190B1C84-F1BE-47ED-AA41-F42193D9C8FC}”;
}
}
## Update correct workflow information.
## Uncomment below two lines if you are ready to go for updating
#get-item . -Language * | foreach-object { SetWorkFlow($_) }
#get-childitem . -recurse -Language * | foreach-object { SetWorkFlow($_) }
## Show Updated Result
get-item . -Language * | Format-Table Id, Name, Language, __Workflow, “__Workflow state”, “__Default workflow”
get-childitem . -recurse -Language * | Format-Table Id, Name, Language, __Workflow, “__Workflow state”, “__Default workflow”
22. Unlock items of a template recursively
Get-ChildItem -Path master:\content\home -Recurse |
Where-Object { $_.TemplateId -eq "{ENTER_YOUR_TEMPLATE_GUID}"} |
Unlock-Item -PassThru
23. Zip and download sitecore media library folder
#
# The ZipFiles function is based on noam's answer
# on the following Stack Overflow's page: http://bit.ly/PsZip
#
function ZipItems( $zipArchive, $sourcedir )
{
Set-Location $sourcedir
[System.Reflection.Assembly]::Load("WindowsBase,Version=3.0.0.0, `
Culture=neutral, PublicKeyToken=31bf3856ad364e35") | Out-Null
$ZipPackage=[System.IO.Packaging.ZipPackage]::Open($zipArchive, `
[System.IO.FileMode]::OpenOrCreate, [System.IO.FileAccess]::ReadWrite)
$items = gci -recurse $sourceDir
[byte[]]$buff = new-object byte[] 40960
$i = 0;
ForEach ($item In $items) {
$i++
if([Sitecore.Resources.Media.MediaManager]::HasMediaContent($item)){
$mediaItem = New-Object "Sitecore.Data.Items.MediaItem" $item;
$mediaStream = $mediaItem.GetMediaStream();
$fileName = Resolve-Path -Path $item.ProviderPath -Relative
$fileName = "$fileName.$($item.Extension)" `
-replace "\\","/" -replace "./", "/"
# Print out the file - the list will show up once the file is downloaded
"Added: $fileName"
# Show progress for the operation
Write-Progress -Activity "Zipping Files " `
-CurrentOperation "Adding $fileName" `
-Status "$i out of $($items.Length)" `
-PercentComplete ($i *100 / $items.Length)
$partUri = New-Object System.Uri($fileName, [System.UriKind]::Relative)
$partUri = [System.IO.Packaging.PackUriHelper]::CreatePartUri($partUri);
$part = $ZipPackage.CreatePart($partUri, `
"application/zip", `
[System.IO.Packaging.CompressionOption]::Maximum)
$stream=$part.GetStream();
do {
$count = $mediaStream.Read($buff, 0, $buff.Length)
$stream.Write($buff, 0, $count)
} while ($count -gt 0)
$stream.Close()
$mediaStream.Close()
}
}
$ZipPackage.Close()
}
#the location will be set by PowerShell automatically based on which item was clicked
$location = get-location
$dateTime = Get-Date -format "yyyy-MM-d_hhmmss"
$zipName = Split-Path -leaf $location | % { $_ -replace " ", ""}
$dataFolder = [Sitecore.Configuration.Settings]::DataFolder
$zipPath = "$dataFolder\$zipName-$datetime.zip"
# Call the Zipping function
ZipItems $zipPath $location
#Send user the file, add -NoDialog if you want to skip the download dialogue
Download-File -FullName $zipPath | Out-Null
# Clean up after yourself
Remove-Item $zipPath
# Close the results window - we don't really need to see the results
Close-Window
24. Zip and download logs
#
# The ZipFiles function is based on noam's answer
# on the following Stack Overflow's page: http://bit.ly/PsZip
#
function ZipFiles( $zipArchive, $sourcedir )
{
[System.Reflection.Assembly]::Load("WindowsBase,Version=3.0.0.0, `
Culture=neutral, PublicKeyToken=31bf3856ad364e35") | Out-Null
$ZipPackage=[System.IO.Packaging.ZipPackage]::Open($zipArchive, `
[System.IO.FileMode]::OpenOrCreate, [System.IO.FileAccess]::ReadWrite)
$in = gci $sourceDir | select -expand fullName
[array]$files = $in -replace "C:","" -replace "\\","/"
ForEach ($file In $files) {
$fileName = [System.IO.Path]::GetFileName($file);
$partName=New-Object System.Uri($file, [System.UriKind]::Relative)
$part=$ZipPackage.CreatePart("/$fileName", "application/zip", `
[System.IO.Packaging.CompressionOption]::Maximum)
Try{
$bytes=[System.IO.File]::ReadAllBytes($file)
}Catch{
$_.Exception.ErrorRecord.Exception
}
$stream=$part.GetStream()
$stream.Write($bytes, 0, $bytes.Length)
$stream.Close()
}
$ZipPackage.Close()
}
# Get Sitecore folders and format the zip file name
$dateTime = Get-Date -format "yyyy-MM-d_hhmmss"
$dataFolder = [Sitecore.Configuration.Settings]::DataFolder
$logsFolder = [Sitecore.Configuration.Settings]::LogFolder
$myZipFile = "$dataFolder\logs-$datetime.zip"
# Warn that the user log files will fail to zip
Write-Host -f Yellow "Zipping files locked by Sitecore will fail." -n
Write-Host -f Yellow "Files listed below were used."
# Zip the log files
ZipFiles $myZipFile $LogsFolder
#Download the zipped logs
Get-File -FullName $myZipFile | Out-Null
#Delete the zipped logs from t
25. Updating renderings properties to enable VaryByData
$items = Get-ChildItem -Recurse | Where-Object {$_.TemplateID -match “{79A0F7AB-17C8-422C-B927-82A1EC666ABC}”} | ForEach-Object {
$renderingInstance = Get-Rendering -Item $_ -Rendering $rendering
if($renderingInstance){
$renderingInstance.VaryByData = 1
Set-Rendering -Item $_ -Instance $renderingInstance
}
}
26. New media item
function New-MediaItem{
[CmdletBinding()]
param(
[Parameter(Position=0, Mandatory=$true, ValueFromPipeline=$true)]
[ValidateNotNullOrEmpty()]
[string]$filePath,
[Parameter(Position=1, Mandatory=$true)]
[ValidateNotNullOrEmpty()]
[string]$mediaPath)
$mco = New-Object Sitecore.Resources.Media.MediaCreatorOptions
$mco.Database = [Sitecore.Configuration.Factory]::GetDatabase("master");
$mco.Language = [Sitecore.Globalization.Language]::Parse("en");
$mco.Versioned = [Sitecore.Configuration.Settings+Media]::UploadAsVersionableByDefault;
$mco.Destination = "$($mediaPath)/$([System.IO.Path]::GetFileNameWithoutExtension($filePath))";
$mc = New-Object Sitecore.Resources.Media.MediaCreator
$mc.CreateFromFile($filepath, $mco);
}
# Usage example
New-MediaItem "C:\Users\Adam\Desktop\Accelerators.jpg" "$([Sitecore.Constants]::MediaLibraryPath)/Images"
27. Update media item
function Update-MediaItem{
[CmdletBinding()]
param(
[Parameter(Position=0, Mandatory=$true, ValueFromPipeline=$true)]
[ValidateNotNullOrEmpty()]
[string]$filePath,
[Parameter(Position=1, Mandatory=$true)]
[ValidateNotNullOrEmpty()]
[string]$mediaPath)
[Sitecore.Data.Items.MediaItem]$item = gi $mediaPath
[Sitecore.Resources.Media.Media] $media = [Sitecore.Resources.Media.MediaManager]::GetMedia($item);
$extension = [System.IO.Path]::GetExtension($filePath);
$stream = New-Object -TypeName System.IO.FileStream -ArgumentList $filePath, "Open", "Read"
$media.SetStream($stream, $extension);
$stream.Close();
}
# Usage example - overwrite the image created with previous cmdlet with new image
Update-MediaItem "$SitecoreDataFolder\Tchotchkeys.jpg" "$([Sitecore.Constants]::MediaLibraryPath)/Images/Accelerators"
28. List Roles for User
function Get-UserRoles{
[CmdletBinding()]
param(
[Parameter(Mandatory=$true, Position=0)]
[string]$Identity
)
$user = Get-User $Identity
return Get-Role -Filter * | Where-Object { $_.IsMember($user,$true,$true) }
}
Write-Host "Roles for ServicesAPI" -ForegroundColor Green
Get-UserRoles "sitecore\ServicesAPI"
Write-Host "Roles for Admin" -ForegroundColor Green
Get-UserRoles "sitecore\admin"
29. Remove unused media items
#Include all paths you do not want to analyse below
$protectedPaths = @(
"/sitecore/media library/System/",
"/sitecore/media library/Experience Explorer"
"/sitecore/media library/Images/Social"
);
#Include all item templates you want to ignore in the array below
$protectedTemplates = @(
[Sitecore.TemplateIDs]::MediaFolder
);
$itemsToDelete =
Get-ChildItem -Path "master:\sitecore\media library" -Recurse |
# filter out items of templates you do not want to touch
Where-Object { $_.TemplateID -notin $protectedTemplates } |
# do not allow items in the protected paths
Where-Object {
$item = $_;
$protected = $protectedPaths | Where-Object { ($item.Paths.Path) -match $_ };
$protected.Count -lt 1;
} |
# and only items that are not used
Where-Object { [Sitecore.Globals]::LinkDatabase.GetReferrerCount($_) -eq 0 }
#List the items
$itemsToDelete | ft ProviderPath
#If the list above looks like what you want to delete you can uncomment the following line
#$itemsToDelete | Remove-Item
30. Get items modified in last 7 days
$days = 7;
Read-Variable -Parameters @{ Name="days"; Title="Number of days"} -Title "Pointy haired report" | Out-Null
Get-ChildItem master:\content\home -Recurse |
? { $_."__updated" -gt (Get-Date).AddDays(-$days) } |
Show-ListView -Property ID, Name, "__updated", "__updated by"