Efficiently Finding Folder Paths in ConfigMgr Using PowerShell

Are you currently spending an extensive amount of time to find folder paths within ConfigMgr device collections?  In this blog post we will walk through three methods and demonstrate how using different data structures can decrease the time spent when querying for large amounts of data.

Query Method
One approach is to grab a list of all device collections, loop through the list, and query the server for the path of each collection in the list. When using Measure-Command, the Query.ps1 script in my ConfigMgr environment (with 189 collections, 162 of which are in folders, and 118 collection folders), I get a time of 1 minute 9 seconds – quite a long time!  The problem with this method is that it creates a new WMI connection for each folder that is in a path, and also for each device collection.  If we could reduce the number of connections required, we could reduce the amount of time it takes to print the folder paths.

Array Method
One way of reducing the amount of time required is to load all of the SMS_ObjectContainerNode objects and SMS_ObjectContainerItem objects up front, and loop through these when finding the folder paths. When running Measure-Command on the Array.ps1 script, the time is reduced to 10 seconds – a significant improvement.  However, we can still do better.  The problem with this method is that we are looping through the list of folders for each folder that exists, which can become slow for large amounts of folders.  The amount of time required to compute the folder path increases quadratically as the number of folders increases.

Hashtable Method
If we use hashtables that are indexed by the property that we want to look up, we can remove the need for looping through an array of objects. Running Measure-Command on the Hashtable.ps1 script gets us down to 2.81 seconds.  We’ve managed to reduce the time required by over 2/3 just by using a data structure that is better suited to the job.

The moral of the story is that if you find yourself repeatedly looping through an array to find an item with a certain property, consider using a hashtable indexed by that property instead.

Testing Methods
To get a better idea of how these types of decisions can affect performance, I wrote a script that would create 1000 nested folders, and on every 20th folder would add a collection and time the execution of the three methodologies.  The result looked something like this:

I ended up with 150 data points that took over 8 hours to gather, and the array method took almost 94% of the total time!

timevsfolders

I purposefully chose a scenario in which the array method would perform poorly to show that it’s important to understand how choices in data structures can affect performance.  While the array method seemed to work well in my production environment, it’s clear from these results that it will not necessarily perform well in all environments.  If we change our view of the data to logarithmic, we can see that for smaller folder counts the array method performs somewhere between the hashtable and query methods.

timevsfolderslog

I would recommend using the hashtable method for looking up folder paths as it should perform better than either of the other methods in most scenarios.  All three scripts are available here for your use.