VMware Cloud Community
jackc201110141
Contributor
Contributor
Jump to solution

powercli script to rename vm's from csv

Hello,

I need some help writing a script to rename vm's and change the network connection to the correct vlan, based on input of a csv file.  Only the vm display name in vcenter needs to be changed (vmdk's will be renamed aftwards by peforming a svmotion)

csv will look like this:

oldname,newname,tobevlan

vm1,tag-vm1,vlan4

vm2,tag-vm2,vlan7

vm3,tag-vm3,vlan4

I'm already using LucD's script to import vm's based on a csv.  Now I need to add this part the to script.  I need to import a large number of vm's place on a few datastores.  There are some vm's that don't need to be imported, so I use a csv to import only the needed one's.  After the registration of the vm's, they all need to be renamed and network connection should be changed.

Thanks for your help.

Regards,

Christophe

0 Kudos
1 Solution

Accepted Solutions
LucD
Leadership
Leadership
Jump to solution

You can try something like this

###############################################################################################################################
# CSV file layout
#
# VMXPath,oldname,newname,vlan
# "[ds] VM1/VM1.vmx",VM1,newVM1,net1
# "[ds] VM2/VM2.vmx",VM2,newVM2,net2
# "[ds] VM3/VM3.vmx",VM3,newVM3,net3
# "[ds] VM4/VM4.vmx",VM4,newVM4,net4
#
###############################################################################################################################
$vms = Import-Csv D:\temp\import-vm.csv -UseCulture

$targetVMX
= $vms | Select -ExpandProperty VMXPath
$Cluster
= "CLUSTER_01"
$Datastores
= "*_DATASTORE"
$VMFolder
= "TESTFOLDER"
$ResourcePool
= "TestRP"
$ESXHost
= Get-Cluster $Cluster | Get-VMHost | Get-Random
foreach
($Datastore in Get-Datastore $Datastores) {   # Search for .VMX Files in Datastore   $ds = Get-Datastore -Name $Datastore | %{Get-View $_.Id}   $SearchSpec = New-Object VMware.Vim.HostDatastoreBrowserSearchSpec
  $SearchSpec.matchpattern = "*.vmx"
  $dsBrowser = Get-View $ds.browser
  $DatastorePath = "[" + $ds.Summary.Name + "]"   # Find all .VMX file paths in Datastore, filtering out ones with .snapshot (Useful for NetApp NFS)   $SearchResult = $dsBrowser.SearchDatastoreSubFolders($DatastorePath, $SearchSpec) | where {$_.FolderPath -notmatch ".snapshot"} | %{$_.FolderPath + ($_.File | select Path).Path}   # Register all .vmx Files as VMs on the datastore   foreach($VMXFile in $SearchResult) {     if($targetVMX -contains $VMXFile){       New-VM -VMFilePath $VMXFile -VMHost $ESXHost -Location $VMFolder -ResourcePool $ResourcePool -RunAsync
    }   } }
foreach($vm in $vms){   Get-VM $($vm.oldname) |   Set-vm -name $($vm.newname) -confirm:$false |    Get-NetworkAdapter |   Set-NetworkAdapter -Networkname $($vm.vlan) -confirm:$false
}



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

View solution in original post

0 Kudos
26 Replies
CRad14
Hot Shot
Hot Shot
Jump to solution

At the very core/basic level

get-vm oldname | set-vm -name newname

Did you need help getting the info from the csv... or is the above good for what you need?

Conrad www.vnoob.com | @vNoob | If I or anyone else is helpful to you make sure you mark their posts as such! 🙂
0 Kudos
jackc201110141
Contributor
Contributor
Jump to solution

I actually need help from getting the info from the csv.

I know  this is the command to change the name: get-vm oldname | set-vm -name newname

But I need a script that reads the complete cvs and change all the vm names.

0 Kudos
CRad14
Hot Shot
Hot Shot
Jump to solution

It would look something like this

$csv=Import-CSV "csvname"

FOREACH ($row in $csv)

{ Get-VM $($row.oldname)  | Set-vm -name $($row.newname) -confirm:$false  }

Something like that...You should definitely test with a small csv first to make sure it does what you want.. there some adjustments to it that could be made for speed, but this should do the job.

Conrad www.vnoob.com | @vNoob | If I or anyone else is helpful to you make sure you mark their posts as such! 🙂
jackc201110141
Contributor
Contributor
Jump to solution

Thank you very much.  This works.  Now I can continue working on my script to integrate this part.

0 Kudos
jackc201110141
Contributor
Contributor
Jump to solution

Can I add Set-NetworkAdapter -NetworkName in the same line?

Like this?

FOREACH ($row in $csv)
{ Get-VM $($row.oldname) | Set-vm -name $($row.newname) | Set-NetworkAdapter -Networkname $($row.tobevlan) -confirm:$false
   }

Is this correct?

0 Kudos
CRad14
Hot Shot
Hot Shot
Jump to solution

I think it should work but with a slight modification

{ Get-VM $($row.oldname) | Set-vm -name $($row.newname) |  Get-NetworkAdapter | Set-NetworkAdapter -Networkname $($row.tobevlan) -confirm:$false
   }

