首页 > 解决方案 > 在 Powershell 中的 ForEach-Object 中引用目标对象

问题描述

我对 Powershell 相当陌生。我试图通过引用作为备份一部分创建的每个 GPO 备份的“gpresult.xml”文件中的名称来重写 GPO 备份文件夹的名称,以使用它们的友好名称而不是它们的 GUID。但是,我不明白如何引用正在读入 ForEach-Object 循环的特定对象(在本例中为文件夹名称),以便读入该文件夹下的文件。

function Backup_GPO {

    $stamp = Get-Date -UFormat "%m%d" 
    New-Item -ItemType "directory" -Name $stamp -Path \\dc-16\share\GPO_Backups -Force | out-null # create new folder to specify day backup is made
    Backup-GPO -All -Path ("\\dc-16\share\GPO_Backups\" + "$stamp\" )
    Get-ChildItem -Path \\dc-16\share\GPO_Backups\$stamp | ForEach-Object {
        # I want to reference the current folder here
        [xml]$file = Get-Content -Path (folder that is being referenced in for loop)\gpresult.xml 
        $name = $file.GPO.Name
    }

我来自 Python,如果我想引用我当前正在迭代的对象,我可以非常简单地这样做 -

for object in list:
    print(object)

如何在 Powershell 的 ForEach-Object 命令中引用当前正在使用的对象?

标签: powershell

解决方案


我来自 Python,如果我想引用我当前正在迭代的对象,我可以非常简单地这样做 -

for object in list: print(object)

PowerShell 中的直接等价物foreach 语句(循环)

$list = 1..3  # create a 3-element array with elements 1, 2, 3
foreach ($object in $list) {
  $object  # expression output is *implicitly* output
}

请注意,您不能直接在 PowerShell管道中使用foreach 语句

在管道中,您必须改用cmdlet ForEach-Object 这有点令人困惑,foreach可以通过别名称为,它只是区分语句和 cmdlet 别名的解析模式。


您在ForEach-Object 应用不同规则管道中使用cmdlet

{ ... }传递给管道处理cmdlet的脚本块 ( )没有语句提供 ForEach-Object式迭代变量。Where-Objectforeach

相反,按照惯例,此类脚本块将当前管道输入对象视为自动变量 $_,或者更详细地说,视为$PSItem.


虽然foreach语句和ForEach-Objectcmdlet在某个抽象级别上的操作相同,但有一个根本区别

  • foreach 语句对预先在内存中收集的集合进行操作, full

  • ForEach-Object cmdlet对流输入逐个对象进行操作,因为每个对象都通过管道接收。

这种差异相当于以下权衡

  • 使用该foreach 语句以获得更好的性能,但会消耗内存

  • ForEach-Object cmdlet用于持续使用内存,也可能用于单个管道的语法优雅,但以牺牲性能为代价- 但是,对于非常大的输入集,这可能是唯一的选择(假设您还没有收集非常大的输出内存中的数据集)。


推荐阅读