12 Replies Latest reply on May 26, 2016 6:06 AM by jterryii

    PowerCLI Script and folder organization help

    jessem Enthusiast

      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?

        • 1. Re: PowerCLI Script and folder organization help
          schepp Virtuoso
          vExpertUser Moderators

          Hey,

           

          of course there are scripts. And of course they were written by LucD ;-)

           

          You can find several here in the forums:

           

          Re: Folder migration

          Re: Export / Import selective Folder structure

           

          Tim

          • 2. Re: PowerCLI Script and folder organization help
            jessem Enthusiast

            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.

            • 3. Re: PowerCLI Script and folder organization help
              jessem Enthusiast

              Can anyone help me please?

              • 4. Re: PowerCLI Script and folder organization help
                adamjg Enthusiast

                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!

                • 5. Re: PowerCLI Script and folder organization help
                  jessem Enthusiast

                  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

                      }

                  }

                  • 6. Re: PowerCLI Script and folder organization help
                    adamjg Enthusiast

                    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.

                    • 7. Re: PowerCLI Script and folder organization help
                      jessem Enthusiast

                      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

                          }

                      }

                      • 8. Re: PowerCLI Script and folder organization help
                        adamjg Enthusiast

                        This is the line that imports the CSV file:

                         

                        $vmfolder = Import-Csv ".\$($Datacenter)-Folders-with-FolderPath.csv" | Sort-Object -Property Path

                        • 9. Re: PowerCLI Script and folder organization help
                          jessem Enthusiast

                          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?

                          • 10. Re: PowerCLI Script and folder organization help
                            adamjg Enthusiast

                            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

                            • 11. Re: PowerCLI Script and folder organization help
                              jessem Enthusiast

                              Perfect - that's exactly what I was looking for - thanks.

                              • 12. Re: PowerCLI Script and folder organization help
                                jterryii Lurker

                                I've seen several noble attempts out there to export and re-create folders but these rock!!  They worked perfectly!! Thank you!!