Powershell:将pracl命令的输出管道传输到数组

Posted

技术标签:

【中文标题】Powershell:将pracl命令的输出管道传输到数组【英文标题】:Powershell: Piping output of pracl command to array 【发布时间】:2020-04-04 06:04:55 【问题描述】:

pracl 是一个 sysinternal 命令,可用于列出目录的 ACL。我有一个共享列表,我想创建一个 csv 文件,这样对于每个 ACL 条目,我希望共享路径位于一列,共享权限位于下一列。我试图通过使用以下代码来做到这一点

$inputfile = "share.txt"

$outputFile = "out.csv"

foreach( $path in Get-Content $inputfile)



$results=.\pracl.exe $path

      

foreach ($result in $results) write-host $path,$line



      

$objResult = [pscustomobject]@

Path = $Path

Permission = $line



$outputArray += $objResult

    $objresult



$outputArray | Export-Csv -Path $outputfile -NoTypeInformation

失败并出现以下错误:-

Method invocation failed because [System.Management.Automation.PSObject] does not contain a method named 'op_Addition'.

At C:\Users\re07393\1\sample.ps1:14 char:1

+ $outputArray += $objResult

+ ~~~~~~~~~~~~~~~~~~~~~~~~~~

    + CategoryInfo          : InvalidOperation: (op_Addition:String) [], RuntimeException

    + FullyQualifiedErrorId : MethodNotFound

有什么建议吗?

【问题讨论】:

【参考方案1】:

您正尝试使用+=在您的$outputArray 变量中迭代地创建[pscustomobject]s 的数组,但是你没有初始化 $outputArray 为一个数组 - 请参阅底部以了解结果行为的解释。

因此,您的问题的直接解决方案就是这样做:

# Do this before your `foreach` loop, then `+=` will work for appending elements.
$outputArray = @()

然而,使用+=添加到数组是低效的,因为实际上每次都必须创建一个数组实例,因为数组是不可变的 数据结构。也就是说,每次使用 += 时,PowerShell 都会在后台创建一个新的数组实例,将现有元素和新元素复制到该实例中。

一种更简单且更有效的方法是让 PowerShell 为您创建一个数组,方法是使用 foreach 循环作为 表达式 并分配它到一个变量作为一个整体: 也就是说,循环的每次迭代中输出的任何内容都会被 PowerShell 自动收集:

一个简化的例子:

# Create an array of 10 custom objects
[array] $outputArray = foreach ($i in 1..10) 
   # Create and implicitly output a custom object in each iteration.
   [pscustomobject] @
     Number = $i
   

注意$outputArray左侧的类型约束[array]的使用,它确保变量值始终是一个数组,即使循环恰好产生一个 输出对象(在这种情况下,PowerShell 将仅存储该对象本身,而不是将其包装在数组中)。

请注意,您可以类似地使用 forifdo / while / switch 语句作为表达式

然而,在所有情况下,这些语句只能作为表达式它们自己;遗憾的是,将它们用作管道的第一段将它们嵌入到更大的表达式中确实不起作用 - 请参阅GitHub issue #6817。


至于你尝试了什么

$outputArray += $objResult

由于您没有在循环之前初始化$outputArray,因此该变量是在循环的第一次迭代中隐式创建的:

如果 LHS 变量尚不存在,+= 实际上与 = 相同:也就是说,RHS 按原样存储在 LHS 变量中,因此 $outputArray 现在包含 @987654343 @实例。

第二次 迭代中,因为 $outputArray 现在有一个值,+= 现在尝试执行适合类型的 + 操作(例如数字的加法和连接字符串),但没有为类型 [pscustomobject] 定义 + (op_Addition()) 操作,因此操作失败并显示您看到的错误消息。

【讨论】:

以上是关于Powershell:将pracl命令的输出管道传输到数组的主要内容,如果未能解决你的问题,请参考以下文章

Powershell 管道总结

理解Powershell管道

PowerShell初级篇●Powershell管道

PowerShell 学习笔记——管道

通过管道将 CMD 输出传递给 Powershell [重复]

将 PowerShell 的默认输出编码更改为 UTF-8