Issue with 2 variables in a Create-VM GUI

Trying to create a GUI that works to create multiple VMs at once. The code works when creating one VM, just having an issue with pairing the Server name text box and the IP text box.

	$includedServers = ($vmnametextbox.Text).Replace(" ","")
	$includedIPs = ($iptextbox.Text).Replace(" ","")
    if ($includedServers.Length -gt 0) {$includedServers = @($includedServers.Split(","))} else {$includedServers = @("*")}
    if ($includedIPs.Length -gt 0) {$includedIPs = @($includedIPs.Split(","))} else {$includedIPs = @("*")}
	$serverout = @()
	$ipout = @()
	        $i = 0
	        foreach ($vm in $includedServers) {
		       if ($i -lt 0) {
		          $serverout += write-host 'this sucks'
		       } else {
		         $serverout += [pscustomobject]@{Server=$vm.ToUpper()}
		       }
		       $i++
	        }
	       
	         $i = 0
	         foreach ($ip in $includedIPs) {
		        if ($i -lt 0) {
		           $ipout += write-host 'this sucks'
		        } else {
		           $ipout += [pscustomobject]@{IP=$ip}
		        }
		        $i++
		        }
	
	$Servers = Join-Object -Left $serverout -Right $ipout

I use this to get the Servers and IPs in a combined object from the text boxes. The output looks fine, and some basic code works, like write-host.


Server IP           
------ --           
TEST1  10.135.16.247
TEST2  10.135.16.248
TEST3  10.135.16.249
TEST4  10.135.16.244
TEST5  10.135.16.245
TEST6  10.135.16.246

That is the combined object, and below is a simple command.

foreach ($server in $servers) {
write-host $server.server'is using'$server.ip
 }


TEST1 is using 10.135.16.247
TEST2 is using 10.135.16.248
TEST3 is using 10.135.16.249
TEST4 is using 10.135.16.244
TEST5 is using 10.135.16.245
TEST6 is using 10.135.16.246

The problem comes when putting into a function to deploy to the multiple VMs at once. I get an error that the IPaddress parameter is invalid.
That code is below.

	Function Deploy-VM
	{
		Lock-FormFields
        $DataGridView.Columns[0].Name = "Progress"

			foreach ($server in $servers)  {
 	TRY
		{
			$CustomSpec = New-OSCustomizationSpec -OSCustomizationSpec $customspecComboBox.Text -Name ([guid]::NewGuid().guid) -Type Persistent
					
			if ($domainComboBox.text -ne "No-Domain")
				{
				if ($customspec.ostype -eq "Windows") { $CustomSpec = $CustomSpec | Set-OSCustomizationSpec -Domain $domainComboBox.text -DomainCredentials $DomainCredentials }
			else { $CustomSpec = $CustomSpec | Set-OSCustomizationSpec -Domain $domainComboBox.text }
				}
			elseif ($customspec.ostype -eq "Windows") { $CustomSpec = $CustomSpec | Set-OSCustomizationSpec -Workgroup "WORKGROUP" }
					
			$DNS = $dns1TextBox.Text, $dns2TextBox.Text

            $CustomSpec | Get-OSCustomizationNicMapping | Set-OSCustomizationNicMapping -IpMode UseStaticIP -IpAddress $server.ip -SubnetMask $netmaskTextBox.Text -DefaultGateway $gatewayTextBox.Text -Dns $DNS

			$NewVMTask = New-VM -Template $templateComboBox.Text -OSCustomizationSpec $CustomSpec -ResourcePool $cluster -Datastore $datastoreComboBox.Text -Name $server.server -RunAsync
					while ($TaskStatus.State -ne "Success")
					{
						$TaskStatus = get-task -Id $NewVMTask.id
						sleep -Milliseconds 1000
					}
			$NewVM = get-vm -id $NewVMTask.ExtensionData.Info.result
			$NewVM | Get-NetworkAdapter | Set-NetworkAdapter -StartConnected $true -Confirm:$false -NetworkName $portgroupComboBox.Text
			$NewVM | Set-VM -MemoryGB $memoryComboBox.text -NumCpu $cpuComboBox.text -Confirm:$false
			Move-VM -VM $NewVM -InventoryLocation (Get-Folder $folderComboBox.text) -Destination ($NewVM | Get-VMHost) -Confirm:$false
			$NewVM | Start-VM
			if ($Attributes) { foreach ($attribute in $Attributes) { Set-Annotation -Entity $server.server -CustomAttribute $attribute.CustomAttribute -Value $attribute.Value } }
			(Get-Datastore $datastoreComboBox.Text).ExtensionData.RefreshDatastoreStorageInfo()
			New-TagAssignment -Entity $server.server -Tag $tag
			Update-Sheets
			Start-Sleep -Seconds 15
			Write-DeployLog -DeploymentLog $DeploymentLog
					
		}
		CATCH
		{
			$DataGridView.Rows.Clear()
			$DataGridView.Rows.Add("Error : " + $_.Exception)
			Write-Error $_.Exception -ErrorAction SilentlyContinue
		}
		FINALLY
		{
			if ($CustomSpec) { $CustomSpec | Remove-OSCustomizationSpec -Confirm:$false }
			Lock-FormFields -Unlock
			$DataGridView.Columns[0].Name = "Process"
		}
	}
}

