wake-up-neo.com

Mehrere -und -oder in PowerShell Where-Object-Anweisung

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

Oben ist mein Codebeispiel. Ich versuche, diesen PowerShell-Code remote auf meinem Dateiserver auszuführen und alle XLS- und XLK-Dateien mit einem Erstellungsdatum am oder nach dem 01.06.2014 zurückzugeben. Wenn ich diesen Code ausführe, werden alle Ordner an diesem Remotestandort ausgespuckt. Wenn ich nur zwei Dinge miteinander vergleiche:

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

Es werden nur die xls-Dateien angezeigt, die am oder nach diesem Datum erstellt wurden. Was ist hier los? Muss ich etwas anderes als die Anweisungen nest -and Und -or Verwenden?

28
Winski Tech

Indem Sie Ihre Vergleiche in Ihrem ersten Beispiel in {} Einschließen, erstellen Sie ScriptBlocks. Der PowerShell-Interpreter sieht es also als Where-Object { <ScriptBlock> -and <ScriptBlock> } an. Da der Operator -and Boolesche Werte verarbeitet, wandelt PowerShell die ScriptBlocks in boolesche Werte um. In PowerShell ist alles wahr, was nicht leer, null oder null ist. Die Anweisung sieht dann aus wie Where-Object { $true -and $true }, Was immer wahr ist.

Verwenden Sie anstelle von {} Klammern ().

Sie möchten auch -eq Anstelle von -match Verwenden, da match Regex verwendet und wahr ist, wenn das Muster irgendwo in der Zeichenfolge gefunden wird (versuchen Sie: '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")}
}

Eine bessere Option ist das Filtern der Erweiterungen mit dem Befehl Get-ChildItem.

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

Sie verwenden geschweifte Klammern, wenn Sie Klammern verwenden sollten.

Eine where-Anweisung wird in einem Skriptblock gespeichert, der mit kurvigen Zeichen { } Definiert wird. Um Ihre Tests zu isolieren/zu verpacken, sollten Sie Klammern () Verwenden.

Ich würde auch vorschlagen, die Filterung auf dem Remotecomputer durchzuführen. Versuchen:

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" }
}
4
Frode F.