VMware Cloud Community
Alexandre2
Contributor
Contributor

VM folders on source datacenter and migration to another VM folders on a target datacenter

Hi all,

I've realized a script to migrate VM from one datacenter to another on the same vCenter. The last operations consist in create the VM folders of the source datacenter on the target datacenter only if it can't already exist.
At the end, I'll use the move-vm to move each VM in the right folder path.

I've already see many posts and script which are get-inventoryplus, get-folderpath but I've some difficulties to agregate all of this. More, I need to have the entire folder path.

Below an example of my folder structure where a VM can reside:
- SourceDatacenter/Folder1
- SourceDatacenter/Folder1/Application1
- SourceDatacenter/Folder1/Application2
- SourceDatacenter/Folder2/Application1

Can you help me please ? Thanks in advance.

 

Reply
0 Kudos
18 Replies
LucD
Leadership
Leadership

Are you saying the snippets in Solved: Re: Export/Import Folder Structure - VMware Technology Network VMTN don't work for you?


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

Reply
0 Kudos
Alexandre2
Contributor
Contributor

get-folderpath works fine, below the output (source datacenter is DC_OLD, target datacenter is DC_MAQ):

"Name";"Path";"Type"
"Qualif";"Centres de donn?es\DC_MAQ\Qualif";"blue"
"BL03";"Centres de donn?es\DC_MAQ\BL03";"blue"
"BAGD";"Centres de donn?es\DC_MAQ\BAGD";"blue"
"test_qualif";"Centres de donn?es\DC_MAQ\Qualif\test_qualif";"blue"
"BAGD";"Centres de donn?es\DC_TEST_LAN\BAGD";"blue"
"BL03";"Centres de donn?es\DC_TEST_LAN\BL03";"blue"
"SI1";"Centres de donn?es\DC_OLD\SI1";"blue"
"Qualif";"Centres de donn?es\DC_OLD\Qualif";"blue"
"SI2";"Centres de donn?es\DC_OLD\SI2";"blue"
"sv007472_folder";"Centres de donn?es\DC_OLD\sv007472_folder";"blue"
"Discovered virtual machine";"Centres de donn?es\DC_OLD\Discovered virtual machine";"blue"
"test_qualif";"Centres de donn?es\DC_OLD\Qualif\test_qualif";"blue"
"OME";"Centres de donn?es\DC_TEST\OME";"blue"
"ex-V4_cluster-bl03";"Centres de donn?es\DC_TEST\ex-V4_cluster-bl03";"blue"
"COW";"Centres de donn?es\DC_TEST\COW";"blue"
"Machine virtuelle d?tect?e";"Centres de donn?es\DC_TEST\Machine virtuelle d?tect?e";"blue"
"RH7";"Centres de donn?es\DC_TEST\RH7";"blue"
"WIN";"Centres de donn?es\DC_TEST\WIN";"blue"
"03 - ESS";"Centres de donn?es\DC_TEST\03 - ESS";"blue"
"02 - SAI";"Centres de donn?es\DC_TEST\02 - SAI";"blue"
"PSO";"Centres de donn?es\DC_TEST\PSO";"blue"
"WCRY";"Centres de donn?es\DC_TEST\WCRY";"blue"
"TEMPLATE";"Centres de donn?es\DC_TEST\TEMPLATE";"blue"
"SAFEKIT";"Centres de donn?es\DC_TEST\SAFEKIT";"blue"
"CLO";"Centres de donn?es\DC_TEST\CLO";"blue"
"ex-V4_NYPL";"Centres de donn?es\DC_TEST\ex-V4_NYPL";"blue"
"ex-V4_NYPL_demarrees";"Centres de donn?es\DC_TEST\ex-V4_NYPL_demarrees";"blue"
"ex-V4_cluster-ha-linux";"Centres de donn?es\DC_TEST\ex-V4_cluster-ha-linux";"blue"
"BAS";"Centres de donn?es\DC_TEST\BAS";"blue"
"IBS";"Centres de donn?es\DC_TEST\IBS";"blue"
"DEV";"Centres de donn?es\DC_TEST\COW\DEV";"blue"
"TEST";"Centres de donn?es\DC_TEST\WIN\TEST";"blue"
"WIN_2016";"Centres de donn?es\DC_TEST\WIN\WIN_2016";"blue"
"LS709905";"Centres de donn?es\DC_TEST\03 - ESS\LS709905";"blue"
"MO410795";"Centres de donn?es\DC_TEST\03 - ESS\MO410795";"blue"
"OME";"Centres de donn?es\DC_TEST\02 - SAI\OME";"blue"
"EXRAP";"Centres de donn?es\DC_TEST\02 - SAI\EXRAP";"blue"
"ST";"Centres de donn?es\DC_TEST\02 - SAI\ST";"blue"
"LOGI";"Centres de donn?es\DC_TEST\02 - SAI\LOGI";"blue"
"TEST";"Centres de donn?es\DC_TEST\PSO\TEST";"blue"
"RHEL_6.5";"Centres de donn?es\DC_TEST\TEMPLATE\RHEL_6.5";"blue"
"WIN_2012R2";"Centres de donn?es\DC_TEST\TEMPLATE\WIN_2012R2";"blue"
"RHEL_7.X";"Centres de donn?es\DC_TEST\TEMPLATE\RHEL_7.X";"blue"
"TEST";"Centres de donn?es\DC_TEST\CLO\TEST";"blue"
"TEST";"Centres de donn?es\DC_TEST\BAS\TEST";"blue"
"TEST";"Centres de donn?es\DC_TEST\IBS\TEST";"blue"
"APACHE";"Centres de donn?es\DC_TEST\03 - ESS\LS709905\APACHE";"blue"
"DR203355";"Centres de donn?es\DC_TEST\02 - SAI\ST\DR203355";"blue"
"MIG-AD";"Centres de donn?es\DC_TEST\02 - SAI\ST\MIG-AD";"blue"
"En attente";"Centres de donn?es\DC_TEST\CLO\TEST\En attente";"blue"

