Here is the deal.
I have a 5.0 vCenter with several hundred VMs that are all neatly organized under folders in the VMs and Templates Inventory View.
I am going to build a fresh new 5.5 vCenter with a new db in parallel with my 5.0 installation.
I want to disconnect the hosts, and have them be managed by the new 5.5 vCenter.
This will kill my folder organization.
Is there a script that can export my current folder hierarchy and then import that config so the script moves the VMs to their proper folder on the 5.5 vCenter?
jessem wrote:
Hey adamjg,
I know that line calls the csv file, maybe I'm confusing the question. If I run that script on the new vcenter just like that, it errors out because it doesn't know where that csv file is located. So pretend I have my csv file ready to be imported. Call is testfile.csv. So now, in the script, where do I enter testfile.csv so it knows where to get it from?
The only thing I did to get it to work is to do:
$datacenter = testfile.csv
in the beginning of the import script.
Am I missing somethign?
That won't actually do anything.
#Import Folders
$datacenter = "name of datacenter"
$vmfolder = Import-Csv ".\$($Datacenter)-Folders-with-FolderPath.csv" | Sort-Object -Property Path
The first line is meant to create the variable for your datacenter name. Let's simplify it and say:
$datacenter = "MyDC"
The next line uses the import-csv cmdlet to import the csv file into the variable $vmfolder. The context is variable = import-csv <path to file>. In this instance it would be looking for a file named MyDC-Folders-with-FolderPath.csv. The .\ indicates current directory. If you want to change that and not use the variable, you can just use a line such as this:
$vmfolder = Import-Csv "c:\mydir\testfile.csv" | Sort-Object -Property Path
Hey,
of course there are scripts. And of course they were written by LucD 😉
You can find several here in the forums:
Re: Export / Import selective Folder structure
Tim
Thanks it gave me some good tips, but it doesn't give me exactly what I am looking for.
I'm going from 5.0 vCenter and moving to a 5.5 vCenter. Perhaps there is something newer.
Can anyone help me please?
I've scripted a bunch of stuff for my 5.0 to 5.5 migrations, so I probably don't have the exact thing you're looking for, but I should have something you can steal from. I will say that the poster above is correct, all this info was borrowed/stolen from LucD. For my environment the best way to migrate is to move a host at a time, so what I do is run the first script which pulls in all VM info on a particular host:
Function Get-VMFolderPath {
Param($VMname)
Get-VM $VMname | Get-View | %{
$row = "" | select Name, ResourcePool, Path
$row.Name = $_.Name
$row.ResourcePool = (Get-View $_.ResourcePool[0]).Name
$current = Get-View $_.Parent
#$path = $_.Name
$path = $null
do {
$parent = $current
if($parent.Name -ne "vm"){$path = $parent.Name + "/" + $path}
$current = Get-View $current.Parent
}
while ($current.Parent -ne $null)
$row.Path = $path
$report += $row
}
$Path
}
Write-Host
$SourceHost = Read-Host "Enter the fqdn name of the 5.0 source VM Host"
Write-Host
Write-Host "Gathering a list of VMs from $SourceHost..." -ForegroundColor "Green"
Write-Host
$VMList = @()
$VMs = Get-VMHost $SourceHost | Get-VM
ForEach ($VM in $VMs) {
$obj = "" | Select Name, Folder
$obj.Name = $VM.Name
$OutputPath = Get-VMFolderPath $VM.Name
$obj.Folder = $OutputPath.Substring(0,$OutputPath.Length-1)
$VMList += $obj
}
$VMList | Sort Name | Export-Csv .\$SourceHost-VMList.csv -NoTypeInformation -UseCulture
In my script I'm also pulling resource pool and VLAN (port group) of network adapter 1 on the VM, but I took it out to simplify things. Then I add the 5.0 host to the 5.5 vCenter live. In my scripts I'm doing some things to manipulate the VMs between hosts and standard/distributed switches, but if you're only worried about the folders, this should work once the host is in 5.5:
#Adds in VDS PowerCLI snap in
Add-PSSnapin VMware.VimAutomation.Vds
function Get-FolderByPath {
<#
.SYNOPSIS Retrieve folders by giving a path
.DESCRIPTION The function will retrieve a folder by it's
path. The path can contain any type of leave (folder or
datacenter).
.NOTES Author: Luc Dekens
.PARAMETER Path
The path to the folder.
This is a required parameter.
.PARAMETER Separator
The character that is used to separate the leaves in the
path. The default is '/'
.EXAMPLE
PS> Get-FolderByPath -Path "Folder1/Datacenter/Folder2"
.EXAMPLE
PS> Get-FolderByPath -Path "Folder1>Folder2" -Separator '>'
#>
param(
[CmdletBinding()]
[parameter(Mandatory = $true)]
[System.String[]]${Path},
[char]${Separator} = '/'
)
process{
if((Get-PowerCLIConfiguration).DefaultVIServerMode -eq "Multiple"){
$vcs = $defaultVIServers
}
else{
$vcs = $defaultVIServers[0]
}
foreach($vc in $vcs){
foreach($strPath in $Path){
$root = Get-Folder -Name Datacenters -Server $vc
$strPath.Split($Separator) | %{
$root = Get-Inventory -Name $_ -Location $root -Server $vc -NoRecursion
if((Get-Inventory -Location $root -NoRecursion | Select -ExpandProperty Name) -contains "vm"){
$root = Get-Inventory -Name "vm" -Location $root -Server $vc -NoRecursion
}
}
$root | where {$_ -is [VMware.VimAutomation.ViCore.Impl.V1.Inventory.FolderImpl]}|%{
Get-Folder -Name $_.Name -Location $root.Parent -Server $vc
}
}
}
}
}
$SourceHost = Read-Host "Enter the fqdn name of the 5.0 source VM Host"
$VMs = import-csv ".\$SourceHost-VMList.csv"
ForEach ($VM in $VMs) {
Get-VM $VM.Name | Move-VM -Destination (Get-FolderByPath -Path $VM.Folder) | Out-Null
Write-Host "$($VM.Name) moved to Folder $($VM.Folder)." -ForegroundColor "Green"
Write-Host
}
If you want a script to export/import folder structures, try this for exporting from 5.0:
$datacenter = "Datacenter" #being lazy here and not prompting and auto connecting.
filter Get-FolderPath {
$_ | Get-View | % {
$row = "" | select Name, Path
$row.Name = $_.Name
$current = Get-View $_.Parent
$path = $_.Name
do {
$parent = $current
if($parent.Name -ne "vm"){$path = $parent.Name + "\" + $path}
$current = Get-View $current.Parent
} while ($current.Parent -ne $null)
$row.Path = $path
$row
}
}
#Export all folders
$report = @()
$report = get-datacenter $datacenter | Get-folder vm | get-folder | Get-Folderpath
#Replace the top level with vm
foreach ($line in $report) {
$line.Path = ($line.Path).Replace($datacenter + "\","vm\")
}
$report | Sort Path | Export-Csv ".\$($datacenter)-Folders-with-FolderPath.csv" -NoTypeInformation
And this to import into 5.5:
#Import Folders
$vmfolder = Import-Csv ".\$($Datacenter)-Folders-with-FolderPath.csv" | Sort-Object -Property Path
foreach($folder in $VMfolder){
$key = @()
$key = ($folder.Path -split "\\")[-2]
if ($key -eq "vm") {
get-datacenter $datacenter | get-folder vm | New-Folder -Name $folder.Name
}
else {
get-datacenter $datacenter | get-folder vm | get-folder $key | New-Folder -Name $folder.Name
}
}
Hope this helps!
Hey, having problems with importing into my target 5.5 vcenter.
I have the file I want to import called "Lab 03-Folders-with-FolderPath.csv"
But according to the import script, WHERE exactly am I placing this into?
#Import Folders
$vmfolder = Import-Csv ".\$($Datacenter)-Folders-with-FolderPath.csv" | Sort-Object -Property Path
foreach($folder in $VMfolder){
$key = @()
$key = ($folder.Path -split "\\")[-2]
if ($key -eq "vm") {
get-datacenter $datacenter | get-folder vm | New-Folder -Name $folder.Name
}
else {
get-datacenter $datacenter | get-folder vm | get-folder $key | New-Folder -Name $folder.Name
}
}
jessem wrote:
Hey, having problems with importing into my target 5.5 vcenter.
I have the file I want to import called "Lab 03-Folders-with-FolderPath.csv"
But according to the import script, WHERE exactly am I placing this into?
#Import Folders
$vmfolder = Import-Csv ".\$($Datacenter)-Folders-with-FolderPath.csv" | Sort-Object -Property Path
foreach($folder in $VMfolder){
$key = @()
$key = ($folder.Path -split "\\")[-2]
if ($key -eq "vm") {
get-datacenter $datacenter | get-folder vm | New-Folder -Name $folder.Name
}
else {
get-datacenter $datacenter | get-folder vm | get-folder $key | New-Folder -Name $folder.Name
}
}
Are you talking about where to put the CSV file? The .\ indicates the current directory. So basically whatever directory you run the script from. Let me know if you're looking for something else.
No I was referring to where the script is calling the csv file?
Is it like this?
#Import Folders
$ datacenter = "name of datacenter"
$vmfolder = Import-Csv ".\$($Datacenter)-Folders-with-FolderPath.csv" | Sort-Object -Property Path
foreach($folder in $VMfolder){
$key = @()
$key = ($folder.Path -split "\\")[-2]
if ($key -eq "vm") {
get-datacenter $datacenter | get-folder vm | New-Folder -Name $folder.Name
}
else {
get-datacenter $datacenter | get-folder vm | get-folder $key | New-Folder -Name $folder.Name
}
}
This is the line that imports the CSV file:
$vmfolder = Import-Csv ".\$($Datacenter)-Folders-with-FolderPath.csv" | Sort-Object -Property Path
Hey adamjg,
I know that line calls the csv file, maybe I'm confusing the question. If I run that script on the new vcenter just like that, it errors out because it doesn't know where that csv file is located. So pretend I have my csv file ready to be imported. Call is testfile.csv. So now, in the script, where do I enter testfile.csv so it knows where to get it from?
The only thing I did to get it to work is to do:
$datacenter = testfile.csv
in the beginning of the import script.
Am I missing somethign?
jessem wrote:
Hey adamjg,
I know that line calls the csv file, maybe I'm confusing the question. If I run that script on the new vcenter just like that, it errors out because it doesn't know where that csv file is located. So pretend I have my csv file ready to be imported. Call is testfile.csv. So now, in the script, where do I enter testfile.csv so it knows where to get it from?
The only thing I did to get it to work is to do:
$datacenter = testfile.csv
in the beginning of the import script.
Am I missing somethign?
That won't actually do anything.
#Import Folders
$datacenter = "name of datacenter"
$vmfolder = Import-Csv ".\$($Datacenter)-Folders-with-FolderPath.csv" | Sort-Object -Property Path
The first line is meant to create the variable for your datacenter name. Let's simplify it and say:
$datacenter = "MyDC"
The next line uses the import-csv cmdlet to import the csv file into the variable $vmfolder. The context is variable = import-csv <path to file>. In this instance it would be looking for a file named MyDC-Folders-with-FolderPath.csv. The .\ indicates current directory. If you want to change that and not use the variable, you can just use a line such as this:
$vmfolder = Import-Csv "c:\mydir\testfile.csv" | Sort-Object -Property Path
Perfect - that's exactly what I was looking for - thanks.
I've seen several noble attempts out there to export and re-create folders but these rock!! They worked perfectly!! Thank you!!