web-dev-qa-db-ja.com

複数の-または-またはPowerShellのWhere-Objectステートメント

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コードをリモートで実行し、作成日が2014年6月1日以降のすべての.xlsおよび.xlkファイルを返すようにしています。このコードを実行すると、そのリモートの場所にあるすべてのフォルダーが吐き出されます。次のような2つのことだけを比較する場合:

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ステートメント以外のものを使用する必要がありますか?

28
Winski Tech

最初の例で{}で比較をラップすることにより、ScriptBlocksを作成しています。そのため、PowerShellインタープリターはWhere-Object { <ScriptBlock> -and <ScriptBlock> }と見なします。 -and演算子はブール値に作用するため、PowerShellはScriptBlocksをブール値にキャストします。 PowerShellでは、空、ゼロ、またはnull以外のすべてがtrueです。この場合、ステートメントはWhere-Object { $true -and $true }のようになり、常にtrueになります。

{}を使用する代わりに、括弧()を使用します。

また、-eqの代わりに-matchを使用したいのは、matchが正規表現を使用し、パターンが文字列のどこかに見つかった場合にtrueになるためです(試用:'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"}
}
40
Rynant

かっこを使用する必要がある場合は、波かっこを使用しています。

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