I am trying to export the path of all folders in a top level folder and the AD groups plus the Members of that AD group. I have got the following script which is able to get all that information but having trouble trying to export it into a nicely formatted CSV
enter code here
$filepath='\\server1\folderA'
$Version=$PSVersionTable.PSVersion
if ($Version.Major -lt 3) {Throw "Powershell version out of date. Please update powershell." }
#Create an empty hashtable to track groups
$ADGroups = @{}
#Get a recursive list of folders and loop through them
ForEach($Folder in (Get-ChildItem $filePath -Directory)){
# Get ACLs for the folder
$ACLs = Get-Acl -Path $Folder.FullName
#Do a bunch of filtering to just get AD groups
$Groups = $ACLs |
% Access | #Expand the Access property
where { $_.IsInherited -eq $false -and $_.AccessControlType -eq 'Allow' -and $_.IdentityReference -notmatch 'BUILTIN|NT AUTHORITY|CREATOR|-----|Identity'} | #Only instances that allow access, are not inherited, and aren't a local group or special case
%{$_.IdentityReference -replace 'JAC.*?\\'} | #Expand the IdentityReference property, and replace anything that starts with JAC all the way to the first backslash (likely domain name trimming)
Select -Unique #Select only unique values
#If there are no groups to display for this folder move to the next folder
If($Groups.Count -eq 0){Continue}
#Display Folder Path
$Folder.FullName
#Put a dashed line under the folder path (using the length of the folder path for the length of the line, just to look nice)
'-'*$Folder.FullName.Length
#Loop through each group and display its name and users
ForEach ($Group in $Groups){
#Display the group name
$Group
#repmoves the domain\ from the ad group
$groupname = $group -creplace '(?s)^.*\\', ''
#Add a line under the group name
'-'*$Groupname.Length
#Check if we already have this group, and if not get the group from AD
If($ADGroups.Keys -notcontains $Groupname){
$Members = Get-ADGroupMember $Groupname | select Name
}
#Display the group members
$Members
}
#output a blank line, for some seperation between folders
"`n"
}
Ideally just need to export
Folder path which is the variable $folder.fullname and the variable $members
I ran this against one of my own shared directories to see exactly what it does, so I can at least see the information you're working with.
In a CSV, you have column headings, and then you have rows under those headings. The information you're gathering with this script is: Folder Name; Groups with access; members of those groups. This means that every line of your CSV will contain this information. The last part of your question indicates that you're just looking for the usernames that have access to the folders. However, for the sake of completeness, I've included all three groups in the output below. In the code below, where it starts $results +=, you can delete the line 'group=$group' if you don't need that information. However, when you look at the CSV, I believe you'll find the information beneficial.
In order to get all of the information into a decent format you'll need to store it in a variable. I recommend creating a custom object that can then be exported. I've used your code below and added the key elements for this. The new lines are noted with three hashes in a row - ###. I've also made a few formatting changes to match my own coding practices - hopefully, it will be easier to see where the various loops are so that you can see how I'm gathering the data into the variable. Let me know if this captures the data you're expecting.
$filepath='\\server\folder'
### New variable called results. This is what will store the custom object.
$results = @()
$Version=$PSVersionTable.PSVersion
if ($Version.Major -lt 3) {Throw "Powershell version out of date. Please update powershell." }
#Create an empty hashtable to track groups
$ADGroups = @()
#Get a recursive list of folders and loop through them
ForEach ($Folder in (Get-ChildItem $filePath -Directory))
{
# Get ACLs for the folder
$ACLs = Get-Acl -Path $Folder.FullName
#Do a bunch of filtering to just get AD groups
#$acls.Access
$Groups = $ACLs |
% Access | #Expand the Access property
where { $_.IsInherited -eq $false -and $_.AccessControlType -eq 'Allow' -and $_.IdentityReference -notmatch 'BUILTIN|NT AUTHORITY|CREATOR|-----|Identity'} | #Only instances that allow access, are not inherited, and aren't a local group or special case
%{$_.IdentityReference -replace 'JAC.*?\\'} | #Expand the IdentityReference property, and replace anything that starts with JAC all the way to the first backslash (likely domain name trimming)
Select -Unique #Select only unique values
#If there are no groups to display for this folder move to the next folder
If($Groups.Count -eq 0){Continue}
#Display Folder Path
$Folder.FullName
#Put a dashed line under the folder path (using the length of the folder path for the length of the line, just to look nice)
'-'*$Folder.FullName.Length
#Loop through each group and display its name and users
ForEach ($Group in $Groups)
{
#Display the group name
$Group
#repmoves the domain\ from the ad group
$groupname = $group -creplace '(?s)^.*\\', ''
#Add a line under the group name
'-'*$Groupname.Length
#Edited post to include this IF statement
#Now that we have the group name, here is where we want to filter out group names
#that we don't want to have
If ($groupname -notlike "*_R" -and $groupname -notlike "*Bambi*")
{
#Check if we already have this group, and if not get the group from AD
If($ADGroups.Keys -notcontains $Groupname)
{
$Members = Get-ADGroupMember $Groupname | select Name
### This is a new foreach loop. This will allow us to easily store each individual member in our results variable
foreach ($Member in $Members)
{
### This is where we are going to store our variable
$results += [pscustomobject]@{
folder = $folder.FullName
group = $Group
name = $member.Name
}
}
}
#Display the group members
$Members
}
}
#output a blank line, for some seperation between folders
"`n"
}
### Now we can export the results
$Results | export-csv "C:\somefolder\filename.csv" -NoTypeInformation