Множество -или -или в 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"}}

Выше мой пример кода. Я пытаюсь удаленно запускать этот код PowerShell на моем файловом сервере и возвращать все файлы .xls и .xlk с датой создания или позже 6/1/2014. Когда я запускаю этот код, он начинает выплевывать все папки в этом удаленном месте. Если я сравниваю только две вещи:

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

Отображаются только файлы xls, созданные после или после этой даты. Что здесь происходит? Нужно ли использовать что-то другое, кроме выражений гнезда -and и -or?

Ответ 1

Объединив сравнения в {} в первом примере, вы создаете ScriptBlocks; поэтому интерпретатор PowerShell рассматривает его как Where-Object { <ScriptBlock> -and <ScriptBlock> }. Поскольку оператор -and работает с булевыми значениями, PowerShell передает ScriptBlocks в логические значения. В PowerShell все, что не пусто, равно нулю или null, является истинным. Затем выражение выглядит как Where-Object { $true -and $true }, которое всегда верно.

Вместо использования {} используйте круглые скобки ().

Также вы хотите использовать -eq вместо -match, так как match использует regex и будет true, если шаблон найден в любом месте строки (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")}
}

Лучшим вариантом является фильтрация расширений с помощью команды Get-ChildItem.

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

Ответ 2

Вы используете фигурные скобки, когда вы должны использовать скобки.

Оператор where хранится внутри блока скрипта, который определяется с помощью соблазнительных связок { }. Чтобы изолировать/обернуть ваши тесты, вы должны использовать скобки ().

Я бы также предложил попробовать выполнить фильтрацию на удаленном компьютере. Пытаться:

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" }
}