How can I use powerCLI to report on which active directory groups have permissions on a given folder in vCenter Server?
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
Did you try ?
Get-VIPermission -Entity (Get-Folder MyFolder)
Blog: lucd.info Twitter: @LucD22 Co-author PowerCLI Reference
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"
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}}
}
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
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" { <<<<
Fiugred it out, I had spaces in the code and this is what was fouling me up. Thanks for all your help LucD.
Quick questions? From the output, how can I tell what permissions are set at vm folder level or are inherited permissions?
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
I'm able to get the permissions I need as well - thanks LucD
@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.
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
Something like
VMName,Folder,Principal,Permission,PermissionLocation
Yes, that is the format I would prefer to see the data.
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
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.
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
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.
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
Perfect. Thanks so much.
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?