Properly checking if an item in a folder is a Directory or not in PowerShell

PowerShell header

Got a great tip from a colleague, on how to properly check if an item is a file or a directory. In one case, we weren’t really ever sure, if another script had finished its running and unzipped a certain zip package into a folder – and we had to verify it had, before continuing the execution. Our initial implementation worked most of the time… But not quite always. The purpose of this blog post is to explain how we found a pretty well working and elegant solution!

Problem

In this particular case, we were testing items for being directories with the following script:

$item = Get-ChildItem -Path [path_to_item]
if ($item -eq $null -or $item.Attributes -ne "Directory") {

However, that doesn’t work that well, as it breaks with whatever additional attributes being applied to the file or folder. And there’s a lot of situations, where new attributes get added to items in a folder. One good example is “NotContentIndexed”, which gets added if you (or whatever piece of automation) sets the file to be excluded from Windows Search index. See the references for more details about the attributes!

After some back and forth, we ended up improving the script in a few ways. 

Solution

The following code example shows a rough idea of how that works. In this example, we needed to test if a zip file was unzipped by a script that ran earlier, and then proceed with the execution.

$item = Get-ChildItem -Path [path_including_name_without_extension] -Directory | select -first 1
if ($item -eq $null -or ($item.Attributes -band [IO.FileAttributes]::Directory) -ne [IO.FileAttributes]::Directory) { 
   Write-Host "The file is missing or not unzipped inside the folder, please unzip it!" -ForegroundColor Red 
}

Let’s dissect this a bit – so what are we actually doing?

In this code example, we start by getting an item from a path, where we KNOW that a zip package used to be located.

$item = Get-ChildItem -Path [path_including_name_without_extension] -Directory | select -first 1

Even if the zip package still is there, it’ll ignore it and only get the directories, and select the first one that matches the path. See for an example below:

Get-ChildItem example with -Directory flag and pipe to select

Get-ChildItem example with -Directory flag and pipe to select

The next part will only run the code inside the IF-block if the item we have is not a directory. In this example, the whole block is just a Write-Host command which complains about the lack of a folder.

if ($item -eq $null -or ($item.Attributes -band [IO.FileAttributes]::Directory) -ne [IO.FileAttributes]::Directory)

The first part of the clause is pretty clear – if we didn’t get anything with the Get-ChildItem, the variable is $null, and we’re going to go into the If block.

The latter part of the clause performs a “bitwise and” comparison between an enum (System.IO.FileAttributes is an enum type) and the flag (value of the enum) for Directory, and will return 0 (if none of the attributes match Directory) or the flag for Directory ([IO.FileAttributes]::Directory).

The return value is then compared to [IO.FileAttributes]::Directory – this should be a pretty surefire way of making sure we’ve got the right item 🙂

   Write-Host "The folder is missing or not unzipped, please unzip it!" -ForegroundColor Red

In the end, if we do end up in the IF block, we complain about the folder missing. And like any good script, we complain in RED.

Get-ChildItem example with a missing Folder

Get-ChildItem example with a missing Folder

Good stuff.

References

The following two tabs change content below.

Antti K. Koskela

Solutions Architect / Escalations Engineer at Koskila / Norppandalotti Software / Valo Solutions
Antti Koskela is a proud digital native nomadic millenial full stack developer (is that enough funny buzzwords? That's definitely enough funny buzzwords!), who works as a Solutions Architect for Valo Intranet, the product that will make you fall in love with your intranet. Working with the global partner network, he's responsible for the success of Valo deployments happening all around the world. He's been a developer from 2004 (starting with PHP and Java), and he's been bending and twisting SharePoint into different shapes since MOSS. Nowadays he's not only working on SharePoint, but also on .NET projects, Azure, Office 365 and a lot of other stuff.This is his personal professional (e.g. professional, but definitely personal) blog.

Let me know your thoughts!