I've edited the csv files to retain the source datacenter only I execute the import script:

"Name";"Path";"Type"
"SI1";"Centres de donn?es\DC_OLD\SI1";"blue"
"Qualif";"Centres de donn?es\DC_OLD\Qualif";"blue"
"SI2";"Centres de donn?es\DC_OLD\SI2";"blue"
"sv007472_folder";"Centres de donn?es\DC_OLD\sv007472_folder";"blue"
"Discovered virtual machine";"Centres de donn?es\DC_OLD\Discovered virtual machine";"blue"
"test_qualif";"Centres de donn?es\DC_OLD\Qualif\test_qualif";"blue"

 

I've errors with the import script:

PS D:\Alexandre\Script> .\import.ps1
Get-Folder : 25/11/2021 12:21:07 Get-Folder Folder with name 'vm' was not found using the specified filter(s).
At D:\Alexandre\Script\import.ps1:7 char:48
+ $location = Get-Datacenter -Name $dcName | Get-Folder -Name 'vm'
+ ~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : ObjectNotFound: (:) [Get-Folder], VimException
+ FullyQualifiedErrorId : Core_OutputHelper_WriteNotFoundError,VMware.VimAutomation.ViCore.Cmdlets.Commands.GetFolder

Get-Inventory : 25/11/2021 12:21:07 Get-Inventory Inventory with name 'DC_OLD' was not found using the specified filter(s).
At D:\Alexandre\Script\import.ps1:13 char:25
+ ... $location = Get-Inventory -Name $_ -Location $location -NoRecursion
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : ObjectNotFound: (:) [Get-Inventory], VimException
+ FullyQualifiedErrorId : Core_OutputHelper_WriteNotFoundError,VMware.VimAutomation.ViCore.Cmdlets.Commands.GetInventory

New-Folder : 25/11/2021 12:21:07 New-Folder Value cannot be found for the mandatory parameter Location
At D:\Alexandre\Script\import.ps1:27 char:5
+ New-Folder -Name $newFolder -Location $location
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : NotSpecified: (:) [New-Folder], VimException
+ FullyQualifiedErrorId : Core_BaseCmdlet_UnknownError,VMware.VimAutomation.ViCore.Cmdlets.Commands.NewFolder

