Remove Full Access permissions from shared folders with exceptions - powershell

Basically at my new work we have a shared network area with individual folders for each department. Each folder has multiple sub folders. The problem is the previous manager assigned 'full access' security rights on each folder and subfolder to absolutely everyone, including the 'everyone' group. I'd like to change the 'full access' security permissions for modify, but not for certain security groups like domain admins and certain other security groups.
I have some code in PowerShell that gives me a list of which groups have full access permissions but I need to be able to take that list and change them to modify.
This is what I shamelessly stole and modified from someone else.
$path = "\\srv-shared\sharedfolders"
$ExcludeUsers = 'Domain\Domain Admins',
'NT AUTHORITY\SYSTEM',
'BUILTIN\Administrator',
'domain\Administrator'
# Create regex-pattern to match all excluded users
$ExcludeUsersRegex = ($ExcludeUsers | % { [regex]::Escape($_) }) -join '|'
Get-Childitem $path -Recurse -Directory | ForEach-Object {
$file = $_
Get-Acl -Path $file.FullName |
Select-Object -ExpandProperty Access |
Where-Object {
$_.IdentityReference -notmatch $ExcludeUsersRegex -and
$_.AccessControlType -eq "Allow" -and
$_.FileSystemRights -eq "FullControl"
} | ForEach-Object {
#Foreach ACL
New-Object psobject -Property #{
Path = $file.FullName
ACL = $_.IdentityReference
}
}
} | Select-Object -Property Path, ACL | Export-Csv e:\check_acl.csv -NoTypeInformation
Basically in the #Foreach ACL section i need it to change the full access permission for the group/user its just found and change it to modify instead.

Related

Exclude specific users when listing Windows folder permissions in PowerShell