Conrad www.vnoob.com | @vNoob | If I or anyone else is helpful to you make sure you mark their posts as such! 🙂
jackc201110141
Contributor
Contributor
Jump to solution

Thanks again CRAD14 for your help.

I now have one script that adds vm's to the vCenter inventory with info from a CSV (thank you LucD for the script)

###############################################################################################################################
$targetVMX = Get-Content D:\temp\import-vm.csv
$Cluster = "CLUSTER_01"
$Datastores = "*_DATASTORE"
$VMFolder = "TESTFOLDER"
$ResourcePool = "TestRP"
$ESXHost = Get-Cluster $Cluster | Get-VMHost | Get-Random

foreach($Datastore in Get-Datastore $Datastores) {
   # Search for .VMX Files in Datastore
   $ds = Get-Datastore -Name $Datastore | %{Get-View $_.Id}
   $SearchSpec = New-Object VMware.Vim.HostDatastoreBrowserSearchSpec
   $SearchSpec.matchpattern = "*.vmx"
   $dsBrowser = Get-View $ds.browser
   $DatastorePath = "[" + $ds.Summary.Name + "]"

   # Find all .VMX file paths in Datastore, filtering out ones with .snapshot (Useful for NetApp NFS)
   $SearchResult = $dsBrowser.SearchDatastoreSubFolders($DatastorePath, $SearchSpec) | where {$_.FolderPath -notmatch ".snapshot"} | %{$_.FolderPath + ($_.File | select Path).Path}

   # Register all .vmx Files as VMs on the datastore
   foreach($VMXFile in $SearchResult) {
  if($targetVMX -contains $VMXFile){
   New-VM -VMFilePath $VMXFile -VMHost $ESXHost -Location $VMFolder -ResourcePool $ResourcePool -RunAsync
   }
}
}
###############################################################################################################################
import-vm.csv content:
[01_DATASTORE] TESTVM03/TESTVM03.vmx
[02_DATASTORE] TESTVM02/TESTVM02.vmx
[03_DATASTORE] TESTVM01/TESTVM01.vmx


And I have another script that changes the display name of the vm with info from another CSV (thank you CRAD14 for the script)

###############################################################################################################################
$csv=Import-CSV "d:\temp\renamevm.csv"
FOREACH ($row in $csv)
{ Get-VM $($row.oldname) | Set-vm -name $($row.newname) -confirm:$false |  Get-NetworkAdapter | Set-NetworkAdapter -Networkname $($row.vlan) -confirm:$false
   }
###############################################################################################################################
renamevm.csv content:
oldname,newname,vlan
TESTVM01,sn123-TESTVM01,Testvlan1
TESTVM02,sn124-TESTVM02,Testvlan3
TESTVM03,sn125-TESTVM03,Testvlan5


Is it possible to combine both scripts into one script and using only one CSV-file?
The goal of this script is to register a number of vm's, change the display name and network with info from just one CSV-file.

0 Kudos
CRad14
Hot Shot
Hot Shot
Jump to solution

If you have all the data in one csv, you could honestly, just place all the code in one ps1 file and run it.

Conrad www.vnoob.com | @vNoob | If I or anyone else is helpful to you make sure you mark their posts as such! 🙂
0 Kudos
jackc201110141
Contributor
Contributor
Jump to solution

I'm struggling with this because I don't have a header in the first CSV file.  If I add a header for the vmx path, what do I have to change so that

foreach($VMXFile in $SearchResult) {
if($targetVMX -contains $VMXFile){.................

keeps working?

0 Kudos
CRad14
Hot Shot
Hot Shot
Jump to solution

Essentially...

The way that the first script calls the csv, with the get-content, you should be fine to add the headers and pretty much anything else you want Smiley Happy

Conrad www.vnoob.com | @vNoob | If I or anyone else is helpful to you make sure you mark their posts as such! 🙂
0 Kudos
jackc201110141
Contributor
Contributor
Jump to solution

if i add anything to the first CSV,  the first script won't run

for example: if i add, oldname,newname,vlan behind the vmx in the CSV,  the script will only add the vmx without anything behind it to the inventory

[01_DATASTORE] TESTVM03/TESTVM03.vmx,TESTVM03,sn123-TESTV03,vlan5
[02_DATASTORE] TESTVM02/TESTVM02.vmx
[03_DATASTORE] TESTVM01/TESTVM01.vmx

Smiley Sad

0 Kudos
LucD
Leadership
Leadership
Jump to solution

You can try something like this

###############################################################################################################################
# CSV file layout
#
# VMXPath,oldname,newname,vlan
# "[ds] VM1/VM1.vmx",VM1,newVM1,net1
# "[ds] VM2/VM2.vmx",VM2,newVM2,net2
# "[ds] VM3/VM3.vmx",VM3,newVM3,net3
# "[ds] VM4/VM4.vmx",VM4,newVM4,net4
#
###############################################################################################################################
$vms = Import-Csv D:\temp\import-vm.csv -UseCulture

$targetVMX
= $vms | Select -ExpandProperty VMXPath
$Cluster
= "CLUSTER_01"
$Datastores
= "*_DATASTORE"
$VMFolder
= "TESTFOLDER"
$ResourcePool
= "TestRP"
$ESXHost
= Get-Cluster $Cluster | Get-VMHost | Get-Random
foreach
($Datastore in Get-Datastore $Datastores) {   # Search for .VMX Files in Datastore   $ds = Get-Datastore -Name $Datastore | %{Get-View $_.Id}   $SearchSpec = New-Object VMware.Vim.HostDatastoreBrowserSearchSpec
  $SearchSpec.matchpattern = "*.vmx"
  $dsBrowser = Get-View $ds.browser
  $DatastorePath = "[" + $ds.Summary.Name + "]"   # Find all .VMX file paths in Datastore, filtering out ones with .snapshot (Useful for NetApp NFS)   $SearchResult = $dsBrowser.SearchDatastoreSubFolders($DatastorePath, $SearchSpec) | where {$_.FolderPath -notmatch ".snapshot"} | %{$_.FolderPath + ($_.File | select Path).Path}   # Register all .vmx Files as VMs on the datastore   foreach($VMXFile in $SearchResult) {     if($targetVMX -contains $VMXFile){       New-VM -VMFilePath $VMXFile -VMHost $ESXHost -Location $VMFolder -ResourcePool $ResourcePool -RunAsync
    }   } }