Get-Folder : 25/11/2021 12:21:07 Get-Folder Folder with name 'vm' was not found using the specified filter(s).
At D:\Alexandre\Script\import.ps1:7 char:48
+ $location = Get-Datacenter -Name $dcName | Get-Folder -Name 'vm'
+ ~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : ObjectNotFound: (:) [Get-Folder], VimException
+ FullyQualifiedErrorId : Core_OutputHelper_WriteNotFoundError,VMware.VimAutomation.ViCore.Cmdlets.Commands.GetFolder

Get-Inventory : 25/11/2021 12:21:08 Get-Inventory Inventory with name 'DC_OLD' was not found using the specified filter(s).
At D:\Alexandre\Script\import.ps1:13 char:25
+ ... $location = Get-Inventory -Name $_ -Location $location -NoRecursion
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : ObjectNotFound: (:) [Get-Inventory], VimException
+ FullyQualifiedErrorId : Core_OutputHelper_WriteNotFoundError,VMware.VimAutomation.ViCore.Cmdlets.Commands.GetInventory

New-Folder : 25/11/2021 12:21:08 New-Folder Value cannot be found for the mandatory parameter Location
At D:\Alexandre\Script\import.ps1:27 char:5
+ New-Folder -Name $newFolder -Location $location
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : NotSpecified: (:) [New-Folder], VimException
+ FullyQualifiedErrorId : Core_BaseCmdlet_UnknownError,VMware.VimAutomation.ViCore.Cmdlets.Commands.NewFolder

Get-Folder : 25/11/2021 12:21:08 Get-Folder Folder with name 'vm' was not found using the specified filter(s).
At D:\Alexandre\Script\import.ps1:7 char:48
+ $location = Get-Datacenter -Name $dcName | Get-Folder -Name 'vm'
+ ~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : ObjectNotFound: (:) [Get-Folder], VimException
+ FullyQualifiedErrorId : Core_OutputHelper_WriteNotFoundError,VMware.VimAutomation.ViCore.Cmdlets.Commands.GetFolder

Get-Inventory : 25/11/2021 12:21:08 Get-Inventory Inventory with name 'DC_OLD' was not found using the specified filter(s).
At D:\Alexandre\Script\import.ps1:13 char:25
+ ... $location = Get-Inventory -Name $_ -Location $location -NoRecursion
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : ObjectNotFound: (:) [Get-Inventory], VimException
+ FullyQualifiedErrorId : Core_OutputHelper_WriteNotFoundError,VMware.VimAutomation.ViCore.Cmdlets.Commands.GetInventory

New-Folder : 25/11/2021 12:21:08 New-Folder Value cannot be found for the mandatory parameter Location
At D:\Alexandre\Script\import.ps1:27 char:5
+ New-Folder -Name $newFolder -Location $location
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : NotSpecified: (:) [New-Folder], VimException
+ FullyQualifiedErrorId : Core_BaseCmdlet_UnknownError,VMware.VimAutomation.ViCore.Cmdlets.Commands.NewFolder

Get-Folder : 25/11/2021 12:21:08 Get-Folder Folder with name 'vm' was not found using the specified filter(s).
At D:\Alexandre\Script\import.ps1:7 char:48
+ $location = Get-Datacenter -Name $dcName | Get-Folder -Name 'vm'
+ ~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : ObjectNotFound: (:) [Get-Folder], VimException
+ FullyQualifiedErrorId : Core_OutputHelper_WriteNotFoundError,VMware.VimAutomation.ViCore.Cmdlets.Commands.GetFolder

Get-Inventory : 25/11/2021 12:21:08 Get-Inventory Inventory with name 'DC_OLD' was not found using the specified filter(s).
At D:\Alexandre\Script\import.ps1:13 char:25
+ ... $location = Get-Inventory -Name $_ -Location $location -NoRecursion
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : ObjectNotFound: (:) [Get-Inventory], VimException
+ FullyQualifiedErrorId : Core_OutputHelper_WriteNotFoundError,VMware.VimAutomation.ViCore.Cmdlets.Commands.GetInventory

