Powershell: Piping output of pracl command to array

本小妞迷上赌 提交于 2021-02-08 09:29:25

问题


pracl is a sysinternal command that can be used to list the ACLs of a directory. I have a list of shares and I want to create a csv file such that for each ACL entry, I want the share path in one column and share permission in the next. I was trying to do that by using the following code

$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

It failed with the following error :-

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

Any suggestions ?


回答1:


You're trying to create an array of [pscustomobject]s in your $outputArray variable iteratively, using +=, but you're not initializing $outputArray as an array - see the bottom section for an explanation of the resulting behavior.

Thus, the immediate solution to your problem is to do just that:

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

However, using += to add to arrays is inefficient, because in reality a new array instance must be created every time, because arrays are immutable data structures. That is, every time += is used, PowerShell creates a new array instance behind the scenes to which the existing elements as well as the new element are copied.

A simpler and much more efficient approach is to let PowerShell create an array for you, by using the foreach loop as an expression and assigning it to a variable as a whole: That is, whatever is output in every iteration of the loop is automatically collected by PowerShell:

A simplified example:

# 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
   }
}

Note the use of type constraint [array] to the left of $outputArray, which ensures that the variable value is always an array, even if the loop happens to produce just one output object (in which case PowerShell would otherwise just store that object itself, and not wrap it in an array).

Note that you can similarly use for, if, do / while / switch statements as expressions.

In all cases, however, as of PowerShell 7.0, these statements can only serve as expressions by themselves; regrettably, using them as the first segment of a pipeline or embedding them in larger expressions does not work - see this GitHub issue.


As for what you tried:

$outputArray += $objResult

Since you didn't initialize $outputArray before the loop, the variable is implicitly created in the loop's first iteration:

If the LHS variable doesn't exist yet, += is effectively the same as =: that is, the RHS is stored as-is in the LHS variable, so that $outputArray now contains a [pscustomobject] instance.

In the second iteration, because $outputArray now has a value, += now tries to perform a type-appropriate + operation (such as numeric addition for numbers, and concatenation for strings), but no + (op_Addition()) operation is defined for type [pscustomobject], so the operation fails with the error message you saw.



来源:https://stackoverflow.com/questions/59277625/powershell-piping-output-of-pracl-command-to-array

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!