VMware Cloud Community
vin01
Expert
Expert
Jump to solution

modifiy the vmx file by copying it to local

I am trying to change hw version for some vms in a cluster with the below script. Its failing for some vms while split of vmx path in line 7 & 8.

$hwveroffvms=Get-Cluster "WTR_LABS_02" | Get-VM |?{$_.powerstate -eq 'PoweredOff' -and $_.version -eq 'v11'} |select name ,version,powerstate

foreach($vmName in $hwveroffvms.name){

$tgtFolder = $env:Temp

Get-VM -Name $vmName | %{

$dsName,$vmxPath = $_.ExtensionData.Config.Files.VmPathName.Split()

$vmxName = $vmxPath.Split('/')[-1]

$vmxFolder = [string]::Join('/',($vmxPath.Split('/')[-99..-2]))

$dsName = $dsName.Trim('[]')

$ds = Get-Datastore -Name $dsName

New-PSDrive -Location $ds -Name DS -PSProvider VimDatastore -Root "\" | Out-Null

Copy-DatastoreItem -Item "DS:$vmxPath" -Destination $tgtFolder

(Get-Content -Path "$tgtFolder\$vmxName")| ForEach-Object {$_ -Replace 'virtualHW.version = "11"', 'virtualHW.version = "10"'} | Set-Content -Path "$tgtFolder\$vmxName"

Copy-DatastoreItem  -Item "$tgtFolder\$vmxName" -Destination "DS:$vmxFolder" -Force

Get-ChildItem -Path "$tgtFolder\$vmxName" | Remove-Item -Confirm:$false

Remove-PSDrive -Name DS -Confirm:$false

}

}

For example if the VM name something  like vm01 the script is able to execute successfully but in the environment there are multiple vcloud vms with name some this like below snap. There script is not splitting the vmx path correctly.

pastedImage_1.png

Regards Vineeth.K
Reply
0 Kudos
1 Solution

Accepted Solutions
LucD
Leadership
Leadership
Jump to solution

Can you try like this

$tgtFolder = $env:Temp

Get-VM -Name 'SEP00VVM-278 (90389be9-cc74-49e5-aa8a-3079efea166d)',

   'POSSoulFoods (868a2a98-9509-4646-b396-6b8093101f81)',

   'AV_SCM_3 - wusas230233-003 (d7ef0854-c5f3-4ad9-aedf-2ddc70d6b36e)' |

   ForEach-Object -Process {

   $dsName = $_.ExtensionData.Config.Files.VmPathName.Split(']').TrimStart('[')[0]

   $vmxPath = $_.ExtensionData.Config.Files.VmPathName.Split(']')[1].TrimStart(' ')

   $vmxName = $vmxPath.Split('/')[-1]

   $vmxFolder = [string]::Join('/', ($vmxPath.Split('/')[-99..-2]))

   $ds = Get-Datastore -Name $dsName

   New-PSDrive -Location $ds -Name DS -PSProvider VimDatastore -Root "\" | Out-Null

   Copy-DatastoreItem -Item "DS:$vmxPath" -Destination $tgtFolder

   (Get-Content -Path "$tgtFolder\$vmxName")| ForEach-Object {$_ -Replace 'virtualHW.version = "11"', 'virtualHW.version = "10"'} | Set-Content -Path "$tgtFolder\$vmxName"

   Copy-DatastoreItem  -Item "$tgtFolder\$vmxName" -Destination "DS:$vmxFolder" -Force

   Get-ChildItem -Path "$tgtFolder\$vmxName" | Remove-Item -Confirm:$false

   Remove-PSDrive -Name DS -Confirm:$false

}


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

View solution in original post

Reply
0 Kudos
17 Replies
LucD
Leadership
Leadership
Jump to solution

1) Why are you doing it that way, and not for example like this?

$do = New-Object -TypeName VMware.Vim.VirtualMachineConfigSpec

$do.ScheduledHardwareUpgradeInfo = New-Object -TypeName VMware.Vim.ScheduledHardwareUpgradeInfo

$do.ScheduledHardwareUpgradeInfo.UpgradePolicy = [VMware.Vim.ScheduledHardwareUpgradeInfoHardwareUpgradePolicy]::onSoftPowerOff

$do.ScheduledHardwareUpgradeInfo.VersionKey = “vmx-13

$do.Tools = New-Object VMware.Vim.ToolsConfigInfo

$do.Tools.ToolsUpgradePolicy = "UpgradeAtPowerCycle"

foreach ($vmName in (Get-Cluster "WTR_LABS_02" | Get-VM |? {$_.powerstate -eq 'PoweredOff' -and $_.version -eq 'v11'} )) {

   $vm = Get-VM -Name $vmName

   $vm.ExtensionData.ReconfigVM_Task($do)

}

2) What part of the name do you need to extract, in other words what is the name of the .vmx file?
The part before the string between parenthesis?
For example for the 1st line SEP00VVM-278?


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

Reply
0 Kudos
vin01
Expert
Expert
Jump to solution

Hi LucD,

I am trying to downgrade the hardware version from 11 to 10 not upgrade.