New-Folder : 25/11/2021 12:21:08 New-Folder Value cannot be found for the mandatory parameter Location
At D:\Alexandre\Script\import.ps1:27 char:5
+ New-Folder -Name $newFolder -Location $location
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : NotSpecified: (:) [New-Folder], VimException
+ FullyQualifiedErrorId : Core_BaseCmdlet_UnknownError,VMware.VimAutomation.ViCore.Cmdlets.Commands.NewFolder

Get-Folder : 25/11/2021 12:21:08 Get-Folder Folder with name 'vm' was not found using the specified filter(s).
At D:\Alexandre\Script\import.ps1:7 char:48
+ $location = Get-Datacenter -Name $dcName | Get-Folder -Name 'vm'
+ ~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : ObjectNotFound: (:) [Get-Folder], VimException
+ FullyQualifiedErrorId : Core_OutputHelper_WriteNotFoundError,VMware.VimAutomation.ViCore.Cmdlets.Commands.GetFolder

Get-Inventory : 25/11/2021 12:21:08 Get-Inventory Inventory with name 'DC_OLD' was not found using the specified filter(s).
At D:\Alexandre\Script\import.ps1:13 char:25
+ ... $location = Get-Inventory -Name $_ -Location $location -NoRecursion
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : ObjectNotFound: (:) [Get-Inventory], VimException
+ FullyQualifiedErrorId : Core_OutputHelper_WriteNotFoundError,VMware.VimAutomation.ViCore.Cmdlets.Commands.GetInventory

New-Folder : 25/11/2021 12:21:08 New-Folder Value cannot be found for the mandatory parameter Location
At D:\Alexandre\Script\import.ps1:27 char:5
+ New-Folder -Name $newFolder -Location $location
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : NotSpecified: (:) [New-Folder], VimException
+ FullyQualifiedErrorId : Core_BaseCmdlet_UnknownError,VMware.VimAutomation.ViCore.Cmdlets.Commands.NewFolder

Get-Folder : 25/11/2021 12:21:08 Get-Folder Folder with name 'vm' was not found using the specified filter(s).
At D:\Alexandre\Script\import.ps1:7 char:48
+ $location = Get-Datacenter -Name $dcName | Get-Folder -Name 'vm'
+ ~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : ObjectNotFound: (:) [Get-Folder], VimException
+ FullyQualifiedErrorId : Core_OutputHelper_WriteNotFoundError,VMware.VimAutomation.ViCore.Cmdlets.Commands.GetFolder

Get-Inventory : 25/11/2021 12:21:08 Get-Inventory Inventory with name 'DC_OLD' was not found using the specified filter(s).
At D:\Alexandre\Script\import.ps1:13 char:25
+ ... $location = Get-Inventory -Name $_ -Location $location -NoRecursion
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : ObjectNotFound: (:) [Get-Inventory], VimException
+ FullyQualifiedErrorId : Core_OutputHelper_WriteNotFoundError,VMware.VimAutomation.ViCore.Cmdlets.Commands.GetInventory

Get-Inventory : 25/11/2021 12:21:08 Get-Inventory Inventory with name 'Qualif' was not found using the specified filter(s).
At D:\Alexandre\Script\import.ps1:13 char:25
+ ... $location = Get-Inventory -Name $_ -Location $location -NoRecursion
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : ObjectNotFound: (:) [Get-Inventory], VimException
+ FullyQualifiedErrorId : Core_OutputHelper_WriteNotFoundError,VMware.VimAutomation.ViCore.Cmdlets.Commands.GetInventory

New-Folder : 25/11/2021 12:21:08 New-Folder Value cannot be found for the mandatory parameter Location
At D:\Alexandre\Script\import.ps1:27 char:5
+ New-Folder -Name $newFolder -Location $location
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : NotSpecified: (:) [New-Folder], VimException
+ FullyQualifiedErrorId : Core_BaseCmdlet_UnknownError,VMware.VimAutomation.ViCore.Cmdlets.Commands.NewFolder

 

Reply
0 Kudos
LucD
Leadership
Leadership

The first error (the "vm" folder) is causing all the other errors.

I find it strange that you apparently have a Datacenter with a hidden "vm" folder.
That is normally the folder where everything under VMs and Templates is stored.

What does the following return?

Get-Datacenter -Name <dcname> | Get-Folder | Select Name


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

