How To Find Items That Don’t Have Any Language Versions Using Powershell

Recently, I ran across a problem using traditional Powershell commands. I was trying to identify items that did not have any associated language version. There are various ways that an item can get to this state. I won’t get into these cases here, as they are typically specific to the implementation. But, what’s certain across all cases is that these items cause problems because they (and their descendants) don’t get published. This causes a lot of confusion because what you see in Experience Editor ends up not matching what you see on the front-end site.

The problem is, all the traditional Powershell commands that retrieve items require a -Language param to retrieve specific versions. I specifically needed to identify unversioned items. If you leave the language param off, it will use “en” as the default choice. If you pass an empty string for this param, it will return all versions of items that have language versions. That’s great, but I still hadn’t uncovered the items without a language version.

If you want to reproduce it, just create a new item, then go to the “Versions” tab and delete the current version.

sitecore item with no versions in any language

Here is a great Powershell work around.

Since I couldn’t use Get-ChildItems to get my unversioned items, I had the idea to look for items that have a collective count of all language versions equal to 0. My friend CJ helped out by showing me that I can use $item.Versions.GetType() to get the .Net class name of the object I’m working with. This allowed me to decompile this class with Resharper to find what methods it exposes. As it turns out, it has a method GetVersions(bool includeAllLanguages) that returns an array of items. This is the perfect method to leverage since I can test for an empty count to determine if it’s one of the unversioned items. Here’s the final code block that CJ and I ended up with.

# point this to the root of your website
$folder = "/sitecore/content"
 
 
# you can combine the Where-Object clause with other tests
# like Name or Template if you are looking for something specific
$items = Get-ChildItem -Path $folder -recurse | `
Where-Object { $_.Versions.GetVersions($true).Count -eq 0 } | `
%{
        [PSCustomObject]@{
            "ID" = $_.ID
            "ItemName" = $_.Name
            "Item" = $_
            "ItemPath" = $_.Paths.Path
        }
}
 
# this will print out any results that it finds
$items

I hope this work around will save you some time and frustration. As I mentioned, being able to identify these items is critical to resolving the conflict between what you are seeing in the Experience Editor and what is showing on the front-end site.

Happy coding! Until next time.

Anastasiya

Anastasiya Flynn

I am a front-to-back, full-stack developer with 7 years of experience in the CMS world – Sitecore and beyond. I excel in the technical aspects of software development and architecture but, personally, I really enjoy working on UI development. I am capable of detaching from my developer brain and analyzing the output from a non-technical perspective, anticipating the challenges end users will experience.

My career started out in the support department, and I keep the lessons I learned there close to my heart. When working on a project, my first priority is to amaze our customer. My second priority is to enforce practices that will make the code a pleasure to maintain. I am not the type of person who is satisfied with producing software that merely works – I am emotionally connected. I want the code to be organized and beautiful, and I am personally invested in its success, usability and longevity. Learn more about Anastasiya Flynn.

1 comment on How To Find Items That Don’t Have Any Language Versions Using Powershell

Michael L WestJuly 27, 2017 - Reply

Very cool. Thanks for sharing. Give `Get-Member` a try. It can be used to inspect objects. `$item.Versions | Get-Member`

Add a Comment

Your email address will not be published. Required fields are marked *

Or request call back