A little corner of the Empire on the web.

11 July, 2016

Find objects within folders in the SCCM Console hierarchy using PowerShell


Ever since Microsoft's SCCM got the new-style System Centre console with SCCM 2012, I've been massively frustrated about how difficult it is to find items in the console once you've organised it with folders. Probably not too much of a problem if you're a lone SCCM admin, but as someone who works as part of a larger team who all use SCCM for slightly different reasons it can be a nightmare finding things like collections buried deep in the folder hierarchy.

Yes, I know that the console has a search function, and I know that there's a subtle "All Subfolders" button that magically appears on the Search ribbon bar sometimes. However that "All Subfolders" button has a few major flaws: 1) it doesn't always appear when it ought to, leaving you in a dance of clicking in the search text box, clicking away, clicking back in there, clicking away to another part of the console, clicking back, all the while crossing your fingers that the button will show up; 2) annoyingly clicking the "All Subfolders" button clears out any text that you may have foolishly typed into the search bar already before you remembered that you wanted to search the whole tree; 3) most importantly, the search results don't give you any information about the folder path that it found each item on, so it doesn't help you find that item (or similar items that may be in the same folder) quickly next time.

SCCM console rant over.


So over time I started casually looking around for ways to access this folder hierarchy info. These days there's a regularly updated set of SCCM PowerShell Cmdlets provided by the ConfgMgr team, this seemed an obvious place to start. Unfortunately, none of them even acknowledge that console folders exist. Next I set off on a hunt through WMI on the site server (using one of my favourite tools WMI Explorer (WMI Explorer downloads), but I couldn't any folder related properties on the collections/packages/etc themselves and couldn't find any obvious looking WMI classes. Real desperation now, open up SQL Management Studio and hunt through the Views in the site database. Nothing obvious. Brick wall hit. I went away and worked on other stuff for a while.


Then early last week I came across this blog post by Peter van der Woude, that my previous searches had somehow missed: More than just ConfigMgr: Get the folder location of an object in ConfigMgr 2012 via PowerShell. Finally, answers - not only did that post contain this magic phrase: A good thing to know is that all folder information is stored in two classes in WMI, SMS_ObjectContainerNode and SMS_ObjectContainerItem. These two classes are the same for every object type., but it also had a working script linked, find his script in the TechNet gallery here: TechNet Gallery: Get the location of an object in the console via PowerShell

Moving Beyond

As great and useful as Peter's script was, it does have a minor flaw, and doesn't handle some edge cases. So I set off to use his information to write my own. The minor flaw was that his script requires hard coding your SMS Site Code and Site Server names into it. I can see the reason for that, especially as it means that his script has no external dependencies (other than the ConfigMgr infrastructure, obviously) but it still bugged me. More problematically, I hit an edge case that it didn't handle within my first few uses of it. Some objects (of different types) in SCCM can share the same SCCM IDs. So a Collection, a Query and a Package could have the same 8 character ([site code][5 hex digits]) ID, as all of those objects have their own numbering starting from XXX00001 and counting upwards. So using Peter's script, you don't always find the object that you're actually looking for, and, as his doesn't echo the name or type of the object that it's showing the hierarchy for, it can get quite confusing if it's not showing the info for the item that you're expecting.

Nirvana (or Farvana)

So, I've written my own PowerShell function to do this: Get-SCCMObjectLocation, find the code on GitHub, here GitHub: Get-SCCMObjectLocation.ps1. There's a bit more code here than Peter's versions, but this now outputs the object's name and type (so that you know you haven't made any typos, and you really have found the droids object you were looking for), and if there are multiple objects with the same ID, it lists them one by one. It also gets the site code and site server name from the ConfigurationManager PowerShell provider, though this does mean that you need the SCCM console installed on your machine, and you need to change to ConfigurationManager's PSDrive before running it.

PS C:\>Get-SCCMObjectLocation -SMSId "ABC001BB"
root\Racked Server Drivers\Dell\PE1950-Microsoft Windows 2008 R2 SP1-OM7.3  [SMS_DriverPackage]
PS C:\>"ABC000CC" | Get-SCCMObjectLocation
WARNING: Multiple objects with ID: ABC000CC
root\x64\Test\Win 7 Ent x64 with Office 2010  [SMS_ImagePackage]
root\Servers\Server roles\All Domain Controllers  [SMS_Collection_Device]
PS C:\>Get-SCCMObjectLocation -SMSId "ABC00166" -SiteCode ABC -SiteServerName sms01.example.com
root\Application Deployment\MS Access App-V  [SMS_Collection_User]


Download the script here: GitHub: Get-SCCMObjectLocation.ps1

Music to get through this with: Faithless - Faithless 2.0