Reply
0 Kudos
Alexandre2
Contributor
Contributor

Below the ouput of both DC:

 

PS D:\Alexandre\Script> Get-Datacenter -Name dc_maq | Get-Folder | Select Name

Name
----
vm
network
host
datastore
Qualif
BL03
BAGD
Witness
folder1
test_qualif

 

PS D:\Alexandre\Script> Get-Datacenter -Name dc_old | Get-Folder | Select Name

Name
----
vm
network
host
datastore
SI1
Qualif
SI2
sv007472_folder
Discovered virtual machine
test_qualif

Reply
0 Kudos
LucD
Leadership
Leadership

There are apparently some Datacenters in the export list that do not exist in the target vCenter.
The Datacenter is the first qualifier in the path in the export CSV.


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

Reply
0 Kudos
Alexandre2
Contributor
Contributor

It's very strange because the both datacenters are in the same vCenter.

Reply
0 Kudos
Alexandre2
Contributor
Contributor

It's works fine when I modify manually the export.csv file like this:

1) Replace old datacenter name by target datacenter name

2) Remove "Centres de donn?es" which is datacenter in french. Before:  "Qualif";"Centres de donn?es\DC_MAQ\Qualif";"blue". After: "Qualif";"DC_MAQ\Qualif";"blue"

3) Sort by name because the import script can't create sub folder if the parent don't exist

All of this actions has been realized manually.

Reply
0 Kudos
LucD
Leadership
Leadership

1. Yes, that is 1 global change in the CSV

2. Yes, same as in 1.

3. Normally the export order in the CSV avoids this issue.
Unless of course the Path is changed.

So what is then the issue with the code?
Those changes are not foreseen in the snippets.
You could eventually code those changes as well.


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

Reply
0 Kudos
Alexandre2
Contributor
Contributor

I added these lignes to my script to replace the words in the csv file like this:

 

[io.file]::readalltext(“D:\Alexandre\Script\folders.csv”).replace(“DC_OLD”,”DC_MAQ”) | Out-File “D:\Alexandre\Script\folders.csv" -Encoding ascii –Force
[io.file]::readalltext(“D:\Alexandre\Script\folders.csv”).replace(“Centres de donn?es\”,””) | Out-File “D:\Alexandre\Script\folders.csv" -Encoding ascii –Force

 

Now, I can create all missing folders on the target datacenter.

However, how is possible to move VM to the right path folder ? The getfolderpath give me the list of all folders to create these on the target but I don't have the relation VM/folder of the source datacenter.

 

Reply
0 Kudos
LucD
Leadership
Leadership

Those snippets are only for recreating a folder structure.
Migrating VMs requires other code.


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

Reply
0 Kudos
Alexandre2
Contributor
Contributor

Thanks, now I can recreate the folder structure on the target datacenter.

For the next step, I use the get-inventory script to obtain a list of virtual machines and folder paths but I have VM name in the path. More, I don't know how I can obtain the target folder for each VM and the migration all of them. 

 

Below the details.

Script

