jpmarquez
(jpmarquez)
1
Hello community
I am a newby here in powershell.
I need to check the specific AD group have and the kind of permissions that this group have on the folders
There are three specific grous in AD, and I want to check that they have the quoted permission
So far the actual script that I have written is:
$outfile = "C:\Users\user\Documents\Script\report.csv"
$header = "FolderPath,AccessControlType,IsInherited"
add-content -Value $header -Path $outfile
if (!(Test-Path H:)){
write-host "Connecting to Network Drive"
New-PSDrive -Name -PSProvider FileSystem -Root "H:\CD"
}else {Write-Host "Connected To Drive"}
$rootpath = "C:\Users\user\Documents\Script\test"
$Folders = dir $RootPath -recurse | where {$_.psiscontainer -eq $true}
foreach ($Folder in $Folders){
$ACLs = get-acl $Folder.fullname | ForEach-Object { $_.Access }
Foreach ($ACL in $ACLs){
$OutInfo = $Folder.Fullname + "," + $ACL.IdentityReference + "," + $ACL.AccessControlType + "," + $ACL.IsInherited + "," + $ACL.InheritanceFlags + "," + $ACL.PropagationFlags
Add-Content -Value $OutInfo -Path $OutFile
}}
Get-Acl C:\Users\user\Documents\Script\test |
select -Expand access | Export-csv C:\Users\jp\Documents\Script\report.csv -NoTypeInformation
However in the out file the only thing that I want to report is the folders that do not comply with the permissions for this AD groups.
It is the first time I am posting here, and I was reluctant becuase I am a novice with powershell, but any help would be very much appreciated!
I hope that I explained myself well.
Thanks in advance!
8 Spice ups
Neally
(Neally)
2
Welcome!
If you post code, please use the ‘Insert Code’ button. Please and thank you!

