VMware Cloud Community
Tutti21
Contributor
Contributor
Jump to solution

Read VM Config save in array and parse in new VM

Hello,

I have some VM as WTS Servers I need to make them new with the same parameters like

Vmware folder

ESX Host

Name VM

MAC-Adress

Name NFS Datastore

that needs to be stored an a array or something

then I have a template that have all the infomation stores that are the same all on servers

after vcenter deployed the template the need to put in the information/config from above delete the server and gets to the next one in the cluster

 

can someone help me with that please

0 Kudos
1 Solution

Accepted Solutions
LucD
Leadership
Leadership
Jump to solution

Try with these.

The export script

Get-Datacenter -Name "DAK NSA" |

Get-VM |

Select Name,

@(N = 'VMName'; E = {$_.Get-VM.name}),  # Is this right ?

@{N = 'Folder'; E = {$_.Folder.Name}},

@{N = 'VMHost'; E = {$_.VMHost.Name}},

@{N = 'Inventar'; E = {(Get-Annotation -Entity $_ -CustomAttribute Inventar).Value}},

@{N = 'MAC'; E = {($_.ExtensionData.Config.Hardware.Device | where {$_ -is [VMware.Vim.VirtualEthernetCard]}).MacAddress}},

@{N = 'Portgroup'; E = {(Get-VirtualPortGroup -VM $_).Name}},

@{N = 'Datastore'; E = {(Get-View -Id $_.DatastoreIdList).Name}} |

Export-Csv -Path "U:\vmwarescript\WTS.csv" -NoTypeInformation -UseCulture

And the import and creation of the new VMs.
I used splatting on the New-VM cmdlet to keep it legible.

$NameTemplate = "Vorlage-Target"

$contactperson = "WTS"

$function = "WTS Target"


$template = Get-template $NameTemplate


foreach ($row in Import-csv "U:\vmwarescript\WTS.csv" -UseCulture) {

   $sVM = @{

   Template = $template

   Name = $row.VMname

   Datastore = $row.Datastore

   VMHost = $row.VMHost

   Location = $row.Folder

   }

   $vm = New-VM @sVM

   Get-NetworkAdapter -VM $vm | Set-NetworkAdapter -MacAddress $row.MAC -NetworkName $row.Portgroup -Confirm:$false

   Set-Annotation -Entity $vm -CustomAttribute contactperson -Value $contactperson

   Set-Annotation -Entity $vm -CustomAttribute function  -Value $function

   Set-Annotation -Entity $vm -CustomAttribute Inventar -Value $row.Inventar

}


Blog: lucd.info  Twitter: @LucD22  Co-author PowerCLI Reference

View solution in original post

19 Replies
LucD
Leadership
Leadership
Jump to solution

Not too sure what you really want?

Is it a report with the configuration data from the current server?

Or is it a template that you will use to create a new identical server (after deleting the original one)?


Blog: lucd.info  Twitter: @LucD22  Co-author PowerCLI Reference

0 Kudos
Tutti21
Contributor
Contributor
Jump to solution

I have like 100 WTS Server on like 40 ESXi Host

I need to save the Information on each VM (e.g. 1)(Vmware folder, ESX Host, Name VM, MAC-Adress,Name of NFS Datastore)

after that deploy a new VM from a template and then when the VM is deployed edit the Information/config from above so that the new  VM has the same infomation it just stored

then delete the old VM

last get to the next VM e.g. 2 do the same as above and next one

 

in the templete is just stores the same configuration that is on all Server teh same so the script dont need to read that just the one from above are different on each VM

 

hope thats better to understand

0 Kudos
LucD
Leadership
Leadership
Jump to solution

No, not really.

The information you want ot save is easy( provided each VM only has 1 vNIC and is located on only 1 datastore)

Get-VM |

Select Name,@{N='VMHost';E={$_.VMHost.Name}},

   @{N='MAC';E={($_.ExtensionData.Config.Hardware.Device | where{$_ -is [VMware.Vim.VirtualEthernetCard]}).MacAddress}},

   @{N='Datastore';E={(Get-View -Id $_.DatastoreIdList).Name}}


With the information you are saving, you can't really create a new VM.
You would still need a Template or something.

Secondly, your order of creating-deleting will not work, the vCenter doesn't allow duplicate MAC addresses.


Blog: lucd.info  Twitter: @LucD22  Co-author PowerCLI Reference

0 Kudos
Tutti21
Contributor
Contributor
Jump to solution

Ok then I try it other way around.

I have a template that have the standart information I deploy 1 VM from it.

Now I want that VM to have the same "exclusive" configuration from 1 of the existent VM in the Cluster like above then delete the VM or store the information first and delete and then change the settings

"Vmware folder, ESX Host, Name VM, MAC-Adress,Name of NFS Datastore"

