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文件,其创建日期为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"}
仅显示在该日期或之后创建的xls文件。这里发生了什么?我是否需要使用嵌套-and
和-or
语句以外的其他内容?
答案 0 :(得分:38)
通过在第一个示例中将比较包装在{}
中,您将创建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")}
}
更好的选择是在Get-ChildItem
命令中过滤扩展名。
Invoke-Command -computername SERVERNAME {
Get-ChildItem -path E:\dfsroots\datastore2\public\* -Include *.xls, *.xlk |
Where-Object {$_.creationtime -ge "06/01/2014"}
}
答案 1 :(得分:2)
当你应该使用parantheses时,你使用曲线括号。
where语句保存在scriptblock中,该块是使用弯曲的baces { }
定义的。要隔离/包装测试,您应该使用parantheses ()
。
我还建议尝试在远程计算机上进行过滤。尝试:
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" }
}
答案 2 :(得分:0)
我在这里找到了解决方法:
How to properly -filter multiple strings in a PowerShell copy script
您必须对-Include
使用Get-ChildItem
标志
我的示例:
$Location = "C:\user\files"
$result = (Get-ChildItem $Location\* -Include *.png, *.gif, *.jpg)
不要忘记在路径位置后面加上“ *”。