12
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. Когда я запускаю этот код, он начинает выплевывать все папки в этом удаленном месте. Если я сравниваю только две такие вещи:Множество -или -или в PowerShell Где-объекта заявление

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 заявлений?

+0

Обратите внимание, что разбивка команды на несколько операторов «где» тоже не работает. Я бы ввел команду: PS H: \> Invoke-Command -computername SERVERNAME {Get-ChildItem -path E: \ dfsroots \ datastore2 \ public} | Где-Объект {$ _. Ex Натяжение-матч "xls" -или $ _. Extension-match "xlk"} | where-object {$ _. creationtime -ge "06/01/2014"} И он начинает выплескивать файлы xlsx, чего я не хочу. –

+0

Используйте круглые скобки, не фигурные скобки, чтобы заключить опции, поэтому 'Where {($ _. Extension -Match" xls "-или $ _. Расширение -Match" xlk ") -and $ _. CreationTime -ge" 06/01/2014 "}' – TheMadTechnician

+0

@ TheMadTechnician, если вы могли бы помочь мне всего минуту, я не могу понять, что такое мини-Markdown форматирование, а что нет. Как вы заключили это в блок «code»? –

ответ

20

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

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

Также вы хотите использовать -eq вместо -match поскольку матч использует регулярное выражение и будет верно, если шаблон найден в любом месте строки (попробуйте: '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"} 
} 
+0

Parenthesis не исправить эту проблему, только изменилось то, что вышло, я получаю файлы xlsx, когда все, что я пытаюсь найти, это файлы xls и xlk. –

+0

См. Мое редактирование. Оператор '-match' будет соответствовать в любой точке строки. – Rynant

1

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

Оператор 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" } 
} 
+0

Parenthesis не исправит проблему, только изменили то, что вышло, я получаю файлы xlsx, когда все, что я пытаюсь найти, это файлы xls и xlk. –

+0

Вы также использовали неправильный оператор. Извините, что не поймал это. Для получения точных совпадений вам нужно использовать '-eq'. '-match' будет включать все результаты с расширениями, которые содержат фразу« xls ». :) –