foreach($vm in $vms){   Get-VM $($vm.oldname) |   Set-vm -name $($vm.newname) -confirm:$false |    Get-NetworkAdapter |   Set-NetworkAdapter -Networkname $($vm.vlan) -confirm:$false
}



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

0 Kudos
jackc201110141
Contributor
Contributor
Jump to solution

Hello Luc, thanks for your reply.

When I try your solution, I get the following error:  Select-Object : property "VMXPath" cannot be found....

Apparently there's an issue with $targetVMX = $vms | Select -ExpandProperty VMXPath

any ideas?

0 Kudos
LucD
Leadership
Leadership
Jump to solution

Did you follow the layout of the CSV file as I placed in the comments on top ?


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

0 Kudos
jackc201110141
Contributor
Contributor
Jump to solution

yes the layout is the same.

when I run     $csv = Import-csv D:\temp\import-vm3.csv -UseCulture

i get this error:

Import-Csv : Cannot process argument because the value of argument "name" is invalid. Change the value of the "name" ar
gument and run the operation again.
At line:1 char:18
+ $csv = Import-csv <<<<  D:\temp\import-vm3.csv -UseCulture
    + CategoryInfo          : InvalidArgument: (:) [Import-Csv], PSArgumentException
    + FullyQualifiedErrorId : Argument,Microsoft.PowerShell.Commands.ImportCsvCommand

It must have something to do with delimiters or blanks??

0 Kudos
LucD
Leadership
Leadership
Jump to solution

Does that CSV file exist ?

Does

Import-csv D:\temp\import-vm3.csv

return all the rows in the CSV file ?

Can you show the content of the CSV file ?


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

0 Kudos
jackc201110141
Contributor
Contributor
Jump to solution

yes the CSV exists (i created a new one for testing)

import-csv D:\temp\import-vm3.csv returns all row of the CSV:

VMXPath                       oldname                       newname                       vlan
-------                       -------                       -------                       ----
[02_DATASTORE] Empty2/Empt... Empty2                        100-Empty2                    vlan1
[03_DATASTORE] Empty3/Empt... Empty3                        101-Empty3                    vlan1
[03_DATASTORE] Empty4/Empt... Empty4                        102-Empty4                    vlan2
[02_DATASTORE] Empty5/Empt... Empty5                        103-Empty5                    vlan1


Content of CSV:
VMXPath,oldname,newname,vlan
"[02_DATASTORE] Empty2/Empty2.vmx",Empty2,100-Empty2,vlan1
"[03_DATASTORE] Empty3/Empty3.vmx",Empty3,101-Empty3,vlan1
"[03_DATASTORE] Empty4/Empty4.vmx",Empty4,102-Empty4,vlan2
"[02_DATASTORE] Empty5/Empty5.vmx",Empty5,103-Empty5,vlan1


Import-Csv : Cannot process argument because the value of argument "name" is invalid. Change the value of the "name" ar
gument and run the operation again.

was caused by a blank line in the CSV.


When i run the script now i still get this error:

Select-Object : Property "VMXPath" cannot be found.
At line:1 char:27
+ $targetVMX = $csv | select <<<<  -ExpandProperty VMXPath
    + CategoryInfo          : InvalidArgument: (@{VMXPath,oldna...x-Empty2,Delta}:PSObject) [Select-Object], PSArgumen
   tException
    + FullyQualifiedErrorId : ExpandPropertyNotFound,Microsoft.PowerShell.Commands.SelectObjectCommand

0 Kudos
LucD
Leadership
Leadership
Jump to solution

In my script that line said

$targetVMX = $vms | select -ExpandProperty VMXPath

Did you change the first line (the one with the Import-Csv) as well ?


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

0 Kudos
jackc201110141
Contributor
Contributor
Jump to solution

does it matter if i use $vms or $csv?  as long as I use everywhere in the script...

0 Kudos