Powershell for adding permissions to folders without inheritance - powershell

We have a giant folder located at "D:\Economy" with hundreds of subfolders. We have a new employee which needs permissions for ALL those folders. Unfortunately there are alot of folders without inheritance, so when I add permissions on D:\Economy\ it doesnt apply to all folders.
Ive found many scrips which lists all the folders, but I can't figure out how to also apply permissions to them.
For instance, this command works for finding folders:
DIR "D:\Economy" -directory -recurse | GET-ACL | where {$_.Access.IsInherited -eq $false}
This command works for setting permissions, but it only applies to those with inheritance enabled:
path = "D:\Economy\"
$acl = Get-Acl $path
$AccessRule = New-Object System.Security.AccessControl.FileSystemAccessRule("MYCOMPANY\firstname.surname","Modify","Allow")
$acl.SetAccessRule($AccessRule)
$acl | Set-Acl $path
So how do I merge those together?
This is something I wrote up but it doesnt work:
$AccessRule = New-Object System.Security.AccessControl.FileSystemAccessRule("MYCOMPANY\firstname.surname","Modify","Allow")
$acl.SetAccessRule($AccessRule)
dir "D:\Economy\" -Directory -recurse | get-acl | Where {$_.AreAccessRulesProtected} | set-acl "D:\Economy\"

$AccessRule = New-Object System.Security.AccessControl.FileSystemAccessRule("MYCOMPANY\firstname.surname","Modify","Allow")
Get-ChildItem "D:\Economy\" -Directory -Recurse | %{
$acl = Get-Acl -Path $_.FullName
if ($acl.AreAccessRulesProtected) {
$acl.AddAccessRule($AccessRule)
$acl | Set-Acl -Path $_.FullName
}
}

Related

Shared file area - how can I improve my PowerShell script?

I am trying to make a script that creates file areas for different groups in a company. All the members in the group need to have full access to the shared files, but any member from the other groups can not have access - not even see them. This is what I have. For the "Limit access" section you need to change up the name of the group, and repeat this for each group. Can I put this in a foreach loop?
I am new to Powershell and really want to learn how to improve my script. So how can I improve and automate this code?
# Creates file areas
$folders = ('C:\shares\it-drift','C:\shares\dev-team','C:\shares\regnskap','C:\shares\renhold','C:\shares\HR')
mkdir -path $folders
$folders | Where-Object {$_ -like "*shares*"} | ForEach-Object {$name = (Get-Item $_).name; $DfsPath = (‘\\sec.core\files\’ + $name); $targetPath = (‘\\dc1\’ + $name);New-DfsnFolderTarget -Path $dfsPath -TargetPath $targetPath}
# Limits access
$folder = ('C:\shares\dev-team')
$ACL = Get-Acl -path \\sec.core\files\dev-team
$AccessRule = New-Object System.Security.AccessControl.FileSystemAccessRule("sec.core\g_dev_team","FullControl","Allow")
$ACL.SetAccessRule($AccessRule)
$ACL | Set-Acl -Path "\\sec.core\files\dev-team"
$ACL.SetAccessRuleProtection($true,$true)
$ACL = Get-Acl "\\sec.core\files\dev-team"
$ACL.Access | where {$_.IdentityReference -eq "BUILTIN\Users" } | foreach { $acl.RemoveAccessRuleSpecific($_) }
Set-Acl "\\sec.core\files\dev-team" $acl
(Get-ACL -Path "\\sec.core\files\dev-team").Access | Format-Table IdentityReference,FileSystemRights,AccessControlType,IsInherited,InheritanceFlags -AutoSize
Appreciate all tips:)
Here is how you can automate set of the same ACL for each shared folder:
# Creates file areas
$folders = #(
'C:\shares\it-drift'
'C:\shares\dev-team'
'C:\shares\regnskap'
'C:\shares\renhold'
'C:\shares\HR'
)
mkdir -path $folders
$folders | Where-Object {$_ -like "*shares*"} |
ForEach-Object {
$name = (Get-Item $_).name
$DfsPath = '\\sec.core\files\' + $name
$targetPath = '\\dc1\' + $name
New-DfsnFolderTarget -Path $dfsPath -TargetPath $targetPath
}
# Limits access
foreach($folder in $folders)
{
$leaf = Split-Path $folder -Leaf
$path="\\sec.core\files\$leaf"
$acl = Get-Acl -Path $path
$AccessRule = New-Object System.Security.AccessControl.FileSystemAccessRule("sec.core\g_dev_team","FullControl","Allow")
$acl.SetAccessRule($AccessRule)
Set-Acl -Path $path -AclObject $acl
$acl.SetAccessRuleProtection($true,$true)
$acl = Get-Acl "\\sec.core\files\dev-team"
$acl.Access.where({$_.IdentityReference -eq "BUILTIN\Users"}).foreach({
$acl.RemoveAccessRuleSpecific($_)
})
Set-Acl -Path $path -AclObject $acl
(Get-ACL -Path $path).Access |
Format-Table IdentityReference,FileSystemRights,AccessControlType,IsInherited,InheritanceFlags -AutoSize
}
Try to use vertical coding instead of horizontal coding. People reading your code will be thankful.

