Author Posts

July 26, 2018 at 6:48 pm

I'm trying to see if anyone knows a more efficient way of concatenating things, or if its possible to do the code below in a single line.

$numbers = 1000..1028
$server_start = "Server"

foreach ($number in $numbers) {
    Write-Output $server_start$number
}

July 26, 2018 at 7:03 pm

What do you find inefficient about that?

July 26, 2018 at 7:40 pm

Not sure about efficiency, but I do this stuff a lot. I wish there was a built-in operator that did it like filling down cells in Excel. Especially when I'm going from 001 to 100. I just have to look up the 3rd method.

1000..1028 | foreach { "Server$_" } 

1000..1028 -replace '^','Server'  # evil foreach avoided!

0..28 | foreach { 'Server{0:d4}' -f $_ }

July 26, 2018 at 10:16 pm

But you are doing two things here and not just concat of string. Generating a dynamic string array/list and adding that to astatic string text.

"like filling down cells in Excel"

What do you mean by this?

Excel is just auto incrementing as you manually drag a cursor down or across the column / row. That is taking what you have in cell / row and the Excel UI element drag (cursor action) is how that code behind is called. Which is still looping. You just don't see it, but you still have to manually do UI interactive stuff to make that happen.

If you did that in VBA code in Excel, you'd end up in the same boat where you are now in the script, having to navigate the Excel DOM on top of that. Well, that and that there is no drag in a script.

So, are you saying, you'd like to do...

Add-CounterToString(100,$SomeString)

Or

$SomeString -AddCounter(100)

Or

$SomeString.AddCounter(100)

If so, that then that sounds like a good homework assignment to write that function / method. Yet, IMHO, not something that makes a lot of sense to me to be a built-in thing, since there are already multiple ways to do this inline as you have just shown. Either way, iteration is going to happen to do this.

Quick and dirty homework...

Function Add-CounterToString
{
 [cmdletbinding()]  
 
 [Alias('acts')]

 Param
  (
      [string]$String, 
      [Int]$Count
  )

    0..$Count | foreach { "$($String){0:d4}" -f $_ } 
}

Add-CounterToString -String 'Server' -Count 10

Remember PS is Open Source, so if it does not have something in it, you can become a contributor, do a pull request, make the change and see if it get accepted and thus becomes part of some future version, or just run with what you can for your own needs. For example, adding something like the above to your PS/VSCode profiles.

I personally created my own ModuleLibrary.psm1 (currently over 8K lines of stuff I've pulled together like this and use / shared with my team), in my Modules folder that I import via my profiles.

Even with something like this, you are still going to end up looping the results to say add them to a lab or prod AD environment or something else. So, well, you know....

July 26, 2018 at 11:10 pm

Thank you for your guys help. Its exactly what I was looking for.

July 28, 2018 at 1:51 pm

Interesting. Is there a way to call that vba code from powershell? Here's how I would do acts:

# I put it in my $profile
Function Add-CounterToString {
 [Alias('acts')]
 Param  (
      $String,
      [Parameter(ValueFromPipeline=$True)]$num
  )
  process {
    "$String{0:d3}" -f $_
  }
}

PS /Users/js> 1..5 + 11,13,15,17 | acts COMP                                                                     
COMP001
COMP002
COMP003
COMP004
COMP005
COMP011
COMP013
COMP015
COMP017