Get-ChildItem and the ‘Shortcut-Hell’

Through a little workaround I had to do, I found out a really anyoing bug in the Get-Childitem cmdlet. On a very huge filesystem, which is used by normally users, the ACLs must be checked regulary. That’s because some files are cutted and not copied. In this case the files have the ACLs from the source location.
The simple solution was an execution of icacls down the complete filestructure. But right, this was too simple for me 😉
The idea was to check every file before running icacls. Why using the wrecking ball when you could correct a mistake only if it is existing?To check every item, you need to collect them in an object array or something else. In my case, I used a ArrayList.

Then I used the simple Get-ChildItem cmdlet with the recursive parameter to collect thousands of files and folders. But the Powershell throwed an exception after some hours. What happened?

In the deeps of the share lay some shortcuts to other shares. The Get-ChildItem cmdlet doesn’t filter these types of files and run into a huge endless loop. So I must getting rid of these shortcuts and get only natural files and folders. And there we have a good old System-Class: System.IO. With this class we can proof if there is a File-Info and an Directory-Info when we have the object.

Unfortunately we cannot pipe such command with the Get-ChildItem and the recurse parameter. So I had to write an function which does exatcly this: Get alle objects of an share which are an regulary file oder folder.

The function is using the simple Get-ChildItem cmdlet without the recurse parameter. Instead the function checks, if the object is an file oder folder. It is an file, the object is going into the array. If it is an folder, the object is also going into the array, but the function is called itself again with this folder object. Recursive function calling. This runs till all objects are processed under the orignally given path from the first call of the function. To avoid errors with system based objects, recycle- and volume-information-objects are ignored.

Nice bonus: This solution is much faster than the recursive parameter in the get-ChildItem cmdlet 🙂

Leave a Comment