but I think thats hard because you cant change the folder etc after you already deployed it and do so by hand.

0 Kudos
LucD
Leadership
Leadership
Jump to solution

I missed the VM Folder property, this includes it.

Does this now have all the information you need?

Get-VM |

Select Name,

   @{N='Folder';E={$_.Folder.Name}},

   @{N='VMHost';E={$_.VMHost.Name}},

   @{N='MAC';E={($_.ExtensionData.Config.Hardware.Device | where{$_ -is [VMware.Vim.VirtualEthernetCard]}).MacAddress}},

   @{N='Datastore';E={(Get-View -Id $_.DatastoreIdList).Name}}

If you have a template, do you have an OSCustomizationSpec to run as part of the cloning process?

What about the IP configuration?
The MAC address will need to be set after the cloning completes with the Set-NetworkAdapter cmdlet.


Blog: lucd.info  Twitter: @LucD22  Co-author PowerCLI Reference

0 Kudos
Tutti21
Contributor
Contributor
Jump to solution

as now I do it via srcipt but way to much is not automated

 

createVMfromTemplateWTS 01.ps1

 

 

NameTemplate ="Vorlage-Target-WTS-01-02"

$Datastore="WTS-01-02"

#$DatastoreCluster="WTS-01-4GB"

 

$ESX="10.10.10.10"

 

$Folder="01-WTS"

 

 

$Contact Person = "WTS"

$function= "WTS Target"

 

#Variables for VM

$Serverliste=Import-Csv "U:\60WTS.csv"

 

 

 

$Serverliste | ForEach-Object {Write-Host $_.Servername -foregroundcolor cyan

 

                New-VM -template (Get-template $NameTemplate) -Name $_.Servername -Datastore (Get-datastore $Datastore) -VMHost $ESX -Location $Folder

                #New-VM -template (Get-template $NameTemplate) -Name $_.Servername -Datastore (Get-DatastoreCluster $DatastoreCluster) -VMHost $ESX -Location $Folder

 

                $vm = Get-VM $_.Servername

                $vm | Get-NetworkAdapter | Set-NetworkAdapter -MacAddress $_.MAC -Confirm:$false

 

               

                $vm | Set-Annotation -CustomAttribute Contact Person -value $Contact Person

                $vm | Set-Annotation -CustomAttribute function -value $function

                $vm | Set-Annotation -CustomAttribute inventory -value $_.inventory

}

 

 

CSV
 

Servername,MAC,inventory

xxx,00:50:00:00:00:00,xxx
xxx2,00:50:00:00:00:00,xxx2
xxx3,00:50:00:00:00:00,xxx3

0 Kudos
Tutti21
Contributor
Contributor
Jump to solution

yeah and I forgot the Netzworkadapter or network vlan.

In the above it read the configuration and paste it in the new VM?

0 Kudos
LucD
Leadership
Leadership
Jump to solution

Ok, with the snippet I gave earlier, you can save that information in a CSV file.

And now your script can pull the values, that you have hard-coded in the current script, can be retrieved from that CSV file.


Blog: lucd.info  Twitter: @LucD22  Co-author PowerCLI Reference

0 Kudos
Tutti21
Contributor
Contributor
Jump to solution

thanks for the help

 

can you give some code that he reads all the VMs in Datacenter "WTS" with the above parameters in a csv file?

and what is the parameter for the networkadapter or vlan on a VM from a standart switch

0 Kudos
LucD
Leadership
Leadership
Jump to solution

Sure, try like this

Get-Datacenter -Name WTS |

Get-VM |

Select Name,

@{N = 'Folder'; E = {$_.Folder.Name}},

@{N = 'VMHost'; E = {$_.VMHost.Name}},

@{N = 'MAC'; E = {($_.ExtensionData.Config.Hardware.Device | where {$_ -is [VMware.Vim.VirtualEthernetCard]}).MacAddress}},

@{N = 'Datastore'; E = {(Get-View -Id $_.DatastoreIdList).Name}} |

Export-Csv -Path .\report.csv -NoTypeInformation -UseCulture

You can set the portgroup for a VM with the Set-NetworkAdapter cmdlet.

Get-VM | Get-NetworkAdapter |

Set-NetworkAdapter -NetworkName portgroup -Confirm:$false


Blog: lucd.info  Twitter: @LucD22  Co-author PowerCLI Reference

0 Kudos
Tutti21
Contributor
Contributor
Jump to solution

thanks again your doing great work here wish I could do powershell better

for reading the networkadapter from the VM to the csv

@{N = 'Network'; E = {$_.NetworkAdapter}} |

is it like that?

0 Kudos
LucD
Leadership
Leadership
Jump to solution

You can do like this

Get-Datacenter -Name WTS |

Get-VM |

Select Name,

