VMware Cloud Community
TheVMinator
Expert
Expert
Jump to solution

Reporting on Folder Permissions

How can I use powerCLI to report on which active directory groups have permissions on a given folder in vCenter Server?

0 Kudos
1 Solution

Accepted Solutions
LucD
Leadership
Leadership
Jump to solution

The following script sort of combines the previous 2 scripts.

It will print the permissions that are applicable on virtual machines and templates.

But that can easily be extended to do the same thing for datacenters and folders. Just call the get-permissions function also for folders and datacenters.

function get-permissions($vm){
    $vmImpl = Get-VM -Name $vm -ErrorAction SilentlyContinue
   
if($vmImpl){         Get-VIPermission -Entity $vmImpl | %{             Write-Host "`t" $_.Role $_.Principal $_.Entity $_.Propagate         }     }     else{         $templImpl = Get-Template -Name $vm -ErrorAction SilentlyCOntinue
        if($templImpl){             Get-VIPermission -Entity $templImpl | %{                 Write-Host "`t" $_.Role $_.Principal $_.Entity $_.Propagate             }         }     } } function get-children-reverse($entity,$path) {     if($entity.Name -ne "vm"){         $path = $path + "\" + $entity.Name     }     foreach($child in $entity.ChildEntity){         $childfld = Get-View -Id $child
       
switch($childfld.gettype().name){             "Folder" {                 Write-Host ($path + "\" + $childfld.Name)                 get-children-reverse $childfld $path
            }            
"VirtualMachine"{                 $vm = $path + "\" + $childfld.Name                 Write-Host $vm
               
get-permissions $childfld.Name             }             "Datacenter"{                 Write-Host ($path + "\" + $childfld.Name)                 get-children-reverse $childfld $path
            }            
"ClusterComputeResource" {                 Write-Host ($path + "\" + $childfld.Name)                 foreach($esxMoRef in $childfld.Host){                     $esx = Get-View -Id $esxMorEF
                   
$h = $esx.Name+ "\" + $path + "\" + $childfld.Name                     Write-Host $h
                }             }         }     } } Get-Datacenter | %{     $dc = Get-View -Id ($_).id     $folder = Get-View -Id $dc.VmFolder     get-children-reverse $folder $dc.Name }

The script dumps all output to the screen.

If you need this in another format, just let me know.


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

View solution in original post

21 Replies
LucD
Leadership
Leadership
Jump to solution

Did you try ?

Get-VIPermission -Entity (Get-Folder MyFolder)


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

chaos007m
Contributor
Contributor
Jump to solution

I have copied this script from a previous thread of yours.  I'm new to power shell scripting so please fogive me if you have already answered this on a another thread, I have been tasked with trying to gather all folders and subfolder along with permissions assigned for each folder as well as export to csv file in the following format if possible.

folder name or Parent or Subfolder:    VM machine name:    Permissions: DataCenter:

>>>>>>>>>>>>>>>>>>>>>>>>>>>

connect-viserver servername

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

}

Export-Csv

"c:\Temp\vmfolder.csv"

0 Kudos
chaos007m
Contributor
Contributor
Jump to solution

I have also tried to use the following code which is just a s fine, but does not give me the VM's within each folder. How do I merge the two outputs together.

Function

Get-Path($entity){

$path = $entity.Name

while($entity.Parent -ne $null){

$entity = Get-View -Id $entity.Parent

if($entity.Name -ne "vm" -and $entity.Name -ne "host"){

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

}

}

$path

}

$si

= Get-View ServiceInstance

$am

= Get-View $si.Content.AuthorizationManager

$roleList

= $am.RoleList

# Create the role map

$roleMap

= @{}

# Add the roles to the map

foreach

($role in $roleList)

{

$roleMap[$role.RoleId] = $role

}

$permissions

= $am.RetrieveAllPermissions()

# Foreach permission

foreach

($permission in $permissions)

{

$roleName = $roleMap[$permission.RoleId].Name

$entityView = Get-View $permission.Entity

$permission | Select-Object @{Name="Principal"; Expression={$permission.Principal}},

@{Name

="RoleName"; Expression={$roleName}},

@{Name

="Object"; Expression={Get-Path $entityView}}

}

0 Kudos
LucD
Leadership
Leadership
Jump to solution

The following script sort of combines the previous 2 scripts.

It will print the permissions that are applicable on virtual machines and templates.

But that can easily be extended to do the same thing for datacenters and folders. Just call the get-permissions function also for folders and datacenters.

function get-permissions($vm){
    $vmImpl = Get-VM -Name $vm -ErrorAction SilentlyContinue
   
if($vmImpl){         Get-VIPermission -Entity $vmImpl | %{             Write-Host "`t" $_.Role $_.Principal $_.Entity $_.Propagate         }     }     else{         $templImpl = Get-Template -Name $vm -ErrorAction SilentlyCOntinue
        if($templImpl){             Get-VIPermission -Entity $templImpl | %{                 Write-Host "`t" $_.Role $_.Principal $_.Entity $_.Propagate             }         }     } } function get-children-reverse($entity,$path) {     if($entity.Name -ne "vm"){         $path = $path + "\" + $entity.Name     }     foreach($child in $entity.ChildEntity){         $childfld = Get-View -Id $child
       
switch($childfld.gettype().name){             "Folder" {                 Write-Host ($path + "\" + $childfld.Name)                 get-children-reverse $childfld $path
            }            
"VirtualMachine"{                 $vm = $path + "\" + $childfld.Name                 Write-Host $vm
               
get-permissions $childfld.Name             }             "Datacenter"{                 Write-Host ($path + "\" + $childfld.Name)                 get-children-reverse $childfld $path
            }            
"ClusterComputeResource" {                 Write-Host ($path + "\" + $childfld.Name)                 foreach($esxMoRef in $childfld.Host){                     $esx = Get-View -Id $esxMorEF
                   
$h = $esx.Name+ "\" + $path + "\" + $childfld.Name                     Write-Host $h
                }             }         }     } } Get-Datacenter | %{     $dc = Get-View -Id ($_).id     $folder = Get-View -Id $dc.VmFolder     get-children-reverse $folder $dc.Name }

The script dumps all output to the screen.

If you need this in another format, just let me know.


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

chaos007m
Contributor
Contributor
Jump to solution

Thanks for the assistance, however I'm receiving the following error when executing your latest script. What am I doing wrong? Also would like to have the script dump what it sees on the scren to csv file, so that we can use to refference when importing the next script.

Unexpected token '{' in expression or statement.

At :line:25 char:23

+ "Folder" { <<<<

0 Kudos
chaos007m
Contributor
Contributor
Jump to solution

Fiugred it out, I had spaces in the code and this is what was fouling me up. Thanks for all your help LucD.

0 Kudos
chaos007m
Contributor
Contributor
Jump to solution

Quick questions? From the output, how can I tell what permissions are set at vm folder level or are inherited permissions?

0 Kudos
LucD
Leadership
Leadership
Jump to solution

On the permissions output lines, the fourth value, from the $_.Propagate property, shows if the permission is inherited ($true) or not ($false).


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

TheVMinator
Expert
Expert
Jump to solution

I'm able to get the permissions I need as well - thanks LucD

0 Kudos
nealsped
Contributor
Contributor
Jump to solution

@LucD I know this is an old post, but I recently discovered it and it worked great to provide me the folders and permissions. I'm trying to export this to .csv or .xlsx.  Can you provide me some guidance on how to alter the script to export? Thanks.

0 Kudos
LucD
Leadership
Leadership
Jump to solution

This indeed very old, and not in the style I would write such a script.
I would definitely not use Write-Host.

What exactly do you want to see in the CSV.
Remember in a CSV each row has to have the same number of columns, although can be empty.

Something like 

VMName,Folder,Principal,Permission,PermissionLocation


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

0 Kudos
nealsped
Contributor
Contributor
Jump to solution

Something like 

VMName,Folder,Principal,Permission,PermissionLocation

 

Yes, that is the format I would prefer to see the data.

0 Kudos
LucD
Leadership
Leadership
Jump to solution

You could do something like this

Function Get-VMFolder{
  [CmdletBinding()]
  param(
    [VMware.VimAutomation.ViCore.Types.V1.Inventory.VirtualMachine]$VM
  )

  $path = $vm.Folder.Name
  $obj = $vm.Folder
  while($obj.Parent -ne $null){
    $path = $obj.Parent.Name,$path -join '/'
    $obj = $obj.Parent
  }
  $path.Replace('/vm','')
}

Get-VM -PipelineVariable vm |
foreach-object -process {
  Get-VIPermission -Entity $vm |
  ForEach-Object -Process {
    New-Object -TypeName PSObject -Property ([ordered]@{
      VMName = $vm.Name
      Folder = Get-VMFolder -VM $vm
      Principal = $_.Principal
      Permission = $_.Role
      PermissionLOcation = $_.Entity.Name
    })
  }
} | Export-Csv -Path .\report.csv -NoTypeInformation -UseCulture


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

0 Kudos
nealsped
Contributor
Contributor
Jump to solution


while($obj.Parent -ne $null){
    $path = $obj.Parent.Name,$path -join '/'
    $obj = $obj.Parent
  }
  $path.Replace('/vm','')
}

 I got an error multiple times on this $path.Replace line. Error: You cannot call a method on a null-valued expression.

I let it keep running despite the error and after 20 times of error it stopped and it appeared the script was still running. Checked file size and the file size was growing so I let it run.  Could the error be due to the VMs that were in the root folder? The number of objects in the root folder seemed to correlate with the number of errors.

0 Kudos
LucD
Leadership
Leadership
Jump to solution

I tested  with VMs in the root folder, so not sure where the error is coming from.

You can run the script for 1 or more VMs by just changing the 

Get-VM -PipelineVariable vm |

line to for example

Get-VM -Name MyVM -PipelineVariable vm |


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

0 Kudos
wolfmoonct
Contributor
Contributor
Jump to solution



 

Function Get-VMFolder{
  [CmdletBinding()]
  param(
    [VMware.VimAutomation.ViCore.Types.V1.Inventory.VirtualMachine]$VM
  )

  $path = $vm.Folder.Name
  $obj = $vm.Folder
  while($obj.Parent -ne $null){
    $path = $obj.Parent.Name,$path -join '/'
    $obj = $obj.Parent
  }
  $path.Replace('/vm','')
}

Get-VM -PipelineVariable vm |
foreach-object -process {
  Get-VIPermission -Entity $vm |
  ForEach-Object -Process {
    New-Object -TypeName PSObject -Property ([ordered]@{
      VMName = $vm.Name
      Folder = Get-VMFolder -VM $vm
      Principal = $_.Principal
      Permission = $_.Role
      PermissionLOcation = $_.Entity.Name
    })
  }
} | Export-Csv -Path .\report.csv -NoTypeInformation -UseCulture

 





I have no scripting experince, but how would I modify this script to only get folder permissions..  so someone wants the permissions for folder and all the subfolders.

0 Kudos
LucD
Leadership
Leadership
Jump to solution

Something like this?

Function Get-FolderPath {
  [CmdletBinding()]
  param(
    [VMware.VimAutomation.ViCore.Types.V1.Inventory.Folder]$Folder
  )

  $path = $Folder.Name
  $obj = $Folder
  while ($obj.Parent -ne $null) {
    $path = $obj.Parent.Name, $path -join '/'
    $obj = $obj.Parent
  }
  $path.Replace('/vm', '')
}

Get-Folder -Type VM -PipelineVariable vmfolder |
ForEach-Object -Process {
  Get-VIPermission -Entity $vmfolder |
  ForEach-Object -Process {
    New-Object -TypeName PSObject -Property ([ordered]@{
      Folder = Get-FolderPath -Folder $vmfolder
      Principal = $_.Principal
      Role = $_.Role
      PermissionLocation = $_.Entity.Name
    })
  }
}


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

0 Kudos
wolfmoonct
Contributor
Contributor
Jump to solution

Perfect.  Thanks so much.

0 Kudos
summer2021
Contributor
Contributor
Jump to solution

Hi LucD

We have global sites in one vCenter. Each site is with its folder (country) and datacenter (site) names. We have different AD groups with all onsite support guys at respective countries being a part of it. We want to set same set of limited permissions to these different AD groups for each folder. How can we do it via script?

0 Kudos