VMware Cloud Community
ugauchr
Contributor
Contributor
Jump to solution

Copy files (vmx) , how to script it ??

Hi,

Quite new in VI Toolkit / Powershell but for a SRM project I need to automate so stuff.

Is there a way that a can take a copy from a vmx file and rename it. (Will be stored in the same folder / datastore but with different name)

Assume can't be so difficult but it didn't get it work yet?

Any idea, some scriptlets

Thanks

Christof

0 Kudos
1 Solution

Accepted Solutions
LucD
Leadership
Leadership
Jump to solution

Ok, I understand.

To change the permissions you need to use the plink tool.

This should do what you want

$vmName = <VM-name>
$vm = Get-VM $vmName | Get-View
$logdir = $vm.Config.Files.LogDirectory
$logdir -match "\[(\w+)\]"
$dummy = $dsName = $matches[1]

$User = <ESX-account>
$Pswd = <ESX-password>
$Computer = (Get-View -Id $vm.Runtime.Host).Name
$plink = "<path to Putty directory>\plink.exe"
$plinkoptions = " -v -batch -pw $Pswd"
$cmd1 = 'chmod 754 /vmfs/volumes/' + $dsName + '/' + $vmName + '/' + $vmName + '-COPY.vmx'

$remoteCommand = '"' + $cmd1 + '"'
$command = $plink + " " + $plinkoptions + " " + $User + "@" + $computer + " " + $remoteCommand

$msg = Invoke-Expression -command $command 

Note that you will have to set up sudo for this to work.

See for details.


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

View solution in original post

0 Kudos
8 Replies
LucD
Leadership
Leadership
Jump to solution

Afaik there is currently no VITK cmdlet that lets you do this.

But we can use the SDK method CopyDatastoreFile_Task to accomplish this task.


$vmName = <VM-name>

$vmImpl = Get-VM $vmName
$vm = $vmImpl | Get-View

$fileMgr = Get-View FileManager
$source = $vm.Config.Files.VmPathName
$sourceDc = ($vmImpl | Get-Datacenter | Get-View).MoRef
$dest = $source.Replace(".vmx","-COPY.vmx")
$destDc = $sourceDc
$force = $false
$taskMoRef = $fileMgr.CopyDatastoreFile_Task($source,$sourceDc,$dest,$destDc, $force)
$task = Get-View -Id $taskMoRef 
while($task.Info.State -eq "running" -or $task.Info.State -eq "queued"){
  sleep 2
  $task.UpdateViewData("Info.State")
}

Note that I just added "-COPY" to the filename.

I.e. the file "ABC.vmx" becomes "ABC-COPY.vmx".

But you can of course change this Smiley Wink


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

ugauchr
Contributor
Contributor
Jump to solution

Hi Luc,

Is exactly what I was looking, give it test right away.

Thanks

Christof

0 Kudos
ugauchr
Contributor
Contributor
Jump to solution

Works Fine but i forget about the file security rights.

After a copy I loose the execute rights on this file. Can this be maintained or should I set the rights again? Is this possble ?

I'm affraid it can only be done through a SDK method. Couldn't find it maybe, a hint? Heart

Thanks

Christof

0 Kudos
LucD
Leadership
Leadership
Jump to solution

I'm not sure I understand exactly which rights you mean.

Wat are you trying to do with the copied VMX file ?


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

ugauchr
Contributor
Contributor
Jump to solution

Hi Luc,

What I want to achieve: set execute file rights on vmx file. On the ESX console I would do something like "chmod +x consistency reasons of vmdks, after a fail over (DR) my VM.vmdk is consistent and the VM-DELTA.vmdk isn't.

I'm trying to manipulate the vmx file so that is start only the VM.vmdk, without custom script it points to VM-DELTA.vmdk.

To achieve this I want copy the vmx apart, then VMs are snapshotted, array replication is trigger, copy of vmx is set back (over the wrong one), VM is started. That is the idea behind it.

Regards

Christof

0 Kudos
LucD
Leadership
Leadership
Jump to solution

Ok, I understand.

To change the permissions you need to use the plink tool.

This should do what you want

$vmName = <VM-name>
$vm = Get-VM $vmName | Get-View
$logdir = $vm.Config.Files.LogDirectory
$logdir -match "\[(\w+)\]"
$dummy = $dsName = $matches[1]

$User = <ESX-account>
$Pswd = <ESX-password>
$Computer = (Get-View -Id $vm.Runtime.Host).Name
$plink = "<path to Putty directory>\plink.exe"
$plinkoptions = " -v -batch -pw $Pswd"
$cmd1 = 'chmod 754 /vmfs/volumes/' + $dsName + '/' + $vmName + '/' + $vmName + '-COPY.vmx'

$remoteCommand = '"' + $cmd1 + '"'
$command = $plink + " " + $plinkoptions + " " + $User + "@" + $computer + " " + $remoteCommand

$msg = Invoke-Expression -command $command 

Note that you will have to set up sudo for this to work.

See for details.


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

0 Kudos
ugauchr
Contributor
Contributor
Jump to solution

Thanks, this is perfect !!!!

0 Kudos
alasdair_carnie
Enthusiast
Enthusiast
Jump to solution

Hi Luc,

Could this be adapted to check for the exsistance of a VM or Template and if it does not exist then copy the VM or Template from one datastore to another?

I am storing my templates in a datastore that cannot be seen by my students ESX hosts, but I need to deploy lots of VMs from this template to the student servers. At the moment I am manually copying the VM Template from the protected Datastore to one the students can see and then running a powershell script to register the template, add the student ESX hosts to a vCenter and then deploy 16 VMs (two onto each host). I'd like to store a copy of the VM Template on the public store, but be able to check that it is there before trying to deploy the VMs, in case a student has deleted the template by mistake.

I tried just deploying the template from the protected datastore, but the performance is really bad. Any help would be appreciated.

0 Kudos