I am currently using the following script to export the permissions, take ownership of a folder and then remove all permissions from that folder. The folder list is taken from a text file.
$InputFile = "C:\temp\Folders.txt"
$OutputFile = "C:\temp\FolderPermissions.txt"
$FolderList = Get-Content $InputFile
foreach ($Folder in $FolderList) {
Get-Acl $folder | Format-List >>$OutputFile
$acl = Get-ACL -Path $folder
$acl.SetAccessRuleProtection($True, $True)
Set-Acl -Path $folder -AclObject $acl
$ACL = Get-ACL -Path $Folder
$Rules = $ACL.Access | Where-Object {$_.IdentityReference -notmatch 'Admin'}
foreach ($Rule in $Rules) {
[void]$ACL.RemoveAccessRule($Rule)
}
Set-Acl -Path $folder -AclObject $acl
}
I really want to be able to reverse this, but cannot figure out how to reapply the permissions from the file that it exports.
List format is okay for human readers, but it's not really suitable for restoring data from a file. Save the full path and SDDL of each folder to a CSV:
foreach ($Folder in $FolderList) {
Get-Acl $folder | Select-Object #{n='Path';e={$Folder.FullName}}, Sddl |
Export-Csv $OutputFile -NoType -Append
...
}
That should allow you to restore the security information like this:
Import-Csv $OutputFile | ForEach-Object {
$acl = Get-Acl -Path $_.Path
$acl.SetSecurityDescriptorSddlForm($_.Sddl)
Set-Acl -Path $_.Path -AclObject $acl
}
Related
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
}
}
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.
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
}
I am currently using this to get a list of all permissions for specific folders.
`$InputFile = "C:\temp\Folders.txt"
$OutputFile = "C:\temp\FolderPermissions.txt"
$FolderList = Get-Content $InputFile
ForEach ($Folder in $FolderList)
{
Get-Acl $folder | Format-list >>$OutputFile
}
`
What i would like is for it to then remove all access apart from administrator from each of the specified folders.
I have looked at using SetAccessControl but can only manage to get it to remove all.
Could someone please point me in the right direction.
Thanks
The following code will remove any user execpt users matching 'administrator'
If you want to add more accounts add it to the Where-Object filter, for example:
Where-Object {$_.IdentityReference -match 'Administrator' -or $_.IdentityReference -eq 'NT AUTHORITY\SYSTEM'}
$InputFile = "C:\temp\Folders.txt"
$OutputFile = "C:\temp\FolderPermissions.txt"
$FolderList = Get-Content $InputFile
ForEach ($Folder in $FolderList)
{
Get-Acl $folder | Format-list >>$OutputFile
### Remove all ACL Rules exepet 'Administrator(s)'
$ACL = Get-ACL -Path $Folder
$Rules = $ACL.Access | Where-Object {$_.IdentityReference -notmatch 'Administrator'}
Foreach ($Rule in $Rules)
{
[Void]$ACL.RemoveAccessRule($Rule)
}
Set-Acl -Path $folder -AclObject $acl
}
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..