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.
I normally use the following 2 scripts.
To export
<#
.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
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
-----------------------------------------------------------------------------
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
-----------------------------------------------------------------------------
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.
Get-FolderPath is not a PowerCLI cmdlet, but a function I wrote.
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
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.
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.
I normally use the following 2 scripts.
To export
<#
.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
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
Hi LucD,
I have different scripts in use from you. Now I would use your Folder-Script (export/import). It works. During the import, however, the folders are only created up to the 3rd level.
Br Tobias
I did notice that the Pattern expression in the above reply is incorrect.
I assume this is an HTML issue when the posts were migrated from the Jive platform to the Khoros platform.
That line should say (note the Pattern expression with back-slash back-slash plus-sign)
Sort-Object -Property { (Select-String -InputObject $_.Path -Pattern '\\+' -AllMatches).Matches.Count } | ForEach-Object {
Does that produce the correct folder structure on import?
I just tested with 4 levels deep, and it seems to work for me.
Blog: lucd.info Twitter: @LucD22 Co-author PowerCLI Reference
It's perfect your support.
Works fine.
Thanks so much.
Great stuff as always @LucD
I was wondering if your export/import script can be set to exclude any empty folders from the export part?
You can add an extra condition to the Where-clause
$report = Get-folder -type VM | where{$_.Name -ne 'vm' -and $_.ExtensionData.childEntity.Count -ne 0} | Get-Folderpath
Blog: lucd.info Twitter: @LucD22 Co-author PowerCLI Reference
Perfect, thanks!
Just ignore my last comment this is exactly what I needed i just had to replace datacenter on destination datacenter and then works like a charm
Hi LucD,
Thanks for the great script.
An issue I have seen when coming to import is that it sometimes tries to recreate the sub folder before the folder above is created, and fails. It's not really an issue as I just ran the script over and over until it had no more folders to create.
I tried sorting the folders.csv file by the path column, but this didn't seem to help.
Cheers
Did you include the Sort-Object with the Select-String I mentioned in another reply?
That should sort the Folders based on the depth of the folderpath
Blog: lucd.info Twitter: @LucD22 Co-author PowerCLI Reference