function Get-InventoryPlus
{
<#
.SYNOPSIS
Retrieve the objects available on a vSphere Server.
.DESCRIPTION
This function will retrieve all objects available on a
vSphere Server, including all storage and network objects.
.NOTES
Author: Luc Dekens
.PARAMETER Server
The vSphere Server (vCenter or ESXi) from which to retrieve
the objects.
The default is $Global:DefaultVIServer
.PARAMETER NoValue
Properties that are not set are returned as an empty string.
The value on this parameter will be used instead of the empty
string.
.EXAMPLE
PS> Get-InventoryPlus
.EXAMPLE
PS> Get-InventoryPlus -Server $vCenter
.EXAMPLE
PS> Get-InventoryPlus -NoValue 'na'
#>

[cmdletbinding()]
param(
[VMware.VimAutomation.ViCore.Types.V1.VIServer]$Server = $Global:DefaultVIServer,
[String]$NoValue = ''
)

function Get-ViBlueFolderPath{
[cmdletbinding()]
param(
[VMware.Vim.ManagedEntity]$Item
)

$hidden = 'Datacenters','vm'

if($Item -is [VMware.Vim.VirtualMachine]){
$Item.UpdateViewData('Parent')
$parent = $Item.Parent
}
elseif($Item -is [VMware.Vim.VirtualApp]){
$Item.UpdateViewData('ParentFolder')
$parent = $Item.ParentFolder
}

if($parent){
$path = @($Item.Name)
while($parent){
$object = Get-View -Id $parent -Property Name,Parent
if($hidden -notcontains $object.Name){
$path += $object.Name
}
if($object -is [VMware.Vim.VirtualApp]){
$object.UpdateViewData('ParentFolder')
if($object.ParentFolder){
$parent = $object.ParentFolder
}
else{
$object.UpdateViewData('ParentVapp')
if($object.ParentVapp){
$parent = $object.ParentVapp
}
}
}
else{
$parent = $object.Parent
}
}
[array]::Reverse($path)
return "/$($path -join '/')"
}
else{
return $NoValue
}
}

function Get-ObjectInfo{
[cmdletbinding()]
param(
[parameter(ValueFromPipeline)]
[VMware.Vim.ManagedEntity]$Object
)

Begin{
$hidden = 'Datacenters','vm','host','network','datastore','Resources'
}

Process{
if($hidden -notcontains $Object.Name){
$props = [ordered]@{
Name = $Object.Name
Type = $Object.GetType().Name
BluePath = $NoValue
}
$blueFolder = $false
$isTemplate = $false
if($object -is [VMware.Vim.Folder]){
$object.UpdateViewData('ChildType')
if($Object.ChildType -contains 'VirtualMachine'){
$blueFolder = $true
}
}
$path = @($Object.Name)
$parent = $Object.Parent

if($object -is [VMware.Vim.VirtualMachine] -or $object -is [VMware.Vim.VirtualApp]){
$props['BluePath'] = Get-VIBlueFolderPath -Item $Object
if($Object -is [VMware.Vim.VirtualMachine]){
$Object.UpdateViewData('ResourcePool','Config.Template')
if($Object.Config.Template){
$parent = $Object.Parent
$props['Type'] = 'Template'
$isTemplate = $true
}
else{
$parent = $Object.ResourcePool
}
}
}
while($parent){
$Object = Get-View -Id $Parent -Property Name,Parent
$parent = $Object.Parent
if($hidden -notcontains $Object.Name){
$path += $Object.Name
}
}
[array]::Reverse($path)
$path = "/$($path -join '/')"
$props.Add('Path',$path)

if($blueFolder){
$props['BluePath'] = $props['Path']
$props['Path'] = $NoValue
}
if($isTemplate){
$props['Path'] = $NoValue
}
New-Object PSObject -Property $props
}
}
}

$sView = @{
Id = 'ServiceInstance'
Server = $Server
Property = 'Content.ViewManager','Content.RootFolder'
}
$si = Get-view @sview
$viewMgr = Get-View -Id $si.Content.ViewManager

$contView = $viewMgr.CreateContainerView($si.Content.RootFolder,$null,$true)
$contViewObj = Get-View -Id $contView

Get-View -Id $contViewObj.View -Property Name,Parent |
where{$hidden -notcontains $_.Name} |
Get-ObjectInfo
}
Get-InventoryPlus | where {($_.Type -eq "VirtualMachine") -and ($_.BluePath -like "*DC_OLD*")} | Out-File D:\Alexandre\Script\inventory.txt

 

Extract file

Name Type BluePath Path
---- ---- -------- ----
Name Type BluePath Path
---- ---- -------- ----
sv007561 VirtualMachine /Centres de donn?es/DC_MAQ/BL03/sv007561 /Centres de donn?es/DC_MAQ/CL_TEST_BL03_LAN/sv007561
sv007563 VirtualMachine /Centres de donn?es/DC_MAQ/BL03/sv007563 /Centres de donn?es/DC_MAQ/CL_TEST_BL03_LAN/sv007563
sv007562 VirtualMachine /Centres de donn?es/DC_MAQ/BL03/sv007562 /Centres de donn?es/DC_MAQ/CL_TEST_BL03_LAN/sv007562
sv007566 VirtualMachine /Centres de donn?es/DC_MAQ/BL03/sv007566 /Centres de donn?es/DC_MAQ/CL_TEST_BL03_LAN/sv007566
sv006171 VirtualMachine /Centres de donn?es/DC_MAQ/BL03/sv006171 /Centres de donn?es/DC_MAQ/CL_TEST_BL03_LAN/sv006171