@{N = 'Folder'; E = {$_.Folder.Name}},

@{N = 'VMHost'; E = {$_.VMHost.Name}},

@{N = 'MAC'; E = {($_.ExtensionData.Config.Hardware.Device | where {$_ -is [VMware.Vim.VirtualEthernetCard]}).MacAddress}},

@{N = 'Portgroup'; E = {(Get-VirtualPortGroup -VM $_).Name}},

@{N = 'Datastore'; E = {(Get-View -Id $_.DatastoreIdList).Name}} |

Export-Csv -Path .\report.csv -NoTypeInformation -UseCulture


Blog: lucd.info  Twitter: @LucD22  Co-author PowerCLI Reference

0 Kudos
Tutti21
Contributor
Contributor
Jump to solution

thanks but I need to trouble you again @LucD

here is my script that I think goes the right way but I forgot that I need to write a custom attribute to the CSVfile and the VMname


#read the folowing parameters to a csv
Get-Datacenter -Name "WTS" |

Get-VM |

Select Name,
@(N = 'VMName'; E = {$_.Get-VM.name}),  # Is this right ?

@{N = 'Folder'; E = {$_.Folder.Name}},

@{N = 'VMHost'; E = {$_.VMHost.Name}},

@{N = 'Inventar'; E = {$_.Inventar.Name | Get-Annotation -CustomAttribute Inventar}},  # Is ths right too ?

@{N = 'MAC'; E = {($_.ExtensionData.Config.Hardware.Device | where {$_ -is [VMware.Vim.VirtualEthernetCard]}).MacAddress}},

@{N = 'Portgroup'; E = {(Get-VirtualPortGroup -VM $_).Name}},

@{N = 'Datastore'; E = {(Get-View -Id $_.DatastoreIdList).Name}} |

Export-Csv -Path "U:\vmwarescript\WTS.csv" -NoTypeInformation -UseCulture


#write you VM-Template with parameters of CSVfile

#NameTemplate ="Vorlage-Target"
#NameTemplate ="Vorlage-Target"

$contactperson = "WTS"
$function= "WTS Target"

