So here is what I'm trying to do. I've seen other posts relating to this, but they only seem to get the immediate parent path rather than the full path. We've basically setup a tree structure like this:
DATA_Center\business_service\SLDC\VM (SLDC = Software Development Cycle)
We've set it up this way so it is easier for admins to find systems related to a particular business service. When a SAN maintenance occurs, we like to inform the business service admins affected by the maintenance. So we basically build a spreadsheet and find all the LUN's attached to that particular SAN, find the VM's, then lookup folder path the VM lies under to find what what business service is affected. I've attached a photo of our VC folder setup as an example.
I was wondering if it was possible through powershell to get a VM's associated folder path like what I have above. I'm able to grab all other information needed, except the folder path. Here is what I have so far:
Get-VM | % {Get-View $_.ID} |
select name,
@{ Name="Datastore";Expression={(Get-Datastore -VM $_.Name).Name}}
(All VMDK's for a server reside on the same datastore so I have no need to look for or list other datastores for a single VM)
I tried messing w/ the script in the below thread for folder pathing, but I can't seem to get what I'm looking for.
http://communities.vmware.com/thread/170864
Ok, the following script should do the trick.
One remark though, if a guest is stored over multiple datastores, only the first datastore will be reported.
$report = @() Get-VM | Get-View | %{ $row = "" | select Name, Datastore, Path $row.Name = $_.Name $row.Datastore = (Get-View $_.Datastore[0]).Summary.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 $report += $row } $report
Note1: that this is the view of the "blue" folders. The "Virtual Machines and Templates" view in the VI client.
Note2: the script suppresses the display of the hidden "vm" folder
Blog: lucd.info Twitter: @LucD22 Co-author PowerCLI Reference
Did you have a look at my script in .
It lists all guests with their complete path and that for the "Hosts & Clusters" view as well as for the "Virtual Machines & Templates" view (blue folders).
Blog: lucd.info Twitter: @LucD22 Co-author PowerCLI Reference
I did not see that. I'll take a look now, thanks. (_)
So I finally got a few minutes to look over the script you referenced. It works great for going top down, but I'm looking to get folder pathing the other way around. From VM to top, you think this is doable?
If I understand it correctly you want the list to be
<VM-name>\<folder-name>\<cluster-name>\<datacenter-name>
instead of
<datacenter-name>\<cluster-name>\<folder-name>\<VM-name>
.
If that is the case, the following script will do that:
function get-children-reverse($entity,$path){ if($entity.Name -ne "vm"){ $path = $entity.Name + "\" + $path } foreach($child in $entity.ChildEntity){ $childfld = Get-View -Id $child switch($childfld.gettype().name){ "Folder" { Write-Host ($childfld.Name + "\" + $path) get-children-reverse $childfld $path } "VirtualMachine"{ $vm = $childfld.Name + "\" + $path Write-Host $vm } "Datacenter"{ Write-Host ($childfld.Name + "\" + $path) get-children-reverse $childfld $path } "ClusterComputeResource" { Write-Host ($childfld.Name + "\" + $path) foreach($esxMoRef in $childfld.Host){ $esx = Get-View -Id $esxMorEF $h = $esx.Name+ "\" + $childfld.Name + "\" + $path Write-Host $h } } } } } # Virtual machines & Templates Write-Host "Virtual Machines & Templates`n" Get-Datacenter | %{ $dc = Get-View -Id ($_).id $folder = Get-View -Id $dc.VmFolder get-children-reverse $folder $dc.Name } # Hosts & Clusters Write-Host "`nHosts & Clusters`n" Get-Datacenter | %{ $dc = Get-View -Id ($_).id $folder = Get-View -Id $dc.HostFolder get-children-reverse $folder $dc.Name }
Note: if you only want VMs and Templates to be listed it can be done easily by removing the Write-Host cmdlets in the get-children-reverse function except for the "VirtualMachine" case.
Blog: lucd.info Twitter: @LucD22 Co-author PowerCLI Reference
Err, not exactly looking for just semantics. What I meant was using my above script, I'm looking for systems that are inside certain datastores. I think I can use your script, but I don't have an idea as how to reference the objects outputted by your function. For instance:
$VIserver = Read-Host "VC Server Name"
connect-viserver -server $VIserver
Get-VM | % {Get-View $_.ID} |
select name,
@{ Name="Datastore";Expression={(Get-Datastore -VM $_.Name) | where {$_.Name -inotmatch 'nfs_share'}}}
This outputs a table that lists a VM's Name and the name of the datastore where the VM resides. I want to add folder path to this. Using your function I was trying to do something like this:
@{ Name="Path";Expression={Get-Datacenter | % {(get-children $_.VmFolder $_.Name) | where {$_ -contains '$_'} }}}
Basically to only output the path that contains the VM's name. I'm pretty sure I'm screwed up on the where command if not elsewhere.
Before I start coding, you want a report showing
Name Path VM1 datacenter1\folder1\VM1 VM2 datacenter1\folder2\VM2 VM3 datacenter2\folder2\VM3
Did I understand it correctly now ?
Blog: lucd.info Twitter: @LucD22 Co-author PowerCLI Reference
Yeppers. Datastore column as well.
Thanks.
Ok, the following script should do the trick.
One remark though, if a guest is stored over multiple datastores, only the first datastore will be reported.
$report = @() Get-VM | Get-View | %{ $row = "" | select Name, Datastore, Path $row.Name = $_.Name $row.Datastore = (Get-View $_.Datastore[0]).Summary.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 $report += $row } $report
Note1: that this is the view of the "blue" folders. The "Virtual Machines and Templates" view in the VI client.
Note2: the script suppresses the display of the hidden "vm" folder
Blog: lucd.info Twitter: @LucD22 Co-author PowerCLI Reference
Dude, that is awesome. Thanks.
Is it also possible to get the annotations with that.
thanx
Hi LucD,
I am trying to move VMs to their respective folders after deploying from Template, however we have multiple folders by the same name in the Datacenter, hence tried your Get-Folder path..but didnt work for me. Can you help me in this.
I want to move VM like this Datacenter\Folder1\Folder2\Folder3..
Below is the PowerCLI Script I used, I just ran the script in PCLI and tried to ran Get-FolderByPath cmdlet, but it is saying that there is no such cmdlet or function..
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 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
}
}
}
}
}
See my reply (with example) on the other thread where you raised this question.
Blog: lucd.info Twitter: @LucD22 Co-author PowerCLI Reference
Hi LucD,
I also have the same requirement as this thread but I need to list all the datastore where VMs active files are residing, because SimpliVity restore dont support if the active files of the VMs are in multiple folders in same datastore or different datastores. can you help me with this pls.
Is there a way to ignore name of vm in end from output of path please
only <dc>\<parent>\<child>\
currently i am getting <dc>\<parent>\<child>\<VM name>
You mean like this?
$report = @()
Get-View -ViewType VirtualMachine | ForEach-Object -Process {
$row = "" | Select-Object -Property Name, Datastore, Path
$row.Name = $_.Name
$row.Datastore = (Get-View $_.Datastore[0]).Summary.Name
$current = Get-View $_.Parent
$path = ''
do {
$parent = $current
if ($parent.Name -ne "vm") {
if($path -ne ''){
$path = $parent.Name + "\" + $path
}
else {
$path = $parent.Name
}
}
$current = Get-View $current.Parent
} while ($current.Parent -ne $null)
$row.Path = $path
$report += $row
}
$report
Blog: lucd.info Twitter: @LucD22 Co-author PowerCLI Reference
Exactly but only one additional thing i need report for specific vms only in vc
Get-VM -Name $VM | Get-View maybe?
You can use the Filter parameter on Get-View, but remember that it uses a RegEx.
For example
# Name in a variable
Get-View -ViewType VirtualMachine -Filter @{Name=$vm}
# Starting with "VM"
Get-View -ViewType VirtualMachine -Filter @{Name="^VM"}
# Or
Get-View -ViewType VirtualMachine -Filter @{Name="vm1|vm2|vm3"}
Blog: lucd.info Twitter: @LucD22 Co-author PowerCLI Reference
I have been struggling with this for a couple days. We have an environment that uses vCenter Enhanced Linked Mode (linking 4 different vCenters across the country). VMware doesn't ensure uniqueness of the parent value. I have the same "parent" in different vCenters, so the "path" I get ends ups confusing/combining different vCenters. Is there any way to figure out the path when the parent value might be in more than 1 vCenter??
When you make the vCenter part of the path, that should create uniqueness I assume?
Blog: lucd.info Twitter: @LucD22 Co-author PowerCLI Reference