Reply
0 Kudos
LucD
Leadership
Leadership

You can use the Split-Path cmdlet, and then in a loop follow the path to get the target folder.
Something like this for example

$path = '/Centres de donn?es/DC_MAQ/CL_TEST_BL03_LAN/sv007561'

$parent = (Split-Path -Path $path -Parent).Replace('\','/')
$vm = Split-Path -Path $path -Leaf

$folder = Get-Folder -Name Datacenters

$parent.split('/') | where{$_} | ForEach-Object -Process {
  $folder = Get-Inventory -Location $folder -Name $_
}

Write-Host "Move VM $($vm) to folder $($folder.Name)"


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

Reply
0 Kudos
Alexandre2
Contributor
Contributor

Ok it's works fine.

 

I launch the get-inventoryplus function but it's very long because I realize a new inventory and retain each time the VM in $VM which is a list of VMs.

How can I optimize this ? I would launch get-inventoryplus only one time for all VM that are in my VM file.

 

Below my script

function Get-InventoryPlus
{
......
}


import-csv liste_VMs.csv | foreach {
$VM = get-vm $_.Name
write-host $VM
Get-InventoryPlus | where {($_.Name -eq $VM) -and ($_.BluePath -like "*DC_OLD*")} | export-csv -append -notype -path D:\Alexandre\Script\inventory.csv -Delimiter ";"

Reply
0 Kudos
LucD
Leadership
Leadership

You could use a hash table to store the VM returned by Get-InventoryPlus, and that meet the requirements ('DC_OLD').

Then read your CSV file, and check if the VM is in the hash table.
You can refer to the BluePath with $vmTab[$_.Name]

$vmTab = @{}

Get-InventoryPlus | 
where {$_.Type -eq 'VirtualMachine' -and $_.BluePath -match 'DC_OLD'} |
ForEach-Object -Process {
    $vmTab.Add($_.Name,$_.BluePath)
}

Import-Csv -Path liste_VMs.csv |
where{$vmTab.ContainsKey($_.Name)} |
ForEach-Object -Process {

    # Your code for this VM, path can be retrieved with $vmTab[$_.Name]

}

 


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

Reply
0 Kudos
Alexandre2
Contributor
Contributor

I've a problem with this command. I can't have VM name and Bluepath too:

Get-InventoryPlus | where {$_.Type -eq 'VirtualMachine' -and $_.BluePath -match 'DC_OLD'} |
ForEach-Object -Process {
$vmTab.Add($_.Name,$_.BluePath)
}
write-host $_.name
write-host $_.Bluepath
write-output $vmtab

write-host $_.Name -->

VM1

write-host $_.Bluepath -->

/Centres de données/DC_OLD/SI1/test2/VM1

write-output $vmtab -->

Key : VM1
Value : /Centres de données/DC_OLD/SI1/test2/VM1
Name : VM1

Output

Import-Csv -Path liste_VMs.csv |
where{$vmTab.ContainsKey($_.Name)} |
ForEach-Object -Process {

write-output $vmTab.($_.Name)
# Your code for this VM, path can be retrieved with $vmTab[$_.Name]

}

#$vmTab.($_.Name) give me only the bluepath and not both (VM & Bluepath)
/Centres de données/DC_OLD/SI1/test2/VM1

 

 

Reply
0 Kudos
LucD
Leadership
Leadership

That is normal.
The $_.Name is the "key" into the hash table, and thus returns the value ($_.BluePath)


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

Reply
0 Kudos
Alexandre2
Contributor
Contributor

Ok, so how i can retrieve the VM name and blue path like this ?

"Name";"Bluepath"

"VM1";"/Centres de données/DC_MAQ/SI1/test2/VM1"

Reply
0 Kudos
LucD
Leadership
Leadership

I just explained that.

In the sample snippet earlier, you read the VM from your CSV, and then you look up the BluePath from the hash table, with the VM name as the key.


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

Reply
0 Kudos