使用"Select"导出CSV文件时的惰性管道评估



预期的脚本输出:我想从Microsoft SharePoint列表中导出包含某些列的CSV文件。

脚本大纲:首先,我获取$items中的列表项:

$query = New-Object Microsoft.SharePoint.Client.CamlQuery
$items = $list.GetItems($query)

输出 CSV 文件的列在哈希映射$h$displayName => $internalName ) 中定义。

现在我为每一列创建一个新的哈希表并将其添加到$selects

$selects = @()
foreach ($h in $mapping.GetEnumerator()) {
     $selects += @{ L = $h.Name; E = { $_[$h.Value] } }
}

然后我输出 CSV 文件:

$items | Select-Object $selects | Export-Csv -Path $outputPath

现在的问题是:

在 E 中,我定义了一个表达式,该表达式仅在我需要时才计算(懒惰地,因此在执行 Select 时)。发生这种情况时,对 $h.Value 属性的引用已更改,因为$h正在循环。因此,在计算表达式时,$h指向已循环的最后一个对象(即哈希映射的最后一个元素)。管道中正在计算的每个 select 语句都是这种情况。

我可以通过将$h的引用(或其值)保存在另一个变量中来解决此问题。但是我需要硬编码数量的变量。

如何解决这个问题?

感谢PetSerAl,这里是经过测试和工作的代码示例:

foreach ($h in $mapping.GetEnumerator()) {
     $selects += @{ L = $h.Name; E = { $_[$h.Value] }.GetNewClosure() }
}

我们可以通过使用闭包来冻结对循环内$h的引用,如本文所述。

最新更新