Powershell Nested For loop

I have two column of data listed as following.
A      B
50	esx10v
51	esx11v
52	esx12v
53	esx13v
54	esx14v
55	esx15v
56	esx16v
57	esx17v
58	esx18v
59	esx19v
60	esx20v
61	esx21v

Open in new window


I am trying to write a script to display the following -
esx10v has 50
esx11v has 51
....
esx21v has 61

Open in new window


My code does not work for obvious reason, is it possible to write it in a loop statement?
$ips=50..61;$vms=10..21;
foreach ($vm in $vms) {
    foreach ($ip in $ips) {
write-host esx"$vm"v has $ips
    }
}

Open in new window

LVL 21
MazdajaiAsked:
Who is Participating?
 
Meir RivkinConnect With a Mentor Full stack Software EngineerCommented:
$ips=50..61;
$vms=10..21;
$i=0
$vms | %{
write-host ("esx{0}v has {1}" -f $_, $ips[$i++])
}

Open in new window

0
 
Mahoney-84Connect With a Mentor Commented:
$ips=50..61
$vms=10..21
$x=0;Foreach($vm in $vms){write-host $vm "has" $ips[$x];$x++}
0
 
MazdajaiAuthor Commented:
Perfect! Do you mind explain the difference?

("esx{0}v has {1}" -f $_, $ips[$i++])

Open in new window

{write-host $vm "has" $ips[$x];$x++} 

Open in new window

0
Protect Your Employees from Wi-Fi Threats

As Wi-Fi growth and popularity continues to climb, not everyone understands the risks that come with connecting to public Wi-Fi or even offering Wi-Fi to employees, visitors and guests. Download the resource kit to make sure your safe wherever business takes you!

 
Meir RivkinConnect With a Mentor Full stack Software EngineerCommented:
$vms | %{ -  means loop $vms
in powershell each item in the object you iterate is stored in default object called $_
"esx{0}v has {1}" is the string being formatted (via -f switch), {0} and {1} are key holders to place the formatting arguments.
so the 1st argument replaces {0}, 2nd argument replaces {1} and so on.
in .Net u use String.Format() which has the same idea.
i use $i as variable counter so for each item in $vms i take the matched item in $ips (by index)
0
 
Mahoney-84Connect With a Mentor Commented:
Sedgwick declared a string and then declared how to format it.

I just dumped my variables to the screen in a specific format.

Basically the same - but Sedgwick's will be more useful in complex scenarios
0
 
QlemoConnect With a Mentor Batchelor, Developer and EE Topic AdvisorCommented:
In more complex scenarios it would be better to use a CSV file or custom object to store the relation, or at least a twodimensional array like
$vms = @( (50, 'esx10v'), (51, 'esx11v') <# aso #>)
$vms | % { write-host "$($_[1]) has IP $($_[0])" }

Open in new window

0
 
MazdajaiAuthor Commented:
Thanks for the feedback. The mulch-dimensional array is interesting but how can I scale in a csv?

Sedgwick,

i am not familiar with the -f switch. This works fine in lab for displaying, but when I remove the write-host and attempt to run it as a script, it did not execute. Any idea or documentation?
0
 
Mahoney-84Commented:
what exactly are you trying to do?
You either have to write it to the screen out write each iteration to a new variable

Those are your options
0
 
MazdajaiAuthor Commented:
Mahoney-84,

Is there a way to append string before $ips[$x] ? It seems to changed the output of my code when I add $ips[$x].

For example -

$ips=50..61
$vms=10..21
$x=0;Foreach($vm in $vms){write-host $vm "has" "10.10.10."$ips[$x];$x++} 

Open in new window

$ips=50..61
$vms=10..21
$x=0;Foreach($vm in $vms){write-host $vm "has" 10.10.10.$ips[$x];$x++} 

Open in new window

0
 
MazdajaiAuthor Commented:
I am trying to use it as a script for automation, column A is the last octet of an ip address.
0
 
Mahoney-84Commented:
Hmmm?? - Need a little more info to help you.  Your original question  - you needed to format two columns in a specific format (string) - We gave you that answer.

If you want to do something else with the information -spin up a new question or give us some more info

If you don't want to write the output to the screen, then you have to write it to a multi dimensional array, a hash table, or each item to a variable.

$ips=50..61
$vms=10..21
$x=0;Foreach($vm in $vms){$mytempvariable =  $vm "has" $ips[$x];$x++;Do-something $mytempvariable}

Open in new window

0
 
MazdajaiAuthor Commented:
Will do. Thanks.
0
 
QlemoBatchelor, Developer and EE Topic AdvisorCommented:
If you want to use a CSV as input:
<# CSV file format:
IP;VM
50;esx10v
51;esx11v
#>
import-csv 'VMs.csv' | % { write-host "$($_.VM) has IP $($_.IP)" }

Open in new window

You can use $_.VM and $_.IP for the current values of the CSV.
0
 
Mahoney-84Commented:
Is there a way to append string before $ips[$x] ? It seems to changed the output of my code when I add $ips[$x].

For example -
I missed this comment between page refreshes - sorry
$ips=50..61;
$vms=10..21;
$i=0
$vms | %{
write-host ("esx{0}v has 10.10.10.{1}" -f $_, $ips[$i++])
}

Open in new window

0
Question has a verified solution.

Are you are experiencing a similar issue? Get a personalized answer when you ask a related question.

Have a better answer? Share it in a comment.

All Courses

From novice to tech pro — start learning today.