0

I am making a user input driven deployment script. Basically I am asking a user "How many VM's would you like to deploy" and depending on the answer I want to create and use so many variables.

So my code currently asks the user for number of VM's Then it loops to create a new variable and ask user to fill that variable however I don't know how to use the variable that is created.

$Vmnumber = Read-Host "Enter number iof VM's that you would like to create."
for($i = 1; $i -le $Vmnumber; $i++){
    New-Variable -Name "vmip$i"
    Write-Host "Please Enter IP Address for VM$i (Site A): " -ForegroundColor Yellow -NoNewline

    do {
        if(($vmip + $i = Read-Host "Press enter to accept default IP form PHPIPAM" $SiteAsorting[$i]"or type a differnet one.") -eq ''){$vmip + $i = $SiteAsorting[$1]}else{$vmip + $i}
        $ok = $vmip + $1 -match $IPPattern
        if ($ok -eq $false) {
            Write-Warning ("'{0}' is not an IP address." -f $vmip + $i)
            write-host -fore Yellow "Please Enter IP for VM$i : " -NoNewline
        }
    } until ( $ok )

}

'''

I would like the the code to create new variable and ask for user input every iteration.

Thanks in advance for any help

4
  • 1
    I usually don't recommend Read-Host because it can't be automated. I would instead recommend to use command-line parameters (param() statement). Your script will be much more flexible, and you can have input validation more or less for free. Commented Aug 27, 2019 at 16:26
  • 4
    Your use of dynamically named variables is completely unnecessary here - I'd strongly recommend re-using a local variable (ie. just $vmip), and then add the final value to an array, list or hashtable Commented Aug 27, 2019 at 16:29
  • 2
    please pay attention to what Mathias R. Jessen said about dynamically named $Vars ... don't do that. [grin] seriously, it is a really bad idea when there are structures already available to do what you want ... arrays, generic.lists, and lots of other collection types. Commented Aug 27, 2019 at 16:51
  • @MathiasR.Jessen Thanks for that. How would I go about that in my example? Commented Aug 28, 2019 at 8:25

2 Answers 2

2

I don't know how to use the variable that is created.

That makes sense, and the solution is simple:

Don't use dynamically named variables.

Use an array or a dictionary/hashtable instead! Since in your example you want to name the VM's starting from 1, and array indices start at 0, let's use a hashtable instead:

# First, let's ensure no one enters a nonsensical value like "100000" or "-3" or "ur mom"
while(([int]$numberOfVMs = Read-Host "Enter number of VM's that you would like to create.") -notin 1..20){
    Write-Error "Please enter a number between 1 and 20"
}

# Create a hashtable to hold the IP addresses
$VMIPs = @{}

foreach($VMNumber in 1..$numberOfVMs){
    do {
        Write-Host "Please Enter IP Address for VM${VMNumber} (Site A): " -ForegroundColor Magenta -NoNewline

        # Read whatever the user suggests
        $suggestedIP = Read-Host "Press enter to accept default IP form PHPIPAM ($($SiteAsorting[$VMNumber]) or type a differnet one."

        # Handle the default 
        if ($suggestedIP -eq '') {
            $suggestedIP = $SiteAsorting[$VMNumber]
        }

        # Now, let's do our validation on the IP (regex is a poor validation tool here, but you can update this later)
        $ok = $suggestedIP -match $IPPattern

        if (-not $ok) {
            # Warn the user that the IP wasn't valid
            Write-Warning "${suggestedIP} is not a valid IP address!"
        }
        else {
            # or, store the IP for later reference
            $VMIPs["VM${VMNumber}"] = $suggestedIP
        }
    } until ( $ok )
}

Notice the string value we used for the hashtable keys above: "VM${VMNumber}" - so, now, if I entered 3 in the first prompt, we should expect a hashtable with the keys VM1, VM2 and VM3, so later we can do:

foreach($VMNumber in 1..$numberOfVMs){
    Write-Host "Now assigning IP to VM${VMNumber}!"
    $IPAddress = $VMIPs["VM${VMNumber}"]
    Add-VMIPAddress -VM "someVMName" -IP $IPAddress
}
Sign up to request clarification or add additional context in comments.

2 Comments

Thank you very much for explaining, and giving examples. I shall give that a go!
This has worked like charm. I accept this as a valid response and thank you for explanation. This helped me to understand the proper way. I feel comfortable to reuse that code in other parts of my script !
0
do {
Write-Host " Enter number of VM's that you would like to create. " -NoNewline ;
write-host "[VMs] : " -ForegroundColor Yellow -NoNewline;
    $NumberOfVM = "Notok"; $NumberOfVM = Read-Host; 
    if($NumberOfVM-ne $Null -and $NumberOfVM.Length -le 30 -$NumberOfVM)
    {Write-Host "ok" -NoNewline}else{Write-Host "Are You Kidding Me?!" -F Red -B Yellow}} 
until($NumberOfVM -eq "ok")

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.