There are a lot of other form functions and such, but this is the function where the task fails. Presumably from either creating the custom spec itself, or trying to create the custom spec NIC parameters.
Because it’s in a Form, I don’t have the debugging available to see what IPaddress is trying to go in during the creation. Just from where I pull it apart and do it more manually like at the beginning of this post to make sure the object looks correct.

Any help would be appreciated.

And yes, I know there’s vRA. I’m just trying to do this to add things like updating our server inventory, email patching lists, and adding servers to groups and OUs based off of name.
Takes a few other manual steps out of our hands all during a single step in this form.
Again, it all works with a single VM, just not when I try to add multiple VMs/IPs

I got it figured out, in part anyways.

I’m so used to putting my “servers” outside of a function so they can be called in the functions, and forgot about this being a form.
As it was, the server list looked empty. I ended up adding an export-csv of the server list to see what the GUI was trying to use when I hit deploy. Realized it was just a *, which is from my if statement on $includedServers and $includedIPs.
That’s when I realized it was empty because the commands for filling out the server list was being done as soon as I ran the GUI, not after I hit deploy.

Added the Server list to a function, and called that at the beginning of the DeployVM function.

New GetServers Function added in globals;

    function GetServers {
    $includedServers = ($vmnametextbox.Text).Replace(" ","")
	$includedIPs = ($iptextbox.Text).Replace(" ","")
    if ($includedServers.Length -gt 0) {$includedServers = @($includedServers.Split(","))} else {$includedServers = @("*")}
    if ($includedIPs.Length -gt 0) {$includedIPs = @($includedIPs.Split(","))} else {$includedIPs = @("*")}
	$serverout = @()
	$ipout = @()
	        $i = 0
	        foreach ($vm in $includedServers) {
		       if ($i -lt 0) {
		          $serverout += write-host 'this sucks'
		       } else {
		         $serverout += [pscustomobject]@{Server=$vm.ToUpper()}
		       }
		       $i++
	        }
	       
	         $i = 0
	         foreach ($ip in $includedIPs) {
		        if ($i -lt 0) {
		           $ipout += write-host 'this sucks'
		        } else {
		           $ipout += [pscustomobject]@{IP=$ip}
		        }
		        $i++
		        }
	
	$Servers = Join-Object -Left $serverout -Right $ipout
    $Servers | Export-Csv c:\temp\serverlist.csv -NoTypeInformation
    return $Servers
    }

Addition to the beginning of DeployVM function;

Function Deploy-VM
	{
		Lock-FormFields
        $serverlist = GetServers
        foreach ($server in $serverlist)  {            
		  TRY
		    {

I have other issues now, but ones I can work through. Just glad I got this one figured out since it was giving me a hard time.