Last active
December 10, 2020 17:27
-
-
Save coza73/890a665ec60e49c365aaec9b16f380fe to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Get-Module –ListAvailable VM* | Import-Module -ErrorAction SilentlyContinue | |
Set-PowerCLIConfiguration -DefaultVIServerMode Multiple -Confirm:$false | |
# Make sure no vcenters are connected that dont need to be. | |
if ($global:DefaultVIServer.IsConnected -eq $true){ | |
write-host "We have vcenters still connected, disconnecting....." -ForegroundColor Red | |
Disconnect-VIServer * -Confirm:$false | |
} | |
function log ([string]$logdata){ | |
$logfile = "c:\temp\MigrateTemplate.log" | |
$date = get-date | |
Write-Output "$date - $logdata" | Out-File $logfile -width 240 -Append | |
} | |
Log "Starting" | |
# check first if ovf tool is installed if not exit | |
$ovftoolpaths = ("C:\Program Files (x86)\VMware\VMware OVF Tool\ovftool.exe", "C:\Program Files\VMware\VMware OVF Tool\ovftool.exe") | |
$ovftool = "" | |
foreach ($ovftoolpath in $ovftoolpaths) | |
{ | |
if(test-path $ovftoolpath) | |
{ | |
$ovftool = $ovftoolpath | |
} | |
} | |
if (!$ovftool) | |
{ | |
write-host -ForegroundColor red "ERROR: OVFtool not found in it"s standard path." | |
Log "ERROR: OVFtool not found in it"s standard path." | |
write-host -ForegroundColor red "Edit the path variable or download ovftool here: http://www.vmware.com/support/..." | |
exit | |
} | |
# Make sure you can connect to multiple vCenters in this session | |
if ((Get-PowerCLIConfiguration -Scope session).defaultviserverMode -ne "Multiple"){ | |
Set-PowerCLIConfiguration -DefaultVIServerMode Multiple -Scope session -WebOperationTimeoutSeconds -1 -Confirm:$false | |
} | |
#Set credentials. Now nessessary for connecting to Vsphere Appliance virtualcenter | |
$credentialFile = "C:\temp\esxranger_cred.txt" | |
If (Test-Path $credentialFile){ | |
Write-Host "Credential file $credentialFile exists will not ask for password" | |
} | |
Else { | |
log "No credential file found" | |
read-host -Prompt "ESXRanger nexus password" -assecurestring | convertfrom-securestring | out-file $credentialFile | |
} | |
$password = get-content $credentialFile | convertto-securestring | |
$credential = new-object -typename System.Management.Automation.PSCredential -argumentlist "esxranger",$password | |
function Copy-Templates { | |
param | |
( | |
[parameter(Mandatory = $true)][String] $SourceViServer, | |
[parameter(Mandatory = $true)][String] $DestinationViServer, | |
[parameter(Mandatory = $true)][String] $DestinationDataStore, | |
[parameter(Mandatory = $true)][String] $SourceDataCenter, | |
[parameter(Mandatory = $true)][String] $DestinationDataCenter, | |
[parameter(Mandatory = $true)][String] $DestinationCluster, | |
[parameter(Mandatory = $true)][String] $DestinationNetworkName, | |
[parameter(Mandatory = $true)][String] $SourceFolderName, | |
[parameter(Mandatory = $true)][String] $DestinationFolderName, | |
[parameter(Mandatory = $false)][String] $appendName, # Append this to destination template name, will also create subfolder under DestinationFolderName | |
[parameter(Mandatory = $false)][Switch] $force, # Force copy of templates | |
[parameter(Mandatory = $false)][Switch] $cleanold, #delete templates in old folder that are older than 1 month | |
[parameter(Mandatory = $false)][Switch] $setTemplateChangeDateFile # do no copying just set a change date file | |
) | |
write-host "" | |
write-host "Migrate to.. " | |
log "Migrate to.. " | |
write-host "" | |
write-host "vCenter: $DestinationViServer" | |
log "vCenter: $DestinationViServer" | |
write-host "Datacenter: $DestinationDataCenter" | |
log "Datacenter: $DestinationDataCenter" | |
write-host "Cluster: $DestinationCluster" | |
log "Cluster: $DestinationCluster" | |
write-host "Folder: $DestinationFolderName" | |
log "Folder: $DestinationFolderName" | |
if ($appendName){ | |
write-host "Append Name: $appendName" | |
log "Append Name: $appendName" | |
} | |
if ($force) { | |
write-host "Forced Migrate" -ForegroundColor Red | |
log "Forced Migrate" | |
} | |
if ($cleanold){ | |
write-host "Clean out old templates" -ForegroundColor Red | |
log "Clean out old templates" | |
} | |
if ($setTemplateChangeDateFile) { | |
write-host "Only create/overwrite changedate file" -foregroundcolor Magenta | |
} | |
write-host "" | |
write-host "Connecting to Source vCenter" -ForegroundColor Green | |
connect-viserver $SourceViServer -Credential $credential | |
write-host "Connecting to Destination vCenter" -ForegroundColor Green | |
connect-viserver $DestinationViServer -Credential $credential | |
$vmhost = Get-Cluster $DestinationCluster | Get-VMHost | |
$DestinationHost = $vmhost[0] | |
write-host "Creating list of Templates -->" -foregroundcolor blue | |
$templatesObject = get-Datacenter -Server $SourceViServer -Name $SourceDataCenter | get-folder -Server $SourceViServer -Name $SourceFolderName| get-template -NoRecursion | |
write-host "Reading from List of Templates -->" -foregroundcolor blue | |
#grab all the names of the templates in the source folder | |
foreach ($template in $templatesObject.name) { | |
#Just making sure we are connected to source VC also need to refresh the session to make sure the session ticket is valid. | |
if ($DefaultVIServer.name -ne $SourceViServer) { | |
connect-viserver $SourceViServer -Credential $credential | |
} | |
Write-Host "Checking if we need to copy $template" | |
#Create a Auth ticket for ovftool to connect to host with. | |
$destinationSession = Get-View -Server $DestinationViServer -Id SessionManager | |
$destinationTicket = $destinationSession.AcquireCloneTicket() | |
$sourceSession = Get-View -Id SessionManager -Server $SourceViServer | |
$SourceTicket = $SourceSession.AcquireCloneTicket() | |
$templateTempName = $template + "-new" | |
# Set name of destination template and folder name based whether appendName has been set | |
if ($appendName) { | |
$destinationTemplateName = $template + $appendName | |
$destinationAppendFolderName = $appendName.trim("-") | |
} | |
else { | |
$destinationTemplateName = $template | |
} | |
# Create destination folder for appendname if does not exist | |
if ($appendName) { | |
if (!(Get-Datacenter -Server $DestinationViServer $destinationDataCenter |get-folder $DestinationFolderName | get-folder $destinationAppendFolderName -NoRecursion -ErrorAction:SilentlyContinue)) { | |
new-folder -location (Get-Datacenter -Server $DestinationViServer $destinationDataCenter |get-folder $DestinationFolderName) -name $destinationAppendFolderName | |
} | |
$destinationFolderObject = Get-Datacenter -Server $DestinationViServer $destinationDataCenter |get-folder $DestinationFolderName | get-folder $destinationAppendFolderName -NoRecursion | |
} | |
else { | |
if (!(Get-Datacenter -Server $DestinationViServer $destinationDataCenter |get-folder $DestinationFolderName -ErrorAction:SilentlyContinue)) { | |
new-folder -location (Get-Datacenter $destinationDataCenter | get-folder -type VM -norecursion) -name $destinationFolderName | |
} | |
$destinationFolderObject = Get-Datacenter -Server $DestinationViServer $destinationDataCenter |get-folder $DestinationFolderName | |
} | |
#Get the last changed date from source template object | |
$templateObject = get-template -Server $SourceViServer -location (Get-Datacenter -Server $SourceViServer -Name $SourceDataCenter | get-folder -Server $SourceViServer -Name $SourceFolderName) $template | |
$templateObjectChangeDate = (Get-View $templateObject).Config.ChangeVersion | |
$templateChangeDateFile = "e:\templates\" + $DestinationViServer + " - " + $DestinationDataCenter + " - " + $destinationFolderObject.Name + " - " + $destinationTemplateName + ".txt" | |
#Get the date changed file for the template, if it does not exist create one | |
if (Test-Path $templateChangeDateFile) { | |
$templateChangeDate = Get-Content $templateChangeDateFile | |
Write-Host "Source template last updated $templateChangeDate" #-ForegroundColor Blue | |
} | |
else { | |
Write-Host "No Change Date file for $template" -ForegroundColor Red | |
Set-Content $templateChangeDateFile $Null | |
} | |
# if -force set to $true then set template date change to $null to force copy | |
if ($force) { | |
$templateChangeDate = $Null | |
} | |
#if setTemplateChangeDateFile switch set only write a new change date file do no copying | |
if ($setTemplateChangeDateFile){ | |
write-host "Setting change date file for $template" | |
Set-Content $templateChangeDateFile $templateObjectChangeDate | |
} | |
# If template date changed matches the change date in the file and template exists in the destination | |
# dont copy else start the copy process | |
elseif (($templateChangeDate -eq $templateObjectChangeDate) -and (Get-Template -Server $DestinationViServer -Location (Get-Datacenter -Server $DestinationViServer -Name $destinationDataCenter) -Name $destinationTemplateName -ErrorAction:SilentlyContinue)) { | |
Write-Host "Not copying $template" -ForegroundColor Green | |
$destinationTemplate = Get-Template -Server $DestinationViServer -Location (Get-Datacenter -Server $DestinationViServer -Name $destinationDataCenter) -Name $destinationTemplateName | |
$destinationTemplateFolderObject = get-folder -Id $destinationTemplate.ExtensionData.parent | |
if ($destinationTemplateFolderObject.Id -ne $destinationFolderObject.Id) { | |
Write-host "$destinationTemplate not in correct folder, moving to $($destinationFolderObject.name) folder" -ForegroundColor Magenta | |
Move-Template -Server $DestinationViServer -Template $destinationTemplate -destination $destinationFolderObject | |
} | |
} | |
else { | |
log "Copying $template to vCenter $DestinationViServer $DestinationDataCenter on Cluster $DestinationCluster as $destinationTemplateName" | |
#Get the Template Moref value to feed into ovftool source | |
$vmd = $($templateObject.name) | |
$moref = $templateObject.extensiondata.moref.value | |
#run ovftool with information collected | |
$ovfArgList = @( | |
"--allowExtraConfig" | |
"--noSSLVerify" | |
"--diskMode=thin" | |
"--name=$($templateTempName)" | |
"-ds=$DestinationDataStore" | |
"--network=$DestinationNetworkName" | |
"--I:targetSessionTicket=$destinationTicket" | |
"--I:sourceSessionTicket=$($sourceTicket)" | |
"vi://$($DefaultVIServer.name)?moref=vim.VirtualMachine:$($moref)" | |
"vi://$($DestinationViServer)/$($DestinationDataCenter)?dns=$DestinationHost" | |
) | |
# | |
& $ovftool $ovfArgList | |
#Test that template actually successfully copied | |
if (!(get-vm -Server $DestinationViServer -Name $templateTempName)) { | |
log "$template failed to copy to $DestinationCluster" | |
Write-Host "$template failed to copy to $DestinationCluster" -ForegroundColor Red | |
} | |
#If copy good replace old with new | |
else { | |
#Move and rename the old matching template from Destination if exists | |
if (!(Get-Template -Server $DestinationViServer -location (get-datacenter $destinationDataCenter) -name $destinationTemplateName -ErrorAction:SilentlyContinue)) { | |
log "Old Destination template does not exist --> $destinationTemplateName" | |
Write-Host "Old Destination template does not exist --> ""$destinationTemplateName" -ForegroundColor Magenta | |
} | |
Else { | |
log "Moving old template --> $destinationTemplateName" | |
write-host "Moving old template --> " "$destinationTemplateName" -ForegroundColor Blue | |
#check for 'old' folder if not there created one | |
if (!(Get-Datacenter -Server $DestinationViServer $destinationDataCenter |get-folder $DestinationFolderName | get-folder -NoRecursion old -ErrorAction:SilentlyContinue)) { | |
new-folder -location (Get-Datacenter -Server $DestinationViServer $destinationDataCenter |get-folder $DestinationFolderName ) -name old | |
} | |
$oldTemplateObject = Get-Template -Server $DestinationViServer -Location $destinationDataCenter -Name $destinationTemplateName | |
$oldFolderObject = Get-Datacenter -Server $DestinationViServer $destinationDataCenter |get-folder $DestinationFolderName | get-folder -NoRecursion old | |
move-template -template $oldTemplateObject -Destination $oldFolderObject | |
# Rename template to -old-*date* | |
set-template -template (Get-Template -Server $DestinationViServer -location (get-datacenter $destinationDataCenter) -name $destinationTemplateName) -Name ($destinationTemplateName + "-old-" + (get-date -format "yyyMMdd")) -confirm:$false | |
} | |
#Convert imported VM to template and move to configured folder and rename from temp name | |
log "Converting VM to Template --> $template" | |
write-host "Converting VM to Template --> " $template -foregroundcolor blue | |
set-vm -vm (get-vm -server $DestinationViServer -Location $destinationDataCenter $templateTempName) -ToTemplate -name $destinationTemplateName -confirm:$false | |
$destinationTemplateFolder = Get-Folder -server $DestinationViServer -id (Get-Template -Server $DestinationViServer $destinationTemplateName).FolderID | |
if ($destinationTemplateFolder -ne $destinationFolderObject) { | |
log "Moving template to $DestinationFolderName" | |
Write-Host "Moving template to $DestinationFolderName" -ForegroundColor Blue | |
Move-Template -Server $DestinationViServer -Template $destinationTemplateName -destination $destinationFolderObject | |
} | |
#Update the templates date changed file | |
Set-Content $templateChangeDateFile $templateObjectChangeDate | |
} | |
} | |
} | |
# exit here if setTemplateChangeDateFile set | |
if ($setTemplateChangeDateFile){ | |
Break | |
} | |
# Cleanup old and redundant templates | |
write-host "Checking for redundant templates" | |
$DestinationTemplatesObject = get-folder -id $destinationFolderObject.id | get-template -NoRecursion | |
foreach ($destinationTemplateObject in $destinationtemplatesobject) { | |
$templateCompareObject = $destinationtemplateobject.name.Substring(0, ($destinationtemplateobject.name.Length - $appendName.Length)) | |
write-host $templateCompareObject | |
if ($templatesobject.name -contains $templateCompareObject) { | |
write-host "template present in source" -ForegroundColor Green | |
} | |
else { | |
log "Moving $destinationTemplateObject to old folder" | |
write-host "Moving $destinationTemplateObject to old folder" | |
#make sure 'old' folder exists | |
if (!(Get-Datacenter -Server $DestinationViServer $destinationDataCenter |get-folder $DestinationFolderName | get-folder -NoRecursion old)) { | |
New-Folder -Location (Get-Datacenter -Server $DestinationViServer $destinationDataCenter |get-folder $DestinationFolderName) -Name old | |
} | |
$oldFolderObject = Get-Datacenter -Server $DestinationViServer $destinationDataCenter |get-folder $DestinationFolderName | get-folder -NoRecursion old | |
move-template -template $destinationTemplateObject -Destination $oldFolderObject | |
set-template -template $destinationTemplateObject -Name ($destinationTemplateObject.Name + "-old-" + (get-date -format "yyyMMdd")) -confirm:$false | |
} | |
} | |
# Delete old templates older than one month | |
if ($cleanold) { | |
Write-Host "Removing old templates that are over 1 month old" | |
if ($DestinationFolderName -eq "legacy") { | |
write-host "Not needed in legacy folder" | |
} | |
else { | |
$oldDestinationTemplates = get-Datacenter -Server $DestinationViServer -Name $DestinationDataCenter | get-folder -Name $DestinationFolderName | get-folder old| get-template -NoRecursion | |
} | |
foreach ($oldDestinationTemplate in $oldDestinationTemplates) { | |
$oldTemplateObjectChangeDate = [datetime](Get-View $oldDestinationTemplate).Config.ChangeVersion | |
$indexDate = (get-date).AddDays(-30) | |
if ($oldTemplateObjectChangeDate -lt $indexDate) { | |
log "$oldDestinationTemplate created $oldTemplateObjectChangeDate will delete" | |
write-host "$oldDestinationTemplate created $oldTemplateObjectChangeDate will delete" | |
Remove-Template -DeletePermanently -Server $DestinationViServer -Template $oldDestinationTemplate -Confirm:$false | |
} | |
else { | |
write-host "$oldDestinationTemplate created $oldTemplateObjectChangeDate not old enough" | |
} | |
} | |
} | |
disconnect-viserver * -force -confirm:$false -ErrorAction SilentlyContinue | |
} | |
# #Prod Templates to VC01 CDC | |
Copy-Templates -SourceViServer vc01-test -DestinationViServer vc01 -DestinationDataStore CDC-Templates -SourceDataCenter CSIRO-TEST -DestinationDataCenter CSIRO -DestinationCluster "CDC Cluster09 (VI Management)" -DestinationNetworkName "CSIRO - VI Internal" -SourceFolderName prod -DestinationFolderName templates -cleanold #-setTemplateChangeDateFile | |
# #Legacy Templates to VC01 CDC | |
Copy-Templates -SourceViServer vc01-test -DestinationViServer vc01 -DestinationDataStore CDC-Templates -SourceDataCenter CSIRO-TEST -DestinationDataCenter CSIRO -DestinationCluster "CDC Cluster09 (VI Management)" -DestinationNetworkName "CSIRO - VI Internal" -SourceFolderName legacy -DestinationFolderName templates-legacy #-setTemplateChangeDateFile | |
# #Prod Templates to VC02 CMDC | |
Copy-Templates -SourceViServer vc01-test -DestinationViServer vc02 -DestinationDataStore CMDC-Templates -SourceDataCenter CSIRO-TEST -DestinationDataCenter CSIRO -DestinationCluster "CMDC Cluster7 (VI Management)" -DestinationNetworkName "CSIRO - VI Internal" -SourceFolderName prod -DestinationFolderName templates #-setTemplateChangeDateFile | |
# #Legacy Templates to VC02 CMDC | |
Copy-Templates -SourceViServer vc01-test -DestinationViServer vc02 -DestinationDataStore CMDC-Templates -SourceDataCenter CSIRO-TEST -DestinationDataCenter CSIRO -DestinationCluster "CMDC Cluster7 (VI Management)" -DestinationNetworkName "CSIRO - VI Internal" -SourceFolderName legacy -DestinationFolderName templates-legacy #-setTemplateChangeDateFile | |
# #Prod tempates to VC01 Self-service Brisbane | |
Copy-Templates -SourceViServer vc01-test -DestinationViServer vc01 -DestinationDataStore QLD-CL20-0808-SAS-2TB -SourceDataCenter CSIRO-TEST -DestinationDataCenter "Self-Service" -DestinationCluster "QLD Cluster 20 (General Self Service)" -DestinationNetworkName "Self-Service VI Internal" -SourceFolderName prod -DestinationFolderName templates -appendName "-bne" #-setTemplateChangeDateFile | |
# #desktop-prod tempates to VC01 Self-service Brisbane | |
Copy-Templates -SourceViServer vc01-test -DestinationViServer vc01 -DestinationDataStore QLD-CL20-0808-SAS-2TB -SourceDataCenter CSIRO-TEST -DestinationDataCenter "Self-Service" -DestinationCluster "QLD Cluster 20 (General Self Service)" -DestinationNetworkName "Self-Service VI Internal" -SourceFolderName desktop-prod -DestinationFolderName templates-desktop -appendName "-bne" #-setTemplateChangeDateFile | |
# #desktop-prod tempates to VC01 Self-service | |
#Copy-Templates -SourceViServer vc01-test -DestinationViServer vc01 -DestinationDataStore cl11-12dc-ssd-8TB -SourceDataCenter CSIRO-TEST -DestinationDataCenter "Self-Service" -DestinationCluster "CDC Cluster 11 (Enterprise Self Service)" -DestinationNetworkName "Self-Service VI Internal" -SourceFolderName desktop-prod -DestinationFolderName templates-desktop #-setTemplateChangeDateFile | |
Copy-Templates -SourceViServer vc01-test -DestinationViServer vc01 -DestinationDataStore CDC_NFS_Templates -SourceDataCenter CSIRO-TEST -DestinationDataCenter "Self-Service" -DestinationCluster "CDC Cluster 11 (General Self Service)" -DestinationNetworkName "Self-Service VI Internal" -SourceFolderName desktop-prod -DestinationFolderName templates-desktop #-setTemplateChangeDateFile | |
# Prod tempates to VC01 Self-service | |
Copy-Templates -SourceViServer vc01-test -DestinationViServer vc01 -DestinationDataStore CDC_NFS_Templates -SourceDataCenter CSIRO-TEST -DestinationDataCenter "Self-Service" -DestinationCluster "CDC Cluster 11 (General Self Service)" -DestinationNetworkName "Self-Service VI Internal" -SourceFolderName prod -DestinationFolderName templates -appendName "-netapp"#-setTemplateChangeDateFile | |
# #Prod Templates to VC01 WA | |
Copy-Templates -SourceViServer vc01-test -DestinationViServer vc01 -DestinationDataStore WA-CL3-c00-SAS-4TB -SourceDataCenter CSIRO-TEST -DestinationDataCenter CSIRO -DestinationCluster "Perth Cluster03 (Production)" -DestinationNetworkName "CSIRO - VI Internal" -SourceFolderName prod -DestinationFolderName templates -appendName "-wa" #-setTemplateChangeDateFile | |
# #Prod Templates to VC01-NGI vSAN | |
#Copy-Templates -SourceViServer vc01-test -DestinationViServer vc01-ngi -DestinationDataStore CL43-vsanDatastore -SourceDataCenter CSIRO-TEST -DestinationDataCenter vSAN -DestinationCluster "CDC Cluster43 (vSAN)" -DestinationNetworkName "vSAN-VI-Internal" -SourceFolderName prod -DestinationFolderName templates | |
# #Prod templates to vc01-test DEV | |
#Copy-Templates -SourceViServer vc01-test -DestinationViServer vc01-test -DestinationDataStore test-templates -SourceDataCenter CSIRO-TEST -DestinationDataCenter DEV -DestinationCluster "CDC cluster07 (Dev)" -DestinationNetworkName "DEV VI Internal" -SourceFolderName legacy -DestinationFolderName legacy-templates | |
#Copy-Templates -SourceViServer vc01-test -DestinationViServer vc01-test -DestinationDataStore CDC-CL7-1ea3-SSD-8TB -SourceDataCenter CSIRO-TEST -DestinationDataCenter DEV -DestinationCluster "CDC cluster07 (Dev)" -DestinationNetworkName "DEV VI Internal" -SourceFolderName prod -DestinationFolderName templates | |
log "Finished" |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment