Multiple -and -or in Powershell Where-Object Statement
PS H:\> Invoke-Command -computername SERVERNAME { Get-ChildItem -path E:\dfsroots\datastore2\public} | Where-Object {{ $_.e
xtension-match "xls" -or $_.extension-match "xlk" } -and  { $_.creationtime -ge "06/01/2014"}}

Above is my code example. I'm trying to remotely run this PowerShell code on my file server and have it return all .xls and .xlk files with a creation date on or later than 6/1/2014. When I run this code it starts spitting out all of the folders in that remote location. If I only compare two things like so:

PS H:\> Invoke-Command -computername SERVERNAME { Get-ChildItem -path E:\dfsroots\datastore2\public} | Where-Object { $_.extension-match "xls" -and  $_.creationtime -ge "06/01/2014"}

Only the xls files created on or after that date display. What's going on here? Do I need to use something other than nest -and and -or statements?

6

3 Answers

By wrapping your comparisons in {} in your first example you are creating ScriptBlocks; so the PowerShell interpreter views it as Where-Object { <ScriptBlock> -and <ScriptBlock> }. Since the -and operator operates on boolean values, PowerShell casts the ScriptBlocks to boolean values. In PowerShell anything that is not empty, zero or null is true. The statement then looks like Where-Object { $true -and $true } which is always true.

Instead of using {}, use parentheses ().

Also you want to use -eq instead of -match since match uses regex and will be true if the pattern is found anywhere in the string (try: 'xlsx' -match 'xls').

Invoke-Command -computername SERVERNAME { 
    Get-ChildItem -path E:\dfsroots\datastore2\public | 
        Where-Object {($_.extension -eq ".xls" -or $_.extension -eq ".xlk") -and ($_.creationtime -ge "06/01/2014")}
}

A better option is to filter the extensions at the Get-ChildItem command.

Invoke-Command -computername SERVERNAME { 
    Get-ChildItem -path E:\dfsroots\datastore2\public\* -Include *.xls, *.xlk | 
        Where-Object {$_.creationtime -ge "06/01/2014"}
}
2

You're using curvy-braces when you should be using parentheses.

A where statement is kept inside a scriptblock, which is defined using curvy baces { }. To isolate/wrap you tests, you should use parentheses ().

I would also suggest trying to do the filtering on the remote computer. Try:

Invoke-Command -computername SERVERNAME {
    Get-ChildItem -path E:\dfsroots\datastore2\public |
    Where-Object { ($_.extension -eq "xls" -or $_.extension -eq "xlk") -and $_.creationtime -ge "06/01/2014" }
}
2

I found the solution here:

How to properly -filter multiple strings in a PowerShell copy script

You have to use -Include flag for Get-ChildItem

My Example:

$Location = "C:\user\files" 
$result = (Get-ChildItem $Location\* -Include *.png, *.gif, *.jpg)

Dont forget put "*" after path location.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Alexander Ross

Alexander Ross

Gaming, Esports & Interactive Media Writer

Alexander Ross has covered the video game industry for a decade, writing deep dives on game design, esports tournaments, VR developments, and gaming culture.

Share this article
Twitter Facebook Pinterest