我是powershell的新手,不明白为什么这个过程有效:
$ftpFiles = Get-FTPChildItem -Session $Session -Path "/myroot" -Recurse | ForEach-Object { $_ | Add-Member -type NoteProperty -name CompareFullName -value ($_.FullName -Replace "ftp://ftp.server.com/myroot/", "") -PassThru }
这不起作用:
$ftpFiles = Get-FTPChildItem -Session $Session -Path "/myroot" -Recurse | Add-Member -type NoteProperty -name CompareFullName -value ($_.FullName -Replace "ftp://ftp.server.com/myroot/", "") -PassThru
我尝试将一个属性(CompareFullName)添加到文件对象,其值使用同一文件对象(FullName)的另一个属性。 Add-Member应该接受管道值。 非工作语法中发生的情况是该属性添加正常但值为null。 第一种语法工作正常。 我希望在不使用foreach-object的情况下实现我的目标的解释或其他方式。
答案 0 :(得分:1)
$_
是一个自动变量,只对在管道中的每个项目上执行的脚本块有意义。第一个示例有效,因为当您传递给ForEach-Object时,为脚本块定义了$_
。第二个示例不起作用,因为没有脚本块,因此$_
未定义。没有foreach,AFAIK没有办法做到这一点。您需要为管道中的每个项目计算值,并且Add-Member不接受脚本块来计算其附加的成员的值。我猜你使用像这样的ScriptProperty:
$ftpFiles = Get-FTPChildItem -Session $Session -Path "/myroot" -Recurse | Add-Member -type ScriptProperty -name CompareFullName -value {$this.FullName -Replace "ftp://ftp.server.com/myroot/", ""} -PassThru
但这在语义上与你拥有的不同,因为它每次访问时都会计算属性值。
根据您要执行的操作,您可以使用Select-Object来提取有用的属性以供日后使用:
$ftpFiles = Get-FTPChildItem -Session $Session -Path "/myroot" -Recurse | select *, @{n="CompareFullName"; e={$_.FullName -replace "ftp://ftp.server.com/myroot/", ""}}
这将生成具有相同属性的新自定义对象,以及另一个属性“CompareFullName”。