powershell - 在 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 命令中引用当前正在使用的对象?
解决方案
我来自 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-Object
foreach
相反,按照惯例,此类脚本块将当前管道输入对象视为自动变量 $_
,或者更详细地说,视为$PSItem
.
虽然foreach
语句和ForEach-Object
cmdlet在某个抽象级别上的操作相同,但有一个根本区别:
该
foreach
语句对预先在内存中收集的集合进行操作, full。ForEach-Object
cmdlet对流输入逐个对象进行操作,因为每个对象都通过管道接收。
这种差异相当于以下权衡:
使用该
foreach
语句以获得更好的性能,但会消耗内存。将
ForEach-Object
cmdlet用于持续使用内存,也可能用于单个管道的语法优雅,但以牺牲性能为代价- 但是,对于非常大的输入集,这可能是唯一的选择(假设您还没有收集非常大的输出内存中的数据集)。