解释 Powershell [void] 行为

Evg*_*nov 3 powershell sharepoint void

我的脚本将一些信息从 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
Run Code Online (Sandbox Code Playgroud)

如果我使用[void]before$Groups.Add($Group.Name)它可以正常工作,但没有[void],则脚本将返回一个空.CSV文件。

为什么会出现这种情况?

mkl*_*nt0 6

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

    • 有关此行为背后的设计原理,请参阅此答案的底部部分。
  • $Groups.Add($Group.Name)输出一个[int]( System.Int32) 值(新附加元素的索引),因此如果不进行强制[void]转换,该整数将首先成为内部循环的输出 [1] 的一部分,然后成为外部foreach循环的输出[1]的一部分,从而有效地成为 中捕获的第一个输出对象$Tree

  • 当将对象通过管道传输到 时,第一个Export-Csv对象将根据该对象的(公共)属性单独确定要导出的列。

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


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