PowerShell Where-Object语句中的多个和 - 或 -

Win*_*ech 30 powershell windows-server-2003 windows-server-2008 windows-7

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"}}
Run Code Online (Sandbox Code Playgroud)

上面是我的代码示例.我正在尝试在我的文件服务器上远程运行此PowerShell代码,并让它返回所有.xls和.xlk文件,其创建日期为2014年6月1日或更晚.当我运行此代码时,它开始吐出该远程位置的所有文件夹.如果我只比较两件事:

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

仅显示在该日期或之后创建的xls文件.这里发生了什么?我是否需要使用除nest -and-or语句之外的其他内容?

Ryn*_*ant 43

通过{}在第一个示例中包含比较,您将创建ScriptBlocks; 所以PowerShell解释器将其视为Where-Object { <ScriptBlock> -and <ScriptBlock> }.由于-and运算符对布尔值进行操作,因此PowerShell将ScriptBlocks转换为布尔值.在PowerShell中任何非空的,零或null都是真的.然后声明看起来Where-Object { $true -and $true }总是如此.

而不是使用{},使用括号().

你也想使用-eq而不是-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")}
}
Run Code Online (Sandbox Code Playgroud)

更好的选择是在Get-ChildItem命令中过滤扩展名.

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


Fro*_* F. 6

当您应该使用括号时,您正在使用曲线括号。

where 语句保存在 scriptblock 中,它使用 curvy baces 定义{ }。要隔离/包装您的测试,您应该使用括号()

我还建议尝试在远程计算机上进行过滤。尝试:

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" }
}
Run Code Online (Sandbox Code Playgroud)