I was tasked with migrating a VMware 4.1 to 5.1 environment. This created a slight issue due to the fact that environment ran vShield. For those of you not familiar, vShield on 4.1 had 2 additional lines in the VMX file that was manually added. These VFILE lines caused the VM not to boot if it was moved to an environment where vShield 1.0 was not present. So to resolve this a script was needed to download all these VMs, remove the lines, then reupload the file with a different name. Well, here you go.

<# 
.SYNOPSIS 
    vCenter Related Script - PowerCLI - Download, Update, and Upload VMX, add to inventory
.DESCRIPTION 
    This script is for vCenter. The script downloads all VMX files for "PoweredOn"
	machines, modifies their VMX file, then reuploads the new file as a new name.
	Once uploaded, the VM is imported to the new 5.1 vCenter server
.NOTES 
    File Name  : VM-GatherVMX.ps1 
    Author     : Thomas Lasswell - lasswellt@techcolumnist.com
.LINK 
	http://www.techcolumnist.com
.EXAMPLE 
    VM-GatherVMX.ps1 {vcenter4.1 server} {vcenter5.1 server}
.PARAMETER vcServer4
	Defines the vCenter 4.1 Server you want to connect to
.PARAMETER vcServer5
	Defines the vCenter 5.1 Server you want to connect to	
#> 
Param(
  [string]$vcServer4,
  [string]$vcServer5
)
cls
if (!$vcServer4) {Write-Host "No vCenter 4 Server Specified"; exit}
if (!$vcServer5) {Write-Host "No vCenter 5 Server Specified"; exit}
##########Load PowerCLI##########
Add-PSSnapin VMware.VimAutomation.Core
$host.ui.rawui.WindowTitle="PowerShell [PowerCLI Module Loaded]"

$outvmxdir= "C:\scripts\vmxfiles" #Download VMX File Location
$outvmxnewdir = "C:\scripts\vmxfiles-new" #Modified VMX File Location
$vCluster= "NA Cluster" #Cluster name in vCenter 4.1 to gather PoweredOn VMs
$VMFolder = Get-Folder "Import" #This folder needs to exist in vCenter 5.1
$ESXHost= "servername" #ESX host in vCenter 5.1 to import VM
$ResPool = "Infrastructure" #Cluster name in vCenter 5.1 to import VM

#Connect to vCenter 4.1 Server
Connect-VIServer $vcServer4

$aVM = Get-VM -Location $vCluster | Where-Object {$_.PowerState -eq "PoweredOn"} | Select Name, PowerState
$aVMInfo = @()
foreach($vm in $aVM){
	$vname= $vm.name
	Write-Host $vname
	#Process DataStore
	$VMDSInfo= Get-Datastore -VM $vname | Select Name
	#Process VMX Information
	$VMView = Get-VM $vname | Get-View
	$VMPathName = $VMView.Config.Files.VmPathName
	Write-Host $VMPathName
	#Download VMX File
	$dsname= $VMPathName.split(" ")[0].TrimStart("[").TrimEnd("]")
	$vmfolder= $VMPathName.split(']')[1].TrimStart(' ')
	Remove-PSDrive -Name fromds -ErrorAction silentlycontinue
	new-psdrive -name fromds -location (get-datastore $dsname) -psprovider vimdatastore -root ‘/’ |out-null
	$dlvmx= $outvmxdir + ("/") + $vmfolder.split('/')[1]
	$checkforoutfile = Test-Path $dlvmx
	If ($checkforoutfile){Remove-Item $dlvmx}
	Copy-DatastoreItem -Item fromds:\$vmfolder -Destination $outvmxdir -Force

	#Update VMX file to -51 file without vShield Lines
	$vmxfile= $VMPathName.split("/")[1]
	$vmxsource= $outvmxdir + "\" + $vmxfile
	$vmxdest= $outvmxnewdir + "\" + $vmxfile.split(".")[0] + "-51.vmx"
	$checkforoutfile = Test-Path $vmxdest
	If ($checkforoutfile){Remove-Item $vmxdest}
	Get-Content $vmxsource | Where-Object {$_ -notmatch 'VFILE.globaloptions' -and $_ -notmatch 'scsi0:0.filters = "VFILE"'} | Set-Content $vmxdest
	Add-Content $vmxdest "`n#Modified to remove VFILE Lines"
	#Upload new VMX file to datastore
	Write-Host $vmxdest
	$vmxupload= $vmfolder.split(".vmx")[0] + "-51.vmx"
	Write-Host $vmxupload
	Copy-DatastoreItem -Item $vmxdest -Destination fromds:\$vmxupload -Force
	
	#set array for addition of VMs
	$obj = New-Object PSObject
	$obj | Add-Member -MemberType NoteProperty -Name "VMName" -Value $vname
	$obj | Add-Member -MemberType NoteProperty -Name "VMDatastore" -Value $dsname
	$obj | Add-Member -MemberType NoteProperty -Name "VMPathName" -Value $vmxupload
	$aVMInfo += $obj
}

Disconnect-VIServer $vcServer4 -force -confirm:$false
sleep 5

#Connect to vCenter 5.1 Server
Connect-VIServer $vcServer5
#Import VM to vCenter 5.1
foreach($vm in $aVMInfo){
	$vname= $vm.VMName
	$datastore= $vm.VMDatastore
	$VMPath= $vm.VMPathName
	Write-Host $vname
	Write-Host $datastore
	Write-Host $VMPath
	Write-Host $VMFullPath
	$VMFullPath= "[" + $datastore + "] " + $VMPath
	New-VM -VMFilePath $VMFullPath -VMHost $ESXHost -Location $VMFolder -ResourcePool $ResPool |out-null
}
Disconnect-VIServer $vcServer5 -force -confirm:$false