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.
[ps]<#
.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
[/ps]