umms
Enthusiast
Enthusiast

Export/Import Folder Structure

Jump to solution

Hi,

So I found this command:

Get-folder -type VM | Foreach {($_ | Get-FolderPath).Path | Out-file C:\scripts\logs\Folders.txt -Append}

When run I get the following error:

Get-FolderPath : The term 'Get-FolderPath' is not recognized as the name of a cmdlet, function, script file, or

operable program. Check the spelling of the name, or if a path was included, verify that the path is correct and try

again.

At line:1 char:38

+ Get-folder -type VM | Foreach {($_ | Get-FolderPath).Path | Out-file  ...

+                                      ~~~~~~~~~~~~~~

    + CategoryInfo          : ObjectNotFound: (Get-FolderPath:String) [], CommandNotFoundException

    + FullyQualifiedErrorId : CommandNotFoundException

Anyone have any suggestions on this one? Also looking for a good Import script.

Thanks.

0 Kudos
1 Solution

Accepted Solutions
LucD
Leadership
Leadership

I normally use the following 2 scripts.

To export

function Get-FolderPath{

    <#

    .SYNOPSIS

        Returns the folderpath for a folder

    .DESCRIPTION

        The function will return the complete folderpath for

        a given folder, optionally with the "hidden" folders

        included. The function also indicats if it is a "blue"

        or "yellow" folder.

    .NOTES

        Authors:    Luc Dekens

    .PARAMETER Folder

        On or more folders

    .PARAMETER ShowHidden

        Switch to specify if "hidden" folders should be included

        in the returned path. The default is $false.

    .EXAMPLE

        PS> Get-FolderPath -Folder (Get-Folder -Name "MyFolder")

    .EXAMPLE

        PS> Get-Folder | Get-FolderPath -ShowHidden:$true

    #>

 

        param(

        [parameter(valuefrompipeline = $true,

        position = 0,

        HelpMessage = "Enter a folder")]

        [VMware.VimAutomation.ViCore.Impl.V1.Inventory.FolderImpl[]]$Folder,

        [switch]$ShowHidden = $false

        )

 

        begin{

            $excludedNames = "Datacenters","vm","host"

        }

 

        process{

            $Folder | %{

                $fld = $_.Extensiondata

                $fldType = "yellow"

                if($fld.ChildType -contains "VirtualMachine"){

                    $fldType = "blue"

                }

                $path = $fld.Name

                while($fld.Parent){

                    $fld = Get-View $fld.Parent

                    if((!$ShowHidden -and $excludedNames -notcontains $fld.Name) -or $ShowHidden){

                        $path = $fld.Name + "\" + $path

                    }

                }

                $row = "" | Select Name,Path,Type

                $row.Name = $_.Name

                $row.Path = $path

                $row.Type = $fldType

                $row

            }

        }

    }

    ## Export all folders

    $report = @()

    $report = Get-folder -type VM | where{$_.Name -ne 'vm'} | Get-Folderpath

    $report | Export-Csv '.\folders.csv' -NoTypeInformation -UseCulture

To import

Import-Csv -Path '.\folders.csv' -UseCulture |

Sort-Object -Property {(Select-String -InputObject $_.Path -Pattern '/+' -AllMatches).Matches.Count} | %{

    $dcName,$rest = $_.Path.Split('\')

    $location = Get-Datacenter -Name $dcName | Get-Folder -Name 'vm'

    if($rest.count -gt 1){

        $rest[0..($rest.Count -2)] | %{

            $location = Get-Inventory -Name $_ -Location $location -NoRecursion

        }

        $newFolder = $rest[-1]

    }

    else{

        $newFolder = $rest

    }

    New-Folder -Name $newFolder -Location $location

}


Blog: lucd.info  Twitter: @LucD22  Co-author PowerCLI Reference

View solution in original post

0 Kudos
5 Replies
Nawals
Expert
Expert

Export all VMs list with Folder structure.

-----------------------------------------------------------------------------

New-VIProperty -Name 'BlueFolderPath' -ObjectType 'VirtualMachine' -Value {
    param($vm)

    function Get-ParentName{
        param($object)

        if($object.Folder){
            $blue = Get-ParentName $object.Folder
            $name = $object.Folder.Name
        }
        elseif($object.Parent -and $object.Parent.GetType().Name -like "Folder*"){
            $blue = Get-ParentName $object.Parent
            $name = $object.Parent.Name
        }
        elseif($object.ParentFolder){
            $blue = Get-ParentName $object.ParentFolder
            $name = $object.ParentFolder.Name
        }
        if("vm","Datacenters" -notcontains $name){
            $blue + "/" + $name
        }
        else{
            $blue
        }
    }

    (Get-ParentName $vm).Remove(0,1)
} -Force | Out-Null

$dcName = "vLAB_DC"

Get-VM -Location (Get-Datacenter -Name $dcName | Get-Cluster "vLAB_Cluster") |
Select Name, VMHost, BlueFolderPath |
Export-Csv "C:\vcenter-migration\vLAB-VMs-Folder.csv" -NoTypeInformation -UseCulture
-----------------------------------------------------------------------------

Import Folder structure and Move VMs to its original folder.


Below script will create folder structure and move VMs to its own folder as it was in old vCenter.

----------------------------------------------------------------------------------------------------------------------------------------------------------  #Import Folders and Move VMs to its folder

$vmsonha5 = Get-Cluster vLAB_Cluster | Get-VM  |sort name
$csv3 = "C:\vCenter-Migration\vLAB_VMs_Folder.csv"

$newDatacenter = "RnDDataCenter5.x"
$newFolder = "vCenter-Folders"

$startFolder = New-Folder -Name $newFolder -Location (Get-Folder -Name vm -Location (Get-Datacenter -Name $newDatacenter))
$startfolder = Get-Folder "vCenter-Folders"

$testing2 = Import-Csv $csv3 -UseCulture

$testing2 | %{
    $location = $startFolder
    $_.BlueFolderPath.TrimStart('/').Split('/') | %{
        $tgtFolder = Get-Folder -Name $_ -Location $location -ErrorAction SilentlyContinue
        if(!$tgtFolder){
            $location = New-Folder -Name $_ -Location $location
        }
        else{
            $location = $tgtFolder
        }
    }
   
#     Write-Host $location
    $hm = $_.Name2
$wups = $vmsonha5 | where {$_.name -eq $hm}

#Write-Host $hm
Move-VM -VM $wups -Destination $location -Confirm:$false -RunAsync
    }

-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------


If your inventory is huge and if this script takes time to complete, I would suggest splitting VM csv file and running this same script in multiple sessions for each csv

This will help you to complete the task with less time.


E.g. in my activity each signal migration was taking 8 seconds to migrate each VM, then I divided exported csv and saved with 5 different names. Created 5 different copies of above script and executed in different in PowerCLI sessions, this helped me to reduce the migration time.

NKS Please Mark Helpful/correct if my answer resolve your query.
0 Kudos
LucD
Leadership
Leadership

Get-FolderPath is not a PowerCLI cmdlet, but a function I wrote.

See Get The Folderpath

On your import question, how did you do the export or what is in the file with the import information?


You can use my New-VIProperties (which the previous replier copied without a reference it seems) I defined in Export / Import selective Folder structure


Blog: lucd.info  Twitter: @LucD22  Co-author PowerCLI Reference

0 Kudos
umms
Enthusiast
Enthusiast

Ok, I went on that page. I copied the script and ran it.

So how would I get the script I originally put in this post to work so I can get a file that outputs the Folder structure?

Oh and for import I would just use the same format as the export script.

0 Kudos
umms
Enthusiast
Enthusiast

Ok, I got this script to work to export to CSV:

Import-Module VMware.VimAutomation.Core

If ($globale:DefaultVIServers) {

Disconnect-VIServer -Server $global:DefaultVIServers -Force

}

$sourceVI = Read-Host "Please enter name or IP address of the source Server"

$datacenter = Read-Host "Datacenter name in source vCenter"

$creds = get-credential

connect-viserver -server $sourceVI -Credential $creds

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 -Server $sourceVI| 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 | Export-Csv "d:\temp\scripts\03-$($datacenter)-Folders-with-FolderPath.csv" -NoTypeInformation

Disconnect-VIServer "*" -Confirm:$False

Now I found a similar script to import the folder structure and it does it by DataCenter. I am wondering can you do it by DataCenter and then Subfolder. For example I want to import the structure to

DC=Test

Subfolder=Test

and now all folders and subfolders that were exported.

0 Kudos
LucD
Leadership
Leadership

I normally use the following 2 scripts.

To export

function Get-FolderPath{

    <#

    .SYNOPSIS

        Returns the folderpath for a folder

    .DESCRIPTION

        The function will return the complete folderpath for

        a given folder, optionally with the "hidden" folders

        included. The function also indicats if it is a "blue"

        or "yellow" folder.

    .NOTES

        Authors:    Luc Dekens

    .PARAMETER Folder

        On or more folders

    .PARAMETER ShowHidden

        Switch to specify if "hidden" folders should be included

        in the returned path. The default is $false.

    .EXAMPLE

        PS> Get-FolderPath -Folder (Get-Folder -Name "MyFolder")

    .EXAMPLE

        PS> Get-Folder | Get-FolderPath -ShowHidden:$true

    #>

 

        param(

        [parameter(valuefrompipeline = $true,

        position = 0,

        HelpMessage = "Enter a folder")]

        [VMware.VimAutomation.ViCore.Impl.V1.Inventory.FolderImpl[]]$Folder,

        [switch]$ShowHidden = $false

        )

 

        begin{

            $excludedNames = "Datacenters","vm","host"

        }

 

        process{

            $Folder | %{

                $fld = $_.Extensiondata

                $fldType = "yellow"

                if($fld.ChildType -contains "VirtualMachine"){

                    $fldType = "blue"

                }

                $path = $fld.Name

                while($fld.Parent){

                    $fld = Get-View $fld.Parent

                    if((!$ShowHidden -and $excludedNames -notcontains $fld.Name) -or $ShowHidden){

                        $path = $fld.Name + "\" + $path

                    }

                }

                $row = "" | Select Name,Path,Type

                $row.Name = $_.Name

                $row.Path = $path

                $row.Type = $fldType

                $row

            }

        }

    }

    ## Export all folders

    $report = @()

    $report = Get-folder -type VM | where{$_.Name -ne 'vm'} | Get-Folderpath

    $report | Export-Csv '.\folders.csv' -NoTypeInformation -UseCulture

To import

Import-Csv -Path '.\folders.csv' -UseCulture |

Sort-Object -Property {(Select-String -InputObject $_.Path -Pattern '/+' -AllMatches).Matches.Count} | %{

    $dcName,$rest = $_.Path.Split('\')

    $location = Get-Datacenter -Name $dcName | Get-Folder -Name 'vm'

    if($rest.count -gt 1){

        $rest[0..($rest.Count -2)] | %{

            $location = Get-Inventory -Name $_ -Location $location -NoRecursion

        }

        $newFolder = $rest[-1]

    }

    else{

        $newFolder = $rest

    }

    New-Folder -Name $newFolder -Location $location

}


Blog: lucd.info  Twitter: @LucD22  Co-author PowerCLI Reference

View solution in original post

0 Kudos