Categories: PowerShellScripts

Powershell: Download VMX file, Rename, Upload, Add to Inventory

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
TomLasswell

Share
Published by
TomLasswell

Recent Posts

Autotask: PowerShell: Enable Client Portal for all users

This is a quick one, it's been forever since I've posted here. After moving back…

2 years ago

PowerShell :: Get Exchange Mailboxes Over XXGB

Simple command turned crazy. I ended up coming up with this due to the fact…

4 years ago

PowerShell: ConnectWise Documents API, Uploading a document or attachment to a ticket

Phew, this one took a minute to figure out. ConnectWise has a form based documents…

6 years ago

PowerShell: ConnectWise REST API Query Contacts by Email Address

I've found myself at a new job, recreating many of the processes that I spent…

6 years ago

First post in a long time — changing hosting providers

Wow, it's been a while since I've done a real post on this site. I've…

7 years ago

Powershell: AutoTask – Get Picklist Values

When using AutoTask's API it's required to lookup a various amount of picklist values that…

10 years ago