56
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?

Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
Winski Tech
  • 579
  • 1
  • 6
  • 8
  • Note that breaking down the command into multiple "where" statements didn't work either. I'd enter a command like: PS H:\> Invoke-Command -computername SERVERNAME { Get-ChildItem -path E:\dfsroots\datastore2\public} | Where-Object { $_.ex tension-match "xls" -or $_.extension-match "xlk" } | where-object { $_.creationtime -ge "06/01/2014"} And it starts spitting out xlsx files which is not what I want. – Winski Tech Jul 10 '14 at 17:46
  • 3
    Use parenthesis not curly brackets to enclose options, so `Where{($_.Extension -Match "xls" -or $_.Extension -Match "xlk") -and $_.CreationTime -ge "06/01/2014"}` – TheMadTechnician Jul 10 '14 at 17:54
  • @TheMadTechnician if you could help me just a minute I cannot figure out what mini-Markdown formatting works and what doesn't. How did you enclose that in a "code" block? – Winski Tech Jul 10 '14 at 18:10
  • @TheMadTechnician Even using parenthesis the results still spit out xlsx files as well. – Winski Tech Jul 10 '14 at 18:16
  • @WinskiTech re: Markdown. click the help link next to the comment box for formatting help. Surround code with backticks `\``. – Rynant Jul 10 '14 at 18:38
  • Then don't use -Match, use -eq instead. – TheMadTechnician Jul 10 '14 at 18:39

3 Answers3

69

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"}
}
lantrix
  • 441
  • 9
  • 17
Rynant
  • 23,153
  • 5
  • 57
  • 71
  • Parenthesis did not fix the issue, only changed what came out, I'm getting xlsx files when all I'm trying to search for is xls and xlk files. – Winski Tech Jul 10 '14 at 18:28
  • See my edit. The `-match` operator will match anywhere in the string. – Rynant Jul 10 '14 at 18:29
9

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" }
}
JoePC
  • 154
  • 2
  • 16
Frode F.
  • 52,376
  • 9
  • 98
  • 114
  • Parenthesis did not fix the issue, only changed what came out, I'm getting xlsx files when all I'm trying to search for is xls and xlk files. – Winski Tech Jul 10 '14 at 18:28
  • 1
    You had also used the wrong operator. Sorry for not catching that. You need to use `-eq` to get exact matches. `-match` would include all results with extentions that contain the phrase "xls". :) – Frode F. Jul 10 '14 at 19:53
1

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.

Sergio Perez
  • 571
  • 6
  • 6