Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
150 views
in Technique[技术] by (71.8m points)

windows 7 - Multiple -and -or in PowerShell Where-Object statement

PS H:> Invoke-Command -computername SERVERNAME { Get-ChildItem -path E:dfsrootsdatastore2public} | 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:dfsrootsdatastore2public} | 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?

question from:https://stackoverflow.com/questions/24682939/multiple-and-or-in-powershell-where-object-statement

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

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:dfsrootsdatastore2public | 
        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:dfsrootsdatastore2public* -Include *.xls, *.xlk | 
        Where-Object {$_.creationtime -ge "06/01/2014"}
}

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...