Powershell:指定的路径或文件名或两者都太长 - 目录排除

时间:2016-07-25 19:39:12

标签: powershell tfsbuild

我们以前运行过这个脚本很好,但是最近我们通过TFS Build中的配置转换步骤得到了一些问题(参见下面的错误)。

$serviceFiles = Get-ChildItem $localWorkspace -Recurse | where {$_.Extension -eq ".exe"}

Error in TFS

我们最近转而使用Gulp编译我们的CSS和JS,它给了我们一个“node_modules”文件夹。看起来它正在尝试抓取这些文件夹并实际达到目录长度限制。我已经尝试了各种各样的建议,我发现谷歌搜索和其他相关的问题,但似乎没有一个对我有用,它仍然会出现同样的错误(我认为实际上并没有排除这些文件夹)

这是我尝试用于排除文件夹

的修改版本的示例
$excludedDirectories = @("*node_modules*", "*packages*", "*Common*");
Write-Verbose $localWorkspace

# get services for config types (service configs named same as assmebly .exe)
$serviceFiles = Get-ChildItem $localWorkspace -Recurse -Exclude $excludedDirectories | ?{$_.Extension -eq ".exe" -and $_.FullName -notmatch '*node_modules*' }

我已根据其他SO问题和答案尝试了一些变体,但解决方案避开了我。我从一些消息来源读到-Exclude在大多数情况下对很多人都不起作用,所以我尝试使用where子句的解决方案来排除文件夹(我想排除多个,但我尝试了node_modules,看看我是否可以通过它,其他文件夹不太深)

我想要排除node_modules目录,以及其他一些不需要检查转换的目录。非常感谢任何帮助,谢谢。

1 个答案:

答案 0 :(得分:2)

不幸的是,-Exclude参数在枚举所有文件之前不会排除目录。所以它仍然出错。您需要提前排除它们。

如果这些目录仅存在于顶层,则可以枚举顶级目录,排除您不想要的目录,然后检查其余目录中的内容。像这样:

$excludedDirectories = @("node_modules", "packages", "Common")

$serviceFiles = Get-ChildItem $localWorkspace -Exclude $excludedDirectories | % { Get-ChildItem $_ -Recurse } | ? {$_.Extension -eq ".exe" }

此外,您可以使用-Include

使这更简单一些
$serviceFiles = Get-ChildItem $localWorkspace -Exclude $excludedDirectories | % { Get-ChildItem $_ -Recurse -Include "*.exe" }

注意我做了什么。我删除了顶级-Recurse并过滤掉了这些目录。然后我在最顶级父母的剩余孩子身上使用-Recurse,向我们提供了我们正在寻找的文件。

如果您需要过滤的目录显示在层次结构的深层或多层,您必须编写自己的递归遍历函数:

function Get-ChildItemRecursiveExclude(
    [Parameter(Mandatory=$true)][string[]]$Path,
    [Parameter(Mandatory=$true)][string[]]$ExcludedDirNames
) {
    $immediateChildren = Get-ChildItem $Path -Exclude $ExcludedDirNames
    foreach ($c in $immediateChildren) {
        # Uncaptured output is returned
        $c
        if (Test-Path $c -PathType Container) {
            Get-ChildItemRecursiveExclude $c $ExcludedDirNames
        }
    }
}

$serviceFiles = Get-ChildItemRecursiveExclude $localWorkspace @("node_modules", "packages", "Common") | ? { $_.Extension -eq ".exe" }

总的来说,基本的想法是,首先必须让PowerShell不再遍历node_modules。 npm创建了非常深的层次结构,超过了路径长度的旧限制。 (我不清楚为什么.NET仍然强制执行它们,但即使某些底层Windows API不再使用它,例如,robocopy和几个第三方运行时,如Node,不要打扰和他们在一起。)