For example the vm name is 'SEP00VVM-278 (90389be9-cc74-49e5-aa8a-3079efea166d)' and vmx file path is [SEP00_97WTR_AA04] SEP00VVM-278 (90389be9-cc74-49e5-aa8a-3079efea166d)/SEP00VVM-278 (90389be9-cc74-49e5-aa8a-3079efea166d).vmx

After this like $vmxName = $vmxPath.Split('/')[-1]

it is showing only this  (90389be9-cc74-49e5-aa8a-3079efea166d).vmx

It should show like this SEP00VVM-278 (90389be9-cc74-49e5-aa8a-3079efea166d).vmx

----

If there is a normal vm (not vcloud vm) without uuid like this SEP00VVM-34. I can able to see correct vmx file path like this

SEP00VVM-34.vmx

---

Problem is I am failing to split the path correctly.

Regards Vineeth.K
Reply
0 Kudos
LucD
Leadership
Leadership
Jump to solution

If the ESXi node supports it, you should be able to downgrade this way as well.
Did you try?


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

Reply
0 Kudos
LucD
Leadership
Leadership
Jump to solution

This seems to working for me

$t = '[SEP00_97WTR_AA04] SEP00VVM-278 (90389be9-cc74-49e5-aa8a-3079efea166d)/SEP00VVM-278 (90389be9-cc74-49e5-aa8a-3079efea166d).vmx'

$t.Split('/')[-1]

What does that return on your station?


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

Reply
0 Kudos
vin01
Expert
Expert
Jump to solution

Output

pastedImage_0.png

Regards Vineeth.K
Reply
0 Kudos
LucD
Leadership
Leadership
Jump to solution

Ok, I think I see what is happening.
Replace this line

$dsName, $vmxPath = $_.ExtensionData.Config.Files.VmPathName.Split()

with these 2 lines

$dsName = $_.ExtensionData.Config.Files.VmPathName.Split(']').TrimStart('[')[0]

$vmxPath = $_.ExtensionData.Config.Files.VmPathName.Split('/')[1]

Did you already try the downgrade with the solution I gave in 1)?


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

Reply
0 Kudos
vin01
Expert
Expert
Jump to solution

After replacing those lines this time $vmxpath is not showing correctly so $vmxFolder showing blank and copy is failing in the next lines of the script.

pastedImage_0.png

Did you already try the downgrade with the solution I gave in 1)?

Yes I tried that script but its not working. Its states 'the virtual machine compatibility is already up-to-date' even if i downgrade to vmx-10

Regards Vineeth.K
Reply
0 Kudos
LucD
Leadership
Leadership
Jump to solution

Try with this version

$hwveroffvms = Get-Cluster "WTR_LABS_02" | Get-VM |? {$_.powerstate -eq 'PoweredOff' -and $_.version -eq 'v11'} |select name , version, powerstate

foreach ($vmName in $hwveroffvms.name) {

   $tgtFolder = $env:Temp

   Get-VM -Name $vmName | % {

   $dsName = $_.ExtensionData.Config.Files.VmPathName.Split(']').TrimStart('[')[0]

   $vmxPath = $_.ExtensionData.Config.Files.VmPathName.Split(']')[1].TrimStart(' ')

   $vmxName = $vmxPath.Split('/')[-1]

   $vmxFolder = [string]::Join('/', ($vmxPath.Split('/')[-99..-2]))

   $ds = Get-Datastore -Name $dsName

   New-PSDrive -Location $ds -Name DS -PSProvider VimDatastore -Root "\" | Out-Null

   Copy-DatastoreItem -Item "DS:$vmxPath" -Destination $tgtFolder

   (Get-Content -Path "$tgtFolder\$vmxName")| ForEach-Object {

   $_ -Replace 'virtualHW.version = "11"', 'virtualHW.version = "10"'

   } | Set-Content -Path "$tgtFolder\$vmxName"

   Copy-DatastoreItem  -Item "$tgtFolder\$vmxName" -Destination "DS:$vmxFolder" -Force

   Get-ChildItem -Path "$tgtFolder\$vmxName" | Remove-Item -Confirm:$false

   Remove-PSDrive -Name DS -Confirm:$false

   }

}


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

Reply
0 Kudos
a_p_
Leadership
Leadership
Jump to solution

I think that the issue occurs due to the spaces in the VM's folder/name, where your original split will not provide the result that you may expect.

$dsName,$vmxPath = $_.ExtensionData.Config.Files.VmPathName.Split()

How about something like this:

$extData = $_.ExtensionData.Config.Files.VmPathName

$dsName = $extData.Split('[]')[1]

$vmxFolder,$vmxName = $extData.Substring($ExtData.IndexOf("]")+2).split("/")

This will not only take care of spaces in the names, but will also allow brackets in the file names (if necessary).

André

Reply
0 Kudos
LucD
Leadership
Leadership
Jump to solution

I'm afraid your solution doesn't handle nested folders (which my original did do).
Try for example with '[ds] folder/vm/vm.vmx'


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