I'm trying to list all users who have access to a specific directory and the subfolders in this directory.
I've found this website that shows me how to do this pretty well. But I want to modify this script slightly so I can exclude certain built-in Windows users from the output.
So I found another link on StackOverflow that shows how to exclude a list of users from the results. But when I add the -notmatch to the existing PS script, the Group/User changes from the actual username to True or False for some reason.
What can I do to have this script filter out the users in the $ignore variable and have the Group/User show the username?
$ignore = #('BUILTIN\Administrators','CREATOR OWNER')
$ExcludeUsersRegex = ($ignore | % { [regex]::Escape($_) }) -join '|'
$FolderPath = Get-ChildItem -Directory -Path "D:\MSSQL" -Recurse -Force
$Output = #()
ForEach ($Folder in $FolderPath) {
$Acl = Get-Acl -Path $Folder.FullName
ForEach ($Access in $Acl.Access) {
$Properties = [ordered]#{'Folder Name'=$Folder.FullName;'Group/User'=$Access.IdentityReference -notmatch $ExcludeUsersRegex;'Permissions'=$Access.FileSystemRights;'Inherited'=$Access.IsInherited}
#$Properties = [ordered]#{'Folder Name'=$Folder.FullName;'Group/User'=$Access.IdentityReference;'Permissions'=$Access.FileSystemRights;'Inherited'=$Access.IsInherited}
$Output += New-Object -TypeName PSObject -Property $Properties
}
}
$Output | Out-GridView
You can filter at the loop level, so undesirable users aren't iterated through the loop.
ForEach($Access in ($Acl.Access|Where{$_.IdentityReference -notmatch $ExcludeUsersRegex})) {
That filters out the accesses that match a specific user name.

Powershell, Get access rights of shared files, format output?

I have some shared files set up for me for testing purposes, on a Windows Server 2016.
My given task is to get all the users, and their access rights to there shared files/folders.
I get the shared files with
Get-SmbShare | Select-Object -Property Name, Path
What I think I should do, is passing each share's path into
Get-Acl
So I came up with this:
$shares = Get-SmbShare | Where-Object Name -notlike "*$" | Select-Object Name
foreach ($share in $shares){
$path = "\\$env:COMPUTERNAME\" + $share.Name.ToString()
$FolderPath = dir -Directory -Path $path -Recurse -Force
Foreach ($Folder in $FolderPath) {
$Acl = Get-Acl -Path $Folder.FullName
foreach ($Access in $acl.Access)
{
$Folder.FullName;
$Access.IdentityReference;
$Access.FileSystemRights;
$Access.IsInherited
}
}
}
My question is: How could I format this output, so it looks readable, and/or is there a simpler, maybe cleaner to do what I intend to do?

Removing ALL user object permissions form ACL / Folder structure

I want to remove ALL AD User objects from a directory/folder security.
So, this maybe a stupid post and i appologise if it is...but basically i want to recurse through a directoery and remove all user objects from permissions. Folder permissions should be secured using groups, buit occasionally there are user onjects directly being added to folders breaking the rules. I've got a simple little script that works great for specific users, but i'm having trouble setting this to use a variable, eg all domain user accounts. If i specify the $user variable as an AD search for instance it just doesnt work, eg $USER = 'Get-ADuser -filter * -Server 'DOMAIN -properties SamAccountName | Select SamAccountName
I'm assumign this doesnt like the variable field set this way. Any help or advise much appreciated. Thanks.
$filepath = 'C:\Temp\ACLTesting'
$user = 'DOMAIN\USER'
Get-ChildItem $filePath -Recurse -Directory | ForEach-Object {
$acl = Get-Acl -Path $_.FullName
$acl.Access | Where-Object {
$_.IdentityReference.Value -eq $user
} | ForEach-Object {
$acl.RemoveAccessRule($_) | Out-Null
}
Set-Acl -Path $_.FullName -AclObject $acl
}
Unfortunately still cant get this to work using user variables... am i missing something or is this not a possible function? Thanks....
Putting this to one side for now as still cant get it to work and other things have cropped up to look at. Will revisit this at somepoint though. Any suggestions always welcome. Thanks.
Slightly modifying what you posted, try this …
$filepath = 'C:\Temp\ACLTesting'
$DomainUsers = (Get-ADUser -Filter *).SamAccountName
ForEach ($DomainUser in $DomainUsers)
{
Get-ChildItem $filePath -Recurse -Directory |
ForEach-Object {
$acl = Get-Acl -Path $_.FullName
$acl.Access |
Where-Object {
$_.IdentityReference.Value -eq $DomainUser
} |
ForEach-Object {
$acl.RemoveAccessRule($_) | Out-Null
}
Set-Acl -Path $_.FullName -AclObject $acl
}
}

List all folders, where users (except admin) have allow full access

At our company file server we used to have loose permissions several years ago.
Meaning, there are folders where users tend to have full permission. This is a bad thing (user playing with rights, locking out the system (and the backup with it) and only giving themselves access.
My goal:
Scan the fileserver folder by folder (files would be too much) and output
folder full path
Security Identity Reference
if someone has fullaccess besides domain admins or system.
The output would be fine as:
Path, ACL
E:\share\projectfolder, Domain\10JohnDoe
E:\share\commonfolder, Domain\Everyone
...
This is what I have, but it is not nearly enough:
##define variable
$path = "E:\Share"
## begin script
foreach ($file in Get-Childitem $path -Recurse -Directory) {
if (Get-Acl $file.FullName |
select -ExpandProperty Access |
where {$_.IdentityReference -notlike "AT\Domain Admins" -and
$_.IdentityReference -notlike "NT AUTHORITY\SYSTEM" -and
$_.AccessControlType -like "Allow" -and
$_.FileSystemRights -like "FullControl"}
) {
Write-Host $file.FullName >> e:\check_acl.txt
Get-Acl $file.FullName |
select -ExpandProperty Access |
where {$_.IdentityReference -notlike "AT\Domain Admins" -and
$_.IdentityReference -notlike "NT AUTHORITY\SYSTEM" -and
$_.AccessControlType -like "Allow" -and
$_.FileSystemRights -like "FullControl"
} >> e:\check_acl.txt
}
}
But I guess, I cannot get the output (into file!) like that.
Write-Host only displays text to the console, it can't be saved. Get-Acl >> check_acl.txt will write the whole "object" and not just the identityreference. What you want is to create a custom object with a Path and ACL (identityreference)-property and export it to csv.
I've also simplified your identity-exclusion and changed the if-test to a foreach-loop so you don't have to run the whole Get-ACL-line twice.
Try this:
##define variable
$path = "E:\Share"
$ExcludeUsers = 'AT\Domain Admins','NT AUTHORITY\SYSTEM','AT\AT-IT','AT\01STREW','AT\01BRUND','AT\01KNAFP','AT\01BECKC'
## begin script
#Create regex-pattern to match all excluded users
$ExcludeUsersRegex = ($ExcludeUsers | % { [regex]::Escape($_) }) -join '|'
Get-Childitem $path -Recurse -Directory | ForEach-Object {
$file = $_
Get-Acl -Path $file.FullName |
Select-Object -ExpandProperty Access |
Where-Object {$_.IdentityReference -notmatch $ExcludeUsersRegex -and $_.AccessControlType -eq "Allow" -and $_.FileSystemRights -eq "FullControl"} |
ForEach-Object {
#Foreach ACL
New-Object psobject -Property #{
Path = $file.FullName
ACL = $_.IdentityReference
}
}
} | Select-Object -Property Path, ACL | Export-Csv e:\check_acl.csv -NoTypeInformation
Sample output:
"Path","ACL"
"C:\Users\frode\Desktop\TEST\YES","CONTOSO\frode"
"C:\Users\frode\Desktop\TEST\YES","CONTOSO\FrodesOtherAccount"

Recurse a limited amount of folders

I have the following snippet of code from a script, used in order to get the NTFS permissions on file shares.
if ($ComputerName -eq '.'){
$Path = $Folder
}
else {
$Path = "\\$ComputerName\$Folder"
}ls
if ($OutputFile){
Get-Childitem $Path -Recurse:$Recurse | ForEach-Object {Get-Acl $_.FullName} | Select-Object #{Name="Path";Expression={$_.PSPath.Substring($_.PSPath.IndexOf(":")+2) }},#{Name="Type";Expression={$_.GetType()}},Owner -ExpandProperty Access | Export-CSV $OutputFile -NoTypeInformation
}
else{
Get-Childitem $Path -Recurse:$Recurse | ForEach-Object {Get-Acl $_.FullName} | Select-Object #{Name="Path";Expression={$_.PSPath.Substring($_.PSPath.IndexOf(":")+2) }},#{Name="Type";Expression={$_.GetType()}},Owner -ExpandProperty Access | Format-Table -AutoSize
}
At the moment when I run this I am able to generate a report on the NTFS permissions, however I would like to make the code recurse one extra folder deeper in a file share. My problem however is I only know of methods to completely recurse through all folders or get the current folders in a path.
For example assume I had a folder called 'test' and inside of test there were two other folders called 'temp1' and 'temp2', with there being one more folder inside of temp2 called 'extra.' I'd want it to get the NTFS permissions for 'test' and then go one level farther and report permissions for 'temp1' and 'temp2,' but I would not want it to get 'extra.'
EDIT:
if ($OutputFile){
gci c:\|%{if($_.PSIsContainer){GCI $_.FullName|get-acl};$_|get-acl}|Select-Object #{Name="Path";Expression={$_.PSPath.Substring($_.PSPath.IndexOf(":")+2) }},#{Name="Type";Expression={$_.GetType()}},Owner -ExpandProperty Access | sort PSParentPath|Export-CSV $OutputFile -NoType
}
You can manually recurse 1 level easily enough. Try this on for size:
if ($ComputerName -eq '.'){
$Path = $Folder
}
else {
$Path = "\\$ComputerName\$Folder"
}ls
if ($OutputFile){
gci c:\|%{if($_.PSIsContainer){GCI $_.FullName|get-acl};$_|get-acl}|sort PSParentPath|Export-CSV $OutputFile -NoType
}
else{
gci c:\|%{if($_.PSIsContainer){GCI $_.FullName|get-acl};$_|get-acl}|sort PSParentPath|FT -Auto
}
Something like this will go down to a depth of one folder
Get-Childitem $path | %{get-childitem -path $_.fullname}