I have a nice string that looks like this:
Get-Azsubscription | ForEach-Object {"$($a).) $($_.Name)"; $a }
It allows me to count how many subscriptions I have on Azure and it adds a number to it. The problem is that the counter starts from 0, which is in my case .)
:
How to make that counter start to count from 1
and not from 0
?
CodePudding user response:
The ForEach-Object
cmdlet takes an additional -Begin
block you can use to initialize any variable you want to use:
Get-Azsubscription | ForEach-Object -Begin { $a = 1 } -Process {"$a.) $($_.Name)"; $a }
CodePudding user response:
To complement Mathias R. Jessen's effective solution:
Indeed you should explicitly initialize your $a
variable with the desired starting value.
If $a
is uninitialized, as it was in your case:
Using it inside an expandable string (
"$a"
) makes it expand to the empty string.The first time you apply
[int]
with) value0
, so that it receives value1
. Subsequent
While using a -Begin
block with ForEach-Object
in order to initialize the variable is conceptually clear, the caveat is that the variable is not scoped to that statement, and lives on afterwards.
Thus, the alternative is to simply initialize it before calling ForEach-Object
.
You can also streamline the command a bit by incorporating the
operation into the expandable string, but note that you then need to enclose it in (...)
, in addition to $(...)
; the reason is that a
operation produces no output by default, except if you apply (...)
, the grouping operator, to pass the value through.
Therefore:
$a = 0 # Initialize the sequence number
Get-Azsubscription | ForEach-Object { "$(( $a)).) $($_.Name)" }
Note the initialization to 0
in combination with the prefix version of
, the increment operator, so that incrementing to 1
and outputting that value happens on the first iteration.
A simplified example:
$a = 0 # Initialize the sequence number
[pscustomobject] @{ Name='foo' }, [pscustomobject] @{ Name='bar' } |
ForEach-Object { "$(( $a)).) $($_.Name)" }
Output:
1.) foo
2.) bar
Finally, a perhaps more PowerShell-idiomatic solution that constructs custom objects for display, which PowerShell automatically formats nicely for you:
$a = 0 # Initialize the sequence number
[pscustomobject] @{ Name='foo' }, [pscustomobject] @{ Name='bar' } |
ForEach-Object { [pscustomobject] @{ '#' = $a; Name = $_.Name } }
Output:
# Name
- ----
1 foo
2 bar