使用 "Select" 导出 CSV 文件时的 Lazy-Pipe-Evaluation

Lazy-Pipe-Evaluation when using "Select" to export CSV file

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

脚本大纲: 首先,我获取 $items:

中的列表项
$query = New-Object Microsoft.SharePoint.Client.CamlQuery
$items = $list.GetItems($query)

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

现在我为每一列创建一个新的 Hashtable 并将其添加到 $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 指向最后一个被循环的对象(因此是 hashmap 的最后一个元素)。这是管道中评估的每个 select 语句 的情况。

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

我该如何解决这个问题?

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

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

我们可以使用闭包在循环内冻结对 $h 的引用,如 in this article 所述。