2

I need to extract a Get command results into a CSV. The order column should be automatically generated upon a call and give each object its counter upon its appearance in the list. Would this be possible?

For example, when I'd do something like

Get-VMHost | Select @{N="Order";E={$suborder++}}, Name, Version, Build | Export-Csv -path .\smth.csv

I would like to get a result like

Order Name        Version   Build   
----- ----        -------   -----   
    1 servername1   1.1.1   11111111
    2 servername2   1.1.1   11111111
    3 servername3   1.1.1   11111111

Would this be possible without using an array?

  • 3
    Change `@{N="Order";E={$suborder++}}` to `@{N="Order";E={(([ref]$suborder).Value++)}}` – Mathias R. Jessen Oct 06 '22 at 14:34
  • That's great :) Consider marking my answer (below) "accepted" by clicking the little checkmark to the left of it – Mathias R. Jessen Oct 06 '22 at 14:47
  • 1
    To add to Mathias' helpful answer: the reason that you cannot just use `($suborder++)` is that the calculated property's script block runs in a _child_ scope, where `$suborder++` implicitly creates a _block-local_ variable that goes out of scope after every invocation; see [this answer](https://stackoverflow.com/a/53393980/45375) for details. – mklement0 Oct 06 '22 at 14:47

1 Answers1

4

There are two problems with the current approach:

  1. Unary ++ doesn't output anything by default
  2. Select-Object runs property expressions in their own scope, so you're not actually updating $suborder, you're creating a new local variable every time.

The first problem can be solved by wrapping the operation in the grouping operator (...):

... | Select @{N="Order";E={($suborder++)}}, ...

The second problem can be solved by obtaining a reference to an object that exposes the suborder value as a property.

You can either use a hashtable or a custom object to "host" the counter:

$counter = @{ suborder = 1 }

... | Select @{N="Order";E={($counter['suborder']++)}}

... or you can make PowerShell wrap the original variable in a PSRef-wrapper by using the [ref] keyword:

$suborder = 1

... | Select @{N="Order";E={(([ref]$suborder).Value++)}}
Mathias R. Jessen
  • 157,619
  • 12
  • 148
  • 206