首先,声明 Get-ChildItem -Include *.dll 将只返回文件对象(除非您有一个名为 <something>.dll 的文件夹,这将是相当少见的),因此如果您过滤目录对象 ($_.PSIsContainer) 的输出,您显然会得出一个空的结果。由于您的其余代码建议您无论如何都需要文件,只需从过滤器中删除 $_.PSIsContainer 子句。
此外,-Exclude 参数适用于项目的名称。您不能使用它来排除(部分)路径。如果您希望结果中省略给定目录中的文件,您应该在 Where-Object 过滤器中使用正则表达式匹配排除它们,如下所示:
$_.FullName -notmatch '^C:\\windows\\(system|temp|winsxs)\\'
最后,wildcard matches (-like, -notlike) 如果要匹配部分字符串,则需要在表达式的开头和/或结尾使用 * 通配符:
PS>
'abcde' -like 'a*e'
真的
PS>
'abcde' -like 'c*e'
错误的
PS>
'abcde' -like '*c*e'
真的
如果没有前导/尾随*,表达式会自动锚定在字符串的开头/结尾。
但是,您的模式一开始就不像通配符表达式。在我看来,它更像是一个正则表达式(匹配包含\obj\ 或以\obj 结尾的路径)。为此,您还可以使用 -notmatch 运算符:
$_.FullName -notmatch '\\obj\\'
从性能的角度来看,通配符匹配更有效,因此最好使用如下表达式:
$_.FullName -notlike '*\obj\*'
使尾部反斜杠可选是没有意义的,因为Get-ChildItem 返回一个*.dll 文件列表,所以没有一个完整路径以\obj 结尾。
假设我正确解释了您的代码,这样的事情应该可以满足您的需求:
$final = Get-ChildItem 'C:\' -Include '*.dll' -Recurse | Where-Object {
$_.FullName -notmatch '^C:\\windows\\(system|temp|winsxs)\\' -and
$_.FullName -notlike '*\obj\*' -and
$_.VersionInfo.LegalCopyright.Contains('Microsoft')
}