解释 Powershell [void] 行为

Explain Powershell [void] behavior

我的脚本将一些信息从 Sharepoint 站点导出到 .CSV 文件。

# Enter Web Application URL
$WebAppURL="http://server"

# Enter Path to CSV-file
$CSVFilePath="Path"

$SiteCollections = Get-SPWebApplication $WebAppURL | Get-SPSite -Limit All

$Tree = foreach ($Site in $SiteCollections) {
    foreach ($Web in $Site.AllWebs) {
    $Groups = New-Object System.Collections.ArrayList
        foreach ($Group in $web.Groups) {
            [void]$Groups.Add($Group.Name)
        }

        $Groups = $Groups -join ','
        [PSCustomObject]@{
            Url = $web.URL
            Title = $web.Title
            CountOfLists= $web.Lists.Count
            PermissionsInherited = $web.Permissions.Inherited
            Groups = $Groups
            }
    }
}

$Tree | Export-CSV $CSVFilePath -NoTypeInformation -Encoding UTF8

如果我在 $Groups.Add($Group.Name) 之前使用 [void] 它工作正常,但没有 [void],脚本 returns 一个空的 .CSV 文件。

为什么会这样?

  • PowerShell 隐式 输出的值既未在变量中捕获,也未被抑制(与 [void] (...)$null = ...Out-Null),重定向(使用 > / >>),也不会通过管道 (|) 发送到另一个命令。

    • 请参阅 的底部部分了解此行为背后的设计原理。
  • $Groups.Add($Group.Name) outputs an [int] (System.Int32) 值(新追加元素的索引),所以如果没有 [void] 转换,这个整数首先成为内部的一部分,然后成为外部 foreach 循环的输出[1],因此有效地捕获了 $Tree.

    中的 第一个 输出对象
  • 当管道对象到 Export-Csv 时,第一个 对象根据该对象的 (public) 属性。

  • [int] 实例本身只是一个值,它没有任何属性,因此生成的 CSV 文件实际上是空的。


[1] System.Collections.ArrayList 的通用等价物是 System.Collections.Generic.List`1,其 .Add() 方法 而不是 return 一个值,这就是为什么它在 PowerShell 中(通常)更受欢迎的原因。等效的构造调用将是:
$Groups = New-Object System.Collections.Generic.List[object] 或者,在 PSv5+ 中,
$Groups = [System.Collections.Generic.List[object]]::new()