MAINICH Marouane
MAINICH Marouane

Reputation: 7

Powershell Wrong output

guys i need help here, i want to return the $Location002 and $Location003 content look what is in output

$Location = "westus2"
$Location002 = "westeurope"
$Location003 = "eastasia"

[int]$VMCount = Read-Host "How many VMs?"

1..$VMCount | ForEach-Object {
    
    $i = $_

    # define name for VM, will be used for other resources
    if ($i -eq 1) {
        $locname = "$Location"
        Write-Output $locname
    }
    else {
        $locname = $("Location00" + "$i")
        Write-Output $locname 
    }
}

output :

PS C:\Users\Marouane\Desktop\testpowershell> c:\Users\Marouane\Desktop\testpowershell\test.ps1
How many VMs?: 3
westus2
Location002
Location003
PS C:\Users\Marouane\Desktop\testpowershell>

i need to output westeurope and eastasia

Upvotes: 0

Views: 70

Answers (3)

Steven
Steven

Reputation: 7087

This is not how I would do it, but the more immediate problem is you're assigning a concatenated string to $location and writing to the output stream. I think what you want to do is reference the value of the earlier variable.

There are some clever syntaxes for that. I struggle to remember them. However below would be a start.

$Location = "westus2"
$Location002 = "westeurope"
$Location003 = "eastasia"

[int]$VMCount = Read-Host "How many VMs?"

1..$VMCount | ForEach-Object {
    
    $i = $_

    # define name for VM, will be used for other resources
    if ($i -eq 1) {
        $name = "$VMName"
        $locname = "$Location"
        Write-Output $locname
    }
    else {
        $name = "$VMName" + "00" + "$i"
        $locname = (Get-Variable ("Location00" + "$i")).Value
        Write-Output $locname 
    }
}

Update With Alternative:

I'm still not sure what the goal is, but based on the original sample it would seem there's a 1 to 1 relationship between the location# and the VM number. That said if you go past the number of VMs you would have to adjust this to pick according to the intended pattern...

$Locations = 'westus2', 'westeurope', 'eastasia'
    
[int]$VMCount = Read-Host 'How many VMs?'

For( $i = 0; $i -lt $VMCount ; ++$i )
{
    $Locations[$i]
}

Further Update:

Respective to Mathias's good answer :

$Locations = 'westus2', 'westeurope', 'eastasia'

[int]$VMCount = Read-Host 'How many VMs?'

For( $i = 0; $i -lt $VMCount ; ++$i )
{
    $Locations[ $i % $Locations.Count ]
}

Using the modulus operator in this pattern is very efficient for distributing one list over another. I wrote a small post about My Modulus Obsession with this and some other uses.

Upvotes: 0

Mathias R. Jessen
Mathias R. Jessen

Reputation: 174845

Using a separate variable for each value in a group or list of things is a bit of an anti-pattern, you'll want to put them all in an array together instead:

# Define array of possible locations
# `$Locations[0]` will resolve to `westus2`
# `$Locations[1]` will resolve to `westeurope`, etc.
$Locations = @(
  "westus2"
  "westeurope"
  "eastasia"
)

[int]$VMCount = Read-Host "How many VMs?"

1..$VMCount | ForEach-Object {
  # Define the VM name 
  $name = "VirtualMachine$_"

  # Pick next location from the $Locations array
  # the % ensures we "wrap around" when we reach the end
  $location = $Locations[($_ - 1) % $Locations.Length]

  # Output a new object with Name + Chosen Location
  [pscustomobject]@{
    VMName   = $name
    Location = $location
  }
}

Output for 3 VMs:

How many VMs?: 3

VMName          Location
------          --------
VirtualMachine1 westus2
VirtualMachine2 westeurope
VirtualMachine3 eastasia

Upvotes: 1

Doug Maurer
Doug Maurer

Reputation: 8868

You'll need to retrieve the variable's content with Get-Variable. You can also avoid the extra step of making an $i variable and instead use the automatic variable $_

$Location = "westus2"
$Location002 = "westeurope"
$Location003 = "eastasia"

[int]$VMCount = Read-Host "How many VMs?"

1..$VMCount | ForEach-Object {

    # define name for VM, will be used for other resources
    if ($_ -eq 1) {
        $name = "$VMName"
        $locname = "$Location"
        Write-Output $locname
    }
    else {
        $name = "$VMName" + "00" + "$_"
        $locname = "Location00" + "$_"
        Write-Output (get-variable $locname).value
    }
}

Upvotes: 0

Related Questions