jitensh
(JitenSh)
3
just playing around
$Groups='domain admins','group 1'
$checks=get-acl C:\scripts | foreach-object{ $_.Access } |select -property @{n="Identity";e={$_.IdentityReference.ToString().Split("\")[1]}}, AccessControlType, FileSystemRights
ForEach($check in $checks){
ForEach($Grp in $groups){
If($Grp -match $($check.identity)){
Write-Host "$($check.identity) has $($check.accesscontroltype) full $($check.filesystemrights)"
}
}
}
jpmarquez
(jpmarquez)
4
So this is what I have got so far
#############################################
# This Script will analyze the folder's permissions on F drive
# It will give a report in a CSV file so that the script executor can see which folder dont have the right permissions
# Any other changes will be reported in the comments of this script
#############################################
# First we need to check if the F drive is mapped in powershell before we start examining the folder's permissions
# We need to create a variable with the path to check; It will be F:\Folder as we need. This can be changed to the desired path we need.
$Path = "F:\Folder"
if(!(Test-path $Path)){
Write-host "$Path will be mapped in powershell";
#We need to map the drive in powershell with New-PSdrive CMDlet.This drive will be mapped during all the time.
New-PSDrive -Name F -PSProvider FileSystem -Root \\Server\Folder -persist
}else{
write-host "The F drive is already mapped in powershell"
}
#Once we have the drive loaded we can proceed to the next part of the script
# We need to check only the folder and subfolders of the CD folder. We will save the informarion in a new variable
$folders = dir $Path -Recurse |where {$_.psiscontainer -eq $true} |select fullname |ft -AutoSize
#After we have done this step, we need to check the permissions of each folder and subfolder that we can find. It can be executed in user permissions
$OutFile = "C:\Users\Documents\Script\Permissions.csv"
$Report = @()
foreach ($folder in $folders){
$ACLs = get-acl -Path $folder.FullName
foreach ($Access in $Acls.access)
{
$OutInfo = [ordered]@{'FolderName,'=$folder.FullName;'ADGroup or User,'= $Access.IdentityReference;'Permissions,'=$Access.FileSystemRights;'Inherited,'=$Access.IsInherited}
$Report += New-Object -TypeName PSObject -Property $OutInfo
Add-Content -Value $Report -Path $OutFile
}
}
So what I am trying to do, instead of giving any particular group, I am trying to export the information into a CSV. Where the script executor will be able to filter those AD group which will not have the right permissions.
I have two questions:
- I am getting this error:
Get-Acl : Cannot validate argument on parameter ‘Path’. The argument is null or empty. Provide an argument that is not null or empty, and then try the command again.
What Am I missing?
- The script creates a CSV but the data is one cell in excel, it is not displayed properly
What should be the proper way to save the information in columns so that a table can be created?
I recognize that I have not been very thorough explainig myself but I will be grateful if anyone could lead me into the right direction.
Thank you
Neally
(Neally)
5
-
$folders = (dir $Path -Recurse |where {$_.psiscontainer -eq $true}).fullname
Does $folders have stuff in it? The ‘ft’ format-table, command breaks things, don’t use it.
jpmarquez
(jpmarquez)
6
That is correct!
I had the FT so I have changed it to:
$folders = Get-ChildItem -Path $Path -recurse
The script now is giving me a CSV file with only the subfolders that do not have inherit permissions.
I have changed the code a bit in the foreach section
ForEach ($item in $folders) {
#Set up progress bar
$i++
$status = "{0:N0}" -f ($i / $tot * 100)
Write-Progress -Activity "Processing Folders" -status "Processing Folder $i of $tot : $status% Completed" -PercentComplete ($i / $tot * 100)
#If the script has an error, the user will need to be aware of the errors. This is the reason why we recur to "Try - Catch"
try {
#All the permissions of each folder will be saved into a new variable by executing get-acl. We added a property so that we only get the permissions of the folder's name
$acl = Get-Acl $item.fullname
#This is the begining of the array, in which each folder's permission will be requested
ForEach ($entry in $acl.access) {
#The condition is in negative because we need to see which folders don't have inherit permissions
If (!$entry.IsInherited) {
#We add the values into the variable and we only select and save the requested porperties
$found += New-Object -TypeName PSObject -Property @{
Folder = $item.fullname
Access = $entry.FileSystemRights
Control = $entry.AccessControlType
User = $entry.IdentityReference
Inheritance = $entry.IsInherited
}
}
}
}
#This is the line that will catch any error that the script may give
catch {
$errors += New-Object -TypeName PSObject -Property @{
Item = $item.fullname
Error = $_.exception
}
}
}
$found |
Select-Object -Property Folder,User,Control,Access,Inheritance |
Export-Csv -NoTypeInformation -Path $out_file
$errors |
Export-Csv -NoTypeInformation -Path $out_error
I will carry on changing the script in order to improve it. But I think I have the main purpose of what I needed to do.
Thank you for the help!
jpmarquez
(jpmarquez)
7
Ok People.
So I have been working a little bit with the Script. I got it working fine.
Here is the code:
[CmdletBinding()]
param(
[String]$Path,
[String]$user,
[String]$permission,
[String]$outfile,
[string]$outerror
)
begin{
Function Get-Folder()
{
param(
[Parameter(Mandatory = $false)]
$initialDirectory,
[Parameter(Mandatory = $True)]
[String]$Title
)
Add-Type -AssemblyName System.windows.forms | Out-Null
$OpenFileDialog = New-Object -TypeName System.Windows.Forms.FolderBrowserDialog
$OpenFileDialog.Description = $Title
$OpenFileDialog.ShowDialog() | Out-Null
$OpenFileDialog.ShowNewFolderButton = $True
#Set-ForegroundWindow -Handle ($OpenFileDialog) -ErrorAction SilentlyContinue | Out-Null
if ($OpenFileDialog.initialDirectory -eq '')
{
Exit
}
$OpenFileDialog.SelectedPath
}
Function Get-FileName()
{
param(
[Parameter(Mandatory = $false)]
$initialDirectory,
[Parameter(Mandatory = $True)]
[String]$Title
)
Add-Type -AssemblyName System.windows.forms | Out-Null
$OpenFileDialog = New-Object -TypeName System.Windows.Forms.SaveFileDialog
$OpenFileDialog.initialDirectory = $initialDirectory
$OpenFileDialog.filter = 'CSV File (*.csv)| *.csv'
$OpenFileDialog.ShowDialog() | Out-Null
$OpenFileDialog.filename
$OpenFileDialog.CheckFileExists = $false
}
$found = @()
$permission = @()
$errors = @()
if(!($Path)){
Write-Host 'Would you like to select a Path? (Default is N)' -ForegroundColor Yellow
$Readhost = Read-Host ' ( y / n ) '
Switch ($Readhost)
{
Y
{
Write-Host 'Please select Path to be audited.'
[String]$Path = Get-Folder -Title 'Select Base Path' | Convert-Path
write-host "`t"
write-host "`t You have selected $Path" -ForegroundColor DarkYellow
write-host "`t"
}
N
{
write-host "`t"
Write-Host 'Default folder will be H:\CD.' -ForegroundColor Yellow
write-host "`t"
$Path = 'H:\CD'
}
Default
{
write-host "`t"
Write-Host 'Default folder is H:\CD.'-ForegroundColor Yellow
write-host "`t"
$Path = 'H:\CD'
}
}
if($Readhost -match 'N' -or 'Default'){
$pathexist = Test-Path -Path 'H:\CD'
if(!$pathexist){
$currentuser = Read-Host "Please type your User Name"
(New-PSDrive -Name H -PSProvider FileSystem -Root \\GBFILE006\DEPT -Credential $currentuser -Persist)
$pathreallyexist = Test-Path -Path 'H:\CD'
if(!$pathreallyexist){
write-host "`t"
Write-Host "Network Drive cannot be loaded" -ForegroundColor Yellow
write-host "`t"
}
else{
write-host "`t"
Write-Host "Network Drive mapped Succesfully" -ForegroundColor Green
write-host "`t"
}
}
else{
write-host "`t"
write-host "Network Drive is already active" -ForegroundColor Green
write-host "`t"
}
}
} else{
write-host "`t"
write-host "The selected path is $Path"
write-host "`t"
}
if(!$user){
write-host "`t"
[String]$user = Read-Host "Input the ADGroup or AD User"
write-host "`t"
write-host "`t Permissions for $user selected" -ForegroundColor green
write-host "`t"
} else{
write-host "`t"
write-host "`t Requested permissions for $user" -ForegroundColor DarkGray
write-host "`t"
}
if(!$permission){
write-host "`t"
[String]$permissions = Read-Host "Please, introduce permission that you want to check"
write-host "`t"
write-host "`t Permissions for $permissions selected" -ForegroundColor green
write-host "`t"
}else{
write-host "`t"
write-host "`t Type of access should be $permissions" -ForegroundColor DarkGray
write-host "`t"
}
if(!$outfile)
{
[string]$outfile = get-FileName -Title 'Choose an output File (CSV)'
write-host "`t"
write-host "`t If incompatibilites are found, the file will be saved in $outfile" -ForegroundColor Green
write-host "`t"
}
else{
write-host "`t"
write-host "`t If incompatibilites are found, the file will be saved in $outfile" -ForegroundColor Green
write-host "`t"
}
}
process{
}
end{
# We need to check only the folder and subfolders of the CD folder. We will save the informarion in a new variable
#We will set a progress bar variables
$folders = Get-ChildItem $Path -recurse -force -ErrorAction SilentlyContinue
$t=0
$total = $folders.count
$folders |Foreach-object {
sleep -Milliseconds 50
$t++
Write-Progress -Id 1 -Activity Updating -Status 'Collecting Folders' -PercentComplete ($t/$total *100) -CurrentOperation 'Storing'
}
#After we have done this step, we need to check the permissions of each folder and subfolder that we can find. It can be executed in user permissions
#An empty array will be saved in the following variables
$i=0
$tot = $folders.count
#This will create an array for each folder that will be found in the directory tree.
ForEach ($item in $folders) {
#Set up progress bar
$i++
$status = "{0:N0}" -f ($i / $tot *100)
Write-Progress -Activity "Processing Folders" -status "Processing Folder $i of $tot : $status% Completed" -PercentComplete ($i / $tot *100)
#If the script has an error, the user will need to be aware of the errors. This is the reason why we recur to "Try - Catch"
try {
#All the permissions of each folder will be saved into a new variable by executing get-acl. We added a property so that we only get the permissions of the folder's name
$acl = get-childitem $item.FullName -ErrorAction SilentlyContinue | get-acl
#This is the begining of the array, in which each folder's permission will be requested
ForEach ($entry in $acl.access) {
#The condition is in negative because we need to see which folders don't have inherit permissions
If (!$entry.IsInherited){
if ($entry.IdentityReference -match $user){
#We add the values into the variable and we only select and save the requested porperties
$found += New-Object -TypeName PSObject -Property @{
Folder = $item.fullname
Access = $entry.FileSystemRights
Control = $entry.AccessControlType
User = $entry.IdentityReference
Inheritance = $entry.IsInherited}
}
}
}
}
#This is the line that will catch any error that the script may give
catch {
$errors += New-Object -TypeName PSObject -Property @{
Item = $item.fullname
Error = $_.exception
}
}
}
if($found.Length -eq 0){
write-host "`t"
write-host "`t No incompatibilites were reported. No file was created" -ForegroundColor Green
write-host "`t"
}
else{
$found | Select-Object -Property Folder,User,Control,Access,Inheritance | Export-Csv -NoTypeInformation -Path $outfile -ErrorAction SilentlyContinue
write-host "`t"
write-host "`t The script was executed correctly and it has been saved in $outfile" -ForegroundColor Green
write-host "`t"
}
if($errors.Length -eq 0){
write-host "`t"
write-host "`t No errors were reported" -ForegroundColor Green
write-host "`t"
}
else{
$errors | Export-Csv -NoTypeInformation -Path $outerror -ErrorAction SilentlyContinue
[string]$outerror = get-FileName -Title 'Choose an Error output File (CSV)'
write-host "`t"
write-host "`t The error has been saved in $outerror" -ForegroundColor Yellow
write-host "`t"
}
#If the output is an error when the script is executed, it will be saves on the following Variable
}
So the script will be executed in a specific folder that I selected previously. However, if the user wants to choose another path, a window form will open.
It will only create a report file if the script genereted something.
I still need to debug some aspects, but I got it working.
What I want to do next is using the paremeter $permissions so thatthe script only gives a report of those files or folders that do not match the permission given (Read, write and so on)
I will try to figure it out. Any help would be great too!
Thank you