Remove NTFS permissions of a user in all sub-directories

I am writing a PowerShell script which would delete a specific user from all sub-directories.
Below script only removes the permission from the folder but I want to remove permission from all sub-folders as well.
$acl = get-acl c:\temp
$accessrule = New-Object System.Security.AccessControl.FileSystemAccessRule ("domain\user","Read",,,"Allow")
$acl.RemoveAccessRuleAll($accessrule)
Set-Acl -Path "c:\temp" -AclObject $acl
You are only setting the acl of the root folder. Set-Acl by itself does not allow you to propagate to subfolders.
Note that that might not be what you want anyway. You want to remove a rule from all folders instead of replacing the acls on all subfolders with the acl of your root folder.
Safer would be to get the acl of each subfolder, remove the rule and set the acl of each subfolder.
icaclscudo's to Ansgar might be better for this task. A Powershell way might be as follows
$accessrule = New-Object system.security.AccessControl.FileSystemAccessRule("domain\user","Read",,,"Allow")
$root = 'c:\temp'
#(Get-Item $root) + #(Get-ChildItem $root -Recurse -Directory) | Foreach-Object {
$acl = Get-Acl $_.FullName
$acl.RemoveAccessRuleAll($accessrule)
Set-Acl $_.FullName -AclObject $acl -WhatIf
}
$Path = "c:\temp\"
$User = "admin"
$Account = new-object system.security.principal.ntaccount($User)
$ACL = Get-Acl -path $Path
$ACL.PurgeAccessRules($Account)
$ACL | Set-Acl -path $Path -Verbose
gci -Recurse -Path $Path -Directory | %{
$ACL = Get-Acl -path $_.FullName
$ACL.PurgeAccessRules($Account)
$ACL | Set-Acl -path $_.FullName -Verbose
}

How to add two acces rules to folder for same group using powershell

I need a group to not be able to modify(/delete) a root folder but the same group has to be able to modify all the subfolders and files, using powershell (repetition/volume)
nb. end result should be two acl rules:
1. one for the current folder (readonly, can make subfolders , can delete subfolders but cannot delete root folder).
2. a second rule for the subfolders and files, in which they can delete and create and have free range over
I have a series of powershell codes that adds the ACL rule for both situations (seperately)
#subfolder rights
$existingAcl = Get-Acl -Path $pad
$permissions = $rechtendoel,'ExecuteFile,ReadData,ReadAttributes,ReadExtendedAttributes,CreateFiles,AppendData,WriteAttributes,WriteExtendedAttributes,DeleteSubdirectoriesAndFiles,Delete,ReadPermissions', 'ContainerInherit,ObjectInherit', 'InheritOnly', 'Allow'
$regel= New-Object -TypeName System.Security.AccessControl.FileSystemAccessRule -ArgumentList $permissions
$existingAcl.SetAccessRule($regel)
$existingAcl | Set-Acl -Path $pad
#rights for just the folder
$existingAcl2 = Get-Acl -Path $pad
$rechten2 = $rechtendoel,'ExecuteFile,ReadData,ReadAttributes,ReadExtendedAttributes,CreateFiles,AppendData,WriteAttributes,WriteExtendedAttributes,DeleteSubdirectoriesAndFiles,ReadPermissions', 'None', 'None', 'Allow'
$regel2= New-Object -TypeName System.Security.AccessControl.FileSystemAccessRule -ArgumentList $rechten2
$existingAcl2.SetAccessRule($regel2)
$existingAcl2 | Set-Acl -Path $pad
However when I run both in succession (or seperate from eachother) the latter run segment overwrites the earlier rule.
Try using this type of method for items in sub-directories
$NewAcl = Get-Acl File0.txt
Get-ChildItem -Path "C:\temp" -Recurse -Include "*.txt" -Force | Set-Acl -AclObject $NewAcl
Reference
https://learn.microsoft.com/en-us/powershell/module/microsoft.powershell.security/set-acl?view=powershell-6

Powershell: Apply owner to multiple files and folders per username