#Collor written VM
$CSVFile | ForEach-Object {Write-Host "$($CSVFile.VMname)" -foregroundcolor cyan

$CSVFile=Import-csv "U:\vmwarescript\WTS.csv"

New-VM -template (Get-template $NameTemplate) -Name "$($CSVFile.VMname)" -Datastore "($CSVFile.Datastore)" -VMHost "($CSVFile.VMHost) -Location "($CSVFile.Folder) -MAC "($CSVFile.MAC) -VirtualportGroup "($CSVFile.Portgroup) -Set-Annotation "($CSVFile.Inventar)"

                $vm | Set-Annotation -CustomAttribute contactperson -value $contactperson
                $vm | Set-Annotation -CustomAttribute function -value $FUNCTION
                $vm | Set-Annotation -CustomAttribute Inventar -value "($CSVFile.Inventar)"  # can you check please

0 Kudos
LucD
Leadership
Leadership
Jump to solution

Try changing that line to

@{N = 'Inventar'; E = {(Get-Annotation -Entity $_ -CustomAttribute Inventar).Value}},


Blog: lucd.info  Twitter: @LucD22  Co-author PowerCLI Reference

0 Kudos
Tutti21
Contributor
Contributor
Jump to solution

Ok the CSV file seem fine now

is it possible to set those parameters to the command new vm template

New-VM -template (Get-template $NameTemplate)

-Name "$($CSVFile.VMname)"

-Datastore "($CSVFile.Datastore)"

-VMHost "($CSVFile.VMHost)

-Location "($CSVFile.Folder)

-MAC "($CSVFile.MAC)

-VirtualportGroup "($CSVFile.Portgroup)

-Set-Annotation "($CSVFile.Inventar)"

I think here are some errors too because I get some, I hope you can help me there too.

0 Kudos
LucD
Leadership
Leadership
Jump to solution

Would you mind sharing those errors, avoids me digging in the dark.


Blog: lucd.info  Twitter: @LucD22  Co-author PowerCLI Reference

0 Kudos
Tutti21
Contributor
Contributor
Jump to solution

thats what I try now I dont know If I must set e.g. $CSVFile.Name  in () and or "" but both seem do get the same error

"#write VM-Template with parameters of CSVfile

$NameTemplate ="T-template"

$contactperson = "WTS"

$function= "WTS "

#colour written VM

#$CSVFile | ForEach-Object {Write-Host "$($CSVFile.VMname)"} -foregroundcolor cyan

$CSVFile=Import-csv "U:\vmwarescript\WTS.csv"

New-VM -template (Get-template $NameTemplate) -Name $CSVFile.Name -Datastore $CSVFile.Datastore -VMHost $CSVFile.VMHost -Location $CSVFile.Folder -MAC $CSVFile.MAC -VirtualportGroup $CSVFile.Portgroup -Set-Annotation $CSVFile.Inventar

                $vm | Set-Annotation -CustomAttribute contactperson -value $contactperson

                $vm | Set-Annotation -CustomAttribute function -value $FUNCTION

                $vm | Set-Annotation -CustomAttribute Inventar -value $CSVFile.Inventar"

"New-VM : A positional parameter cannot be found that accepts argument 'System.Object[]'.

At U:\vmwarescript\test.ps1:14 char:1

+ New-VM -template (Get-template $NameTemplate) -Name "$($CSVFile.Name) ...

+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

    + CategoryInfo          : InvalidArgument: (:) [New-VM], ParameterBindingException

    + FullyQualifiedErrorId : PositionalParameterNotFound,VMware.VimAutomation.ViCore.Cmdlets.Commands.NewVM

Set-Annotation : Cannot validate argument on parameter 'Entity'. The argument is null. Provide a valid value for the argument, and

then try running the command again.

At U:\vmwarescript\test.ps1:18 char:23

+ ...       $vm | Set-Annotation -CustomAttribute contactperson -value $con ...

+                 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

    + CategoryInfo          : InvalidData: (:) [Set-Annotation], ParameterBindingValidationException

    + FullyQualifiedErrorId : ParameterArgumentValidationError,VMware.VimAutomation.ViCore.Cmdlets.Commands.SetAnnotation

Set-Annotation : Cannot validate argument on parameter 'Entity'. The argument is null. Provide a valid value for the argument, and

then try running the command again.

At U:\vmwarescript\test.ps1:19 char:23

+ ...       $vm | Set-Annotation -CustomAttribute function -value $FUNCTION ...

+                 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

    + CategoryInfo          : InvalidData: (:) [Set-Annotation], ParameterBindingValidationException

    + FullyQualifiedErrorId : ParameterArgumentValidationError,VMware.VimAutomation.ViCore.Cmdlets.Commands.SetAnnotation

Set-Annotation : Cannot validate argument on parameter 'Entity'. The argument is null. Provide a valid value for the argument, and

then try running the command again.

At U:\vmwarescript\test.ps1:20 char:23

+ ...       $vm | Set-Annotation -CustomAttribute Inventar -value "($CSVFil ...

+                 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

    + CategoryInfo          : InvalidData: (:) [Set-Annotation], ParameterBindingValidationException

    + FullyQualifiedErrorId : ParameterArgumentValidationError,VMware.VimAutomation.ViCore.Cmdlets.Commands.SetAnnotation"

0 Kudos
LucD
Leadership
Leadership
Jump to solution

Try with these.

The export script

Get-Datacenter -Name "DAK NSA" |

Get-VM |

Select Name,

@(N = 'VMName'; E = {$_.Get-VM.name}),  # Is this right ?

@{N = 'Folder'; E = {$_.Folder.Name}},

@{N = 'VMHost'; E = {$_.VMHost.Name}},

@{N = 'Inventar'; E = {(Get-Annotation -Entity $_ -CustomAttribute Inventar).Value}},

@{N = 'MAC'; E = {($_.ExtensionData.Config.Hardware.Device | where {$_ -is [VMware.Vim.VirtualEthernetCard]}).MacAddress}},

@{N = 'Portgroup'; E = {(Get-VirtualPortGroup -VM $_).Name}},

@{N = 'Datastore'; E = {(Get-View -Id $_.DatastoreIdList).Name}} |

Export-Csv -Path "U:\vmwarescript\WTS.csv" -NoTypeInformation -UseCulture

And the import and creation of the new VMs.
I used splatting on the New-VM cmdlet to keep it legible.

$NameTemplate = "Vorlage-Target"

$contactperson = "WTS"

$function = "WTS Target"


$template = Get-template $NameTemplate


foreach ($row in Import-csv "U:\vmwarescript\WTS.csv" -UseCulture) {

   $sVM = @{

   Template = $template

   Name = $row.VMname

   Datastore = $row.Datastore

   VMHost = $row.VMHost

   Location = $row.Folder

   }

   $vm = New-VM @sVM

   Get-NetworkAdapter -VM $vm | Set-NetworkAdapter -MacAddress $row.MAC -NetworkName $row.Portgroup -Confirm:$false

   Set-Annotation -Entity $vm -CustomAttribute contactperson -Value $contactperson

   Set-Annotation -Entity $vm -CustomAttribute function  -Value $function

   Set-Annotation -Entity $vm -CustomAttribute Inventar -Value $row.Inventar

}


Blog: lucd.info  Twitter: @LucD22  Co-author PowerCLI Reference

Tutti21
Contributor
Contributor
Jump to solution

this works great , you are the best.

0 Kudos