I am attempting to automate the creation of VMs by using a CSV file and I am encountering issues with assigning the VLAN based on the values that are found within the CSV file. I am wondering if I am doing this correctly and if not, if anybody would know the correct/alternative way of performing this operation.
The script I am using is:
# Specify vCenter Server, vCenter Server username and vCenter Server user password
write-host “Please specify vCenter Server and enter credentials” -foreground green
$vc = read-Host "Connect to which vCenter Server?"
write-host “Connecting to vCenter Server $vc” -foreground green
$CSVPath = "C:\VMDeploy\PROD_VMRequestTEST.xlsx.csv"
Connect-VIServer -Server $vc
# Specify vCenter Server Virtual Machine & Templates folder
$Folder = “Discovered virtual machine”
#
Import-Csv -Path $CSVPath |
%{
$esx = Get-Cluster $_.Cluster | Get-VMHost -State connected
Write-Host “Creation of VM $($_.Name) initiated” -ForegroundColor green
New-VM -Name $_.Name -VMHost ($esx | Get-Random) -Location $Folder
$list = Get-Cluster $_.Cluster | Get-VMHost | Select Name
foreach ($esxhost in $list)
{New-VirtualPortgroup -VirtualSwitch vSwitch0 "VLAN $($_.VLAN)"
Set-VirtualPortGroup -VirtualPortGroup "VLAN $($_.VLAN)" -VLANID $($_.VLAN)
Write-Host "Power On of the VM $($_.Name) initiated" -ForegroundColor green
Start-VM -VM $_.Name-confirm:$false -RunAsync
I am currently able to apply the Cluster and Name columns of the CSV file thus far but the error occurs when it attempts to apply the New-VirtualPortgroup and Set-VirtualPortGroup commands. The errors that occur are:
New-VirtualPortGroup The specified parameter 'VirtualSwitch' expects a single value, but your name
criteria 'vSwitch0' corresponds to multiple values.
Set-VirtualPortGroup : Cannot bind parameter 'VirtualPortGroup'. Cannot
convert the "VLAN 900" value of type "System.String" to type
"VMware.VimAutomation.ViCore.Types.V1.Host.Networking.VirtualPortGroup".
I have tried to comment out the ""VLAN $($_.VLAN)"" section of the "{New-VirtualPortgroup -VirtualSwitch vSwitch0 "VLAN $($_.VLAN)"" line to try to move past the error indicating that the criteria 'vSwitch0' corresponde to multiple values but it does not make a difference. The VmHosts contain Standard Switch: vSwitch0 and VLAN 900 with VLANID: 900.
I appreciate any help you may provide,
It looks as if you have more than one vSwitch0 returned.
I assume this switch is defined on each ESXi node, which would explain why multiple objects are returned.
The New-VirtualPortgroup cmdlet will first resolve the vSwitch0, but there probably more than one returned.
Try adding a Get-VirtualSwitch cmdlet at the beginning of that pipeline construct.
When you add the VMHost parameter, only one vSwitch0 object will be passed to the New-VirtualPortgroup cmdlet.
Something like this
foreach ($esxhost in $list)
{
Get-VirtualSwitch -Name vSwitch0 -VMHost $esxhost |
New-VirtualPortgroup -Name "VLAN $($_.VLAN)"
Set-VirtualPortGroup -VirtualPortGroup "VLAN $($_.VLAN)" -VLANID $($_.VLAN)
Blog: lucd.info Twitter: @LucD22 Co-author PowerCLI Reference
It looks as if you have more than one vSwitch0 returned.
I assume this switch is defined on each ESXi node, which would explain why multiple objects are returned.
The New-VirtualPortgroup cmdlet will first resolve the vSwitch0, but there probably more than one returned.
Try adding a Get-VirtualSwitch cmdlet at the beginning of that pipeline construct.
When you add the VMHost parameter, only one vSwitch0 object will be passed to the New-VirtualPortgroup cmdlet.
Something like this
foreach ($esxhost in $list)
{
Get-VirtualSwitch -Name vSwitch0 -VMHost $esxhost |
New-VirtualPortgroup -Name "VLAN $($_.VLAN)"
Set-VirtualPortGroup -VirtualPortGroup "VLAN $($_.VLAN)" -VLANID $($_.VLAN)
Blog: lucd.info Twitter: @LucD22 Co-author PowerCLI Reference
Thanks for the response - I went ahead and added what you suggested and it is now returning a new error related to the Get-VirtualSwitch cmdlet:
Get-VirtualSwitch : Cannot bind parameter 'VMHost'. Cannot convert the ""
value of type "System.Management.Automation.PSCustomObject" to type
"VMware.VimAutomation.ViCore.Types.V1.Inventory.VMHost".
+ {Get-VirtualSwitch -Name vSwitch0 -VMHost $esxhost |
Does this error have something to do with $list returning 2 hosts when it is trying to set -VMHost?
I appreciate your help with this
Oops, didn't notice you had a Select after the Get-VMHost line.
Change that line to
$list = Get-Cluster $_.Cluster | Get-VMHost
Blog: lucd.info Twitter: @LucD22 Co-author PowerCLI Reference
Thank you again for all of your help with this.
I made the changes to the line that you suggested and I was presented with this error:
New-VirtualPortgroup : New-VirtualPortGroup
The specified key, name, or identifier already exists.
+ New-VirtualPortgroup -Name "VLAN $($_.VLAN)"
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : NotSpecified: (:) [New-VirtualPortGroup], VimExc
eption
+ FullyQualifiedErrorId : Core_BaseCmdlet_UnknownError,VMware.VimAutomatio
n.ViCore.Cmdlets.Commands.Host.NewVirtualPortGroup
I attempted to bypass this error by commenting out the line that had the New-VirtualPortgroup cmdlet to see if it would go through without it and then I was faced with this error relating to the Set-VirtualPortGroup cmdlet:
Set-VirtualPortGroup : Cannot bind parameter 'VirtualPortGroup'. Cannot
convert the "VLAN 928" value of type "System.String" to type
"VMware.VimAutomation.ViCore.Types.V1.Host.Networking.VirtualPortGroup".
+ Set-VirtualPortGroup -VirtualPortGroup "VLAN $($_.VLAN)" -VLANID
$($_.VLAN)
+ ~~~~~~~~~~~~~~~~~
+ CategoryInfo : InvalidArgument: (:) [Set-VirtualPortGroup], Par
ameterBindingException
+ FullyQualifiedErrorId : CannotConvertArgumentNoMessage,VMware.VimAutomat
ion.ViCore.Cmdlets.Commands.SetVirtualPortGroup
Is my syntax incorrect for specifying the name for the Set-VirtualPortGroup cmdlet?
Are you sure that portgroup is not already there?
Did you do a cleanup after your previous runs?
Otherwise attach the script that you are currently using and an extract of your CSV file (mask out sensite data!)
Blog: lucd.info Twitter: @LucD22 Co-author PowerCLI Reference
Whoops, you are correct - I was misunderstanding and I was trying to create a VLAN that already previously existed. I changed the value in the CSV file to something unique and it successfully created the VLAN; however, it did not assign the newly created VMs to the VLAN that was created. I see 'VLAN 800' in vSphere now as is specified in the CSV file but an error related to Set-VirtualPortGroup cmdlet appears when it gets to that step:
Set-VirtualPortGroup : Cannot bind parameter 'VirtualPortGroup'. Cannot
convert the "VLAN 800" value of type "System.String" to type
"VMware.VimAutomation.ViCore.Types.V1.Host.Networking.VirtualPortGroup".
+ Set-VirtualPortGroup -VirtualPortGroup "VLAN $($_.VLAN)" -VLANID
$($_.VLAN)
+ ~~~~~~~~~~~~~~~~~
+ CategoryInfo : InvalidArgument: (:) [Set-VirtualPortGroup], Par
ameterBindingException
+ FullyQualifiedErrorId : CannotConvertArgumentNoMessage,VMware.VimAutomat
ion.ViCore.Cmdlets.Commands.SetVirtualPortGroup
The newly created VMs appear to be placed in a default VLAN 150 on creation and I would like them to be assigned to the one that is created (800)
The Set-0VirtualPortgroup cmdlet expects a VirtualPortgroup object (as parameter or in the pipeline).
You can pipe the output of the New-VirtualPortGroup cmdlet to the Set-VirtualPortgroup cmdlet.
But you can already specify the VLANid on the New-VirtualPortgroup cmdlet, so there is no need to do the Set-VirtualPortgroup..
Blog: lucd.info Twitter: @LucD22 Co-author PowerCLI Reference
I'm not sure I get the purpose of the script you are trying to write.
You create a VM from the CSV, then you create a new Portgroup on each ESXi node.
Is it the intention that the VM is connected to this newly created portgroup?
Blog: lucd.info Twitter: @LucD22 Co-author PowerCLI Reference
You are correct - I realized that I was incorrectly trying to use the Set-VirtualPortGroup cmdlet as Set-NetworkAdapter. I have solved the issue now and the script is working the way I intended it to.
I really appreciate all of your help with this - I am new to this and trying to learn as I go.
Great that you got it working.
And no problem in asking, that's what the community is for.
We all started with this at some point :smileygrin:
Blog: lucd.info Twitter: @LucD22 Co-author PowerCLI Reference