Search code examples
powershellget-childitemjunction

Exclude Junction-Points in Get-ChildItem


I'd like to get a list of all user-created folders in the C:\ drive. However I'm getting false results because of junction points. I tried

$generalExclude += @("Users", "LocalData", "PerfLogs", "Program Files", "Program Files (x86)", "ProgramData", "sysdat", "Windows", "eplatform", "Intel", "Recovery",  "OneDriveTemp")

Get-ChildItem "\\localhost\c$" -Directory -force -Exclude $generalExclude -ErrorAction 'silentlycontinue' | Where-Object $_.Attributes.ToString() -NotLike "ReparsePoint"

But I get a

You cannot call a method on a null-valued expression error.


Solution

  • I guess you are missing the braces{} for your scriptblock in your Where-Object cmdlet. Also the -notlike operator uses wildcard for search operation.

    Get-ChildItem "\\localhost\c$" -Directory -force -Exclude $generalExclude -erroraction 'silentlycontinue' | Where-Object {$_.Attributes.ToString() -NotLike "*ReparsePoint*"}
    

    As per the msdn document for the Where-Object cmdlet, you will see there are two ways to construct a Where-Object command.

    Method 1

    Script block.

    You can use a script block to specify the property name, a comparison operator, and a property value. Where-Object returns all objects for which the script block statement is true.

    For example, the following command gets processes in the Normal priority class, that is, processes where the value of the PriorityClass property equals Normal.

    Get-Process | Where-Object {$_.PriorityClass -eq "Normal"}
    

    Method 2

    Comparison statement.

    You can also write a comparison statement, which is much more like natural language. Comparison statements were introduced in Windows PowerShell 3.0.

    For example, the following commands also get processes that have a priority class of Normal. These commands are equivalent and can be used interchangeably.

    Get-Process | Where-Object -Property PriorityClass -eq -Value "Normal"
    
    Get-Process | Where-Object PriorityClass -eq "Normal"
    

    Additional Info -

    Starting in Windows PowerShell 3.0, Where-Object adds comparison operators as parameters in a Where-Object command. Unless specified, all operators are case-insensitive. Prior to Windows PowerShell 3.0, the comparison operators in the Windows PowerShell language could be used only in script blocks.

    In your case, you are constructing the Where-Object as a scriptblock and hence braces{} become a necessary evil. Alternatively, you can construct your Where-Object in the following ways -

    Get-ChildItem "\\localhost\c$" -Directory -force -Exclude $generalExclude -erroraction 'silentlycontinue' | Where-Object Attributes -NotLike "*ReparsePoint*"
    

    (OR)

    Get-ChildItem "\\localhost\c$" -Directory -force -Exclude $generalExclude -erroraction 'silentlycontinue' | Where-Object -property Attributes -NotLike -value "*ReparsePoint*"