We have a server that houses the My Documents folder for all our users. Some of the folder owner changed to administrator. I am trying to devise a PowerShell script that goes to each user's root my documents folder and applies the user as the owner for all the sub folders and files with in it. Is this Possible?
I have the following from a previous script that attempted to set the user as full permissions per each my document root folder:
$FolderPath = "E:\mydocuredir\"
$MyDocsMain = Get-ChildItem -Path $FolderPath -Directory
Get-ChildItem -Path $FolderPath -Directory | ForEach-Object{
$HomeFolders = Get-ChildItem $FolderPath $_.Name -Directory
$Path = $HomeFolders.FullName
$Acl = (Get-Item $Path).GetAccessControl('Access')
$Username = $_.Name
$Ar = New-Object System.Security.AccessControl.FileSystemAccessRule($Username, 'FullControl', 'ObjectInherit', 'InheritOnly', 'Allow')
$Acl.SetAccessRule($Ar)
Set-Acl -path $Path -AclObject $Acl
}
Firstly ensure that the share and root folder permissions for redirected folders follow best practice.
I would use the NTFSSecurity PS Module (blog on its use). This module has commands that are much easier to understand as they follow they way your would set permissions via the GUI.
$FolderPath = "E:\mydocuredir"
Get-ChildItem -Path $FolderPath -Directory | ForEach-Object{
Add-NTFSAccess -Path $_.FullName -Account "domain\$($_.Name)" -AccessRights FullControl -AppliesTo ThisFolderSubfoldersAndFiles
}
To set Owner, replace the Add-NTFSAccess command with:
Set-NTFSOwner -Path $_.FullName -Account "domain\$($_.Name)"

Export/import ACL using csv

I want to export in a csv file the ACL of every subfolder starting from a root folder and then to import them of mirroring folders on another computer.
I'm using this code to export from C:\Users\user\Desktop\a :
Get-ChildItem "C:\Users\user\Desktop\a" -Recurse | ?{ $_.PsIsContainer } | %{
$Path = $_.FullName
# Exclude inherited rights from the report
(Get-Acl $Path).Access | ?{ !$_.IsInherited } | Select-Object `
#{n='Path';e={ $Path }}, IdentityReference, AccessControlType, `
InheritanceFlags, PropagationFlags, FileSystemRights
} | Export-CSV "C:\Users\user\Desktop\Permissions.csv"
and this code to import ACL:
$par = Import-Csv -Path "C:\Users\user\Desktop\Permissions.csv"
foreach ( $i in $par ) {
$path= $i.Path
$IdentityReference= $i.IdentityReference
$AccessControlType=$i.AccessControlType
$InheritanceFlags= $i.InheritanceFlags
$PropagationFlags=$i.PropagationFlags
$FileSystemRights=$i.FileSystemRights
echo $path $IdentityReference
$acl = Get-Acl C:\Users\user\Desktop
$permission = $i.IdentityReference,$i.FileSystemRights,$i.AccessControlType
$accessRule = new-object System.Security.AccessControl.FileSystemAccessRule $permission
$acl.SetAccessRule($accessRule)
$acl | Set-Acl $path
}
Permissions.csv is something like this:
#TYPE Selected.System.Security.AccessControl.FileSystemAccessRule
"Path","IdentityReference","AccessControlType","InheritanceFlags","PropagationFlags","FileSystemRights"
"C:\Users\user\Desktop\a\b","DITOADMIN\pluto","Allow","None","None","ReadAndExecute, Synchronize"
"C:\Users\user\Desktop\a\b\c","DITOADMIN\pluto","Allow","ContainerInherit, ObjectInherit","None","ReadAndExecute, Synchronize"
"C:\Users\user\Desktop\a\b\c","DITOADMIN\admin","Allow","None","None","FullControl"
"C:\Users\user\Desktop\a\b\c","DITOADMIN\pippo","Allow","ContainerInherit, ObjectInherit","None","ReadAndExecute, Synchronize"
unfortunately, import action doesn't work since only last permission is imported (so only for pippo user and not for pluto).
anybody knows why?
I've fixed it.
the problem was the line, the path I use here was wrong (should be the path from the CSV import)
$acl = Get-Acl C:\Users\user\Desktop
$permission = $i.IdentityReference,$i.FileSystemRights,$i.AccessControlType
I've changed with
$acl = Get-Acl $path
$permission = $IdentityReference, $FileSystemRights, $InheritanceFlags, $PropagationFlags, $AccessControlType
bye
It's almost perfect. Here you add the permission from the CSV to the folder, but you keep the old permission on it. You dont "reset/copy" the ACL from one folder to the other.
So instead of getting the ACL of the receiving folder:
$acl = Get-Acl $path
Ive create a new one:
$acl = New-Object System.Security.AccessControl.DirectorySecurity
But then, i lose the Owner attribute. So i need a way to export the owner in the CSV with the rights..