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.
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
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
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
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
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
It's very strange because the both datacenters are in the same vCenter.
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.
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
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.
Those snippets are only for recreating a folder structure.
Migrating VMs requires other code.
Blog: lucd.info Twitter: @LucD22 Co-author PowerCLI Reference
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
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
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 ";"
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
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
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
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"
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