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