Reply
0 Kudos
a_p_
Leadership
Leadership
Jump to solution

What should also work - with the least changes to your original script - is to modify line 5 from

$dsName,$vmxPath = $_.ExtensionData.Config.Files.VmPathName.Split()

to

$dsName,$vmxPath = $_.ExtensionData.Config.Files.VmPathName.Split('[] ', 4)[1,3]

André

Reply
0 Kudos
vin01
Expert
Expert
Jump to solution

Yes now its copying and changing vmx version as expected but it is only taking one vm in the loop.

For example if i give as below its just changing for this VM  'SEP00VVM-278 (90389be9-cc74-49e5-aa8a-3079efea166d)' 3 times. Is there anything wrongly mentioned in the loop.

what is $t its no where mentioned in the script.

foreach ($vmName in (Get-VM 'SEP00VVM-278 (90389be9-cc74-49e5-aa8a-3079efea166d)','POSSoulFoods (868a2a98-9509-4646-b396-6b8093101f81)','AV_SCM_3 - wusas230233-003 (d7ef0854-c5f3-4ad9-aedf-2ddc70d6b36e)')) {

$tgtFolder = $env:Temp

Get-VM -Name $vmName.name | % {

$dsName, $vmxPath = $_.ExtensionData.Config.Files.VmPathName.Split()

$dsName = $t.Split(']').TrimStart('[')[0]

$vmxPath = $t.Split(']')[1].TrimStart(' ')

$vmxName = $vmxPath.Split('/')[-1]

$vmxFolder = [string]::Join('/', ($vmxPath.Split('/')[-99..-2]))

$ds = Get-Datastore -Name $dsName

New-PSDrive -Location $ds -Name DS -PSProvider VimDatastore -Root "\" | Out-Null

Copy-DatastoreItem -Item "DS:$vmxPath" -Destination $tgtFolder

(Get-Content -Path "$tgtFolder\$vmxName")| ForEach-Object {$_ -Replace 'virtualHW.version = "11"', 'virtualHW.version = "10"'} | Set-Content -Path "$tgtFolder\$vmxName"

Copy-DatastoreItem  -Item "$tgtFolder\$vmxName" -Destination "DS:$vmxFolder" -Force

Get-ChildItem -Path "$tgtFolder\$vmxName" | Remove-Item -Confirm:$false

Remove-PSDrive -Name DS -Confirm:$false

   }

}

Regards Vineeth.K
Reply
0 Kudos
LucD
Leadership
Leadership
Jump to solution

Can you try like this

$tgtFolder = $env:Temp

Get-VM -Name 'SEP00VVM-278 (90389be9-cc74-49e5-aa8a-3079efea166d)',

   'POSSoulFoods (868a2a98-9509-4646-b396-6b8093101f81)',

   'AV_SCM_3 - wusas230233-003 (d7ef0854-c5f3-4ad9-aedf-2ddc70d6b36e)' |

   ForEach-Object -Process {

   $dsName = $_.ExtensionData.Config.Files.VmPathName.Split(']').TrimStart('[')[0]

   $vmxPath = $_.ExtensionData.Config.Files.VmPathName.Split(']')[1].TrimStart(' ')

   $vmxName = $vmxPath.Split('/')[-1]

   $vmxFolder = [string]::Join('/', ($vmxPath.Split('/')[-99..-2]))

   $ds = Get-Datastore -Name $dsName

   New-PSDrive -Location $ds -Name DS -PSProvider VimDatastore -Root "\" | Out-Null

   Copy-DatastoreItem -Item "DS:$vmxPath" -Destination $tgtFolder

   (Get-Content -Path "$tgtFolder\$vmxName")| ForEach-Object {$_ -Replace 'virtualHW.version = "11"', 'virtualHW.version = "10"'} | Set-Content -Path "$tgtFolder\$vmxName"

   Copy-DatastoreItem  -Item "$tgtFolder\$vmxName" -Destination "DS:$vmxFolder" -Force

   Get-ChildItem -Path "$tgtFolder\$vmxName" | Remove-Item -Confirm:$false

   Remove-PSDrive -Name DS -Confirm:$false

}


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

Reply
0 Kudos
vin01
Expert
Expert
Jump to solution

I got the issue.

I am sorry there is already a stored value in $t variable for VM 'SEP00VVM-278 (90389be9-cc74-49e5-aa8a-3079efea166d)' which I executed earlier. I believe that why its executed only for that vm.

This time I closed the ISE and reopen it and executed below script and this is error. what need to replaced in $t

pastedImage_0.png

pastedImage_2.pngpastedImage_1.png

Regards Vineeth.K
Reply
0 Kudos
LucD
Leadership
Leadership
Jump to solution

You didn't copy the latest version I included


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

Reply
0 Kudos
vin01
Expert
Expert
Jump to solution

Totally Confused. I thought i copied correctly. Thanks LucD now its working as expectedSmiley Happy

Regards Vineeth.K
Reply
0 Kudos
LucD
Leadership
Leadership
Jump to solution

That happens to the best of us.
Happy it is working now :smileygrin:


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

Reply
0 Kudos