I have a txt file with a lot of pc names inside. I need to change folder permissions of a specific folder on each pc for thr local group "users" -> read and write. the folder is always the same.
I've got the following. if i only put one computername in the txt file it works well but if i put two or more, it doens't work.
this is what i have
$file = get-content -path "C:\pcnames.txt"
$acl = get-acl -path "$file\C$\testfolder1"
$new = "users","write, read","ContainerInherit,ObjectInherit","None","Allow"
$accessRule = new-object System.Security.AccessControl.FileSystemAccessRule $new
$acl.SetAccessRule($accessRule)
$acl | Set-Acl "$file\C$\testfolder1"
That's because Get-Content will return an array if there are multiple lines. You therefor need to loop through every element in the $file array.
Your code will look something like this:
$file = get-content -path "C:\pcnames.txt"
foreach($pc in $file) {
$acl = get-acl -path "$pc\C$\testfolder1"
$new = "users","write, read","ContainerInherit,ObjectInherit","None","Allow"
$accessRule = new-object System.Security.AccessControl.FileSystemAccessRule $new
$acl.SetAccessRule($accessRule)
$acl | Set-Acl "$pc\C$\testfolder1"
}
Related
I am trying to use the "default" options in applying folder permissions; by that, I mean that using the "Full Controll, Write, Read, etc" in the 'Properties' for a folder.
The following script works to add the user in, but it applies "Special Permissions" - not the ones with the tick boxes for the ones visible in the properties menu of the folder:
$Acl = Get-Acl "\\R9N2WRN\Share"
$Ar = New-Object System.Security.AccessControl.FileSystemAccessRule ("user","FullControl","Allow")
$Acl.SetAccessRule($Ar)
Set-Acl "\\R9N2WRN\Share" $Acl
What am I doing wrong please?
Specifying inheritance in the FileSystemAccessRule() constructor fixes this, as demonstrated by the modified code below (notice the two new constuctor parameters inserted between "FullControl" and "Allow").
$Acl = Get-Acl "\\R9N2WRN\Share"
$Ar = New-Object System.Security.AccessControl.FileSystemAccessRule("user", "FullControl", "ContainerInherit,ObjectInherit", "None", "Allow")
$Acl.SetAccessRule($Ar)
Set-Acl "\\R9N2WRN\Share" $Acl
According to this topic
"when you create a FileSystemAccessRule the way you have, the
InheritanceFlags property is set to None. In the GUI, this
corresponds to an ACE with the Apply To box set to "This Folder Only",
and that type of entry has to be viewed through the Advanced
settings."
I have tested the modification and it works, but of course credit is due to the MVP posting the answer in that topic.
Referring to Gamaliel 's answer: $args is an array of the arguments that are passed into a script at runtime - as such cannot be used the way Gamaliel is using it.
This is actually working:
$myPath = 'C:\whatever.file'
# get actual Acl entry
$myAcl = Get-Acl "$myPath"
$myAclEntry = "Domain\User","FullControl","Allow"
$myAccessRule = New-Object System.Security.AccessControl.FileSystemAccessRule($myAclEntry)
# prepare new Acl
$myAcl.SetAccessRule($myAccessRule)
$myAcl | Set-Acl "$MyPath"
# check if added entry present
Get-Acl "$myPath" | fl
Another example using PowerShell for set permissions (File / Directory) :
Verify permissions
Get-Acl "C:\file.txt" | fl *
Apply full permissions for everyone
$acl = Get-Acl "C:\file.txt"
$accessRule = New-Object System.Security.AccessControl.FileSystemAccessRule("everyone","FullControl","Allow")
$acl.SetAccessRule($accessRule)
$acl | Set-Acl "C:\file.txt"
Screenshots:
Hope this helps
In case you need to deal with a lot of folders containing subfolders and other recursive stuff. Small improvement on #Mike L'Angelo:
$mypath = "path_to_folder"
$myacl = Get-Acl $mypath
$myaclentry = "username","FullControl","Allow"
$myaccessrule = New-Object System.Security.AccessControl.FileSystemAccessRule($myaclentry)
$myacl.SetAccessRule($myaccessrule)
Get-ChildItem -Path "$mypath" -Recurse -Force | Set-Acl -AclObject $myacl -Verbose
Verbosity is optional in the last line
This One work for me
$path = "C:\test"
$name = [System.Security.Principal.WindowsIdentity]::GetCurrent().Name
$acl = Get-Acl "C:\test"
$accessRule = New-Object System.Security.AccessControl.FileSystemAccessRule($name,"FullControl","Allow")
$acl.SetAccessRule($accessRule)
$acl | Set-Acl "C:\test"
Get-ChildItem -Path "$path" -Recurse -Force | Set-Acl -aclObject $acl -Verbose
$path = "C:\DemoFolder"
$acl = Get-Acl $path
$username = [System.Security.Principal.WindowsIdentity]::GetCurrent().Name
$Attribs = $username, "FullControl", "ContainerInherit,ObjectInherit", "None", "Allow"
$AccessRule = New-Object System.Security.AcessControl.FileSystemAccessRule($Attribs)
$acl.SetAccessRule($AccessRule)
$acl | Set-Acl $path
Get-ChildItem -Path "$path" -Recourse -Force | Set-Acl -aclObject $acl -Verbose
Attempting to set the owner of a folder as Domain Admins and force inheritance on all sub-folder/files. Using a combination of scripts I've found:
$Account = New-Object -TypeName System.Security.Principal.NTAccount -ArgumentList $DomainAdmins;
#Get a list of folders and files
$ItemList = Get-ChildItem -Path $Dir -Recurse;
#Iterate over files/folders
foreach ($Item in $ItemList) {
$Acl = $null; # Reset the $Acl variable to $null
$Acl = Get-Acl -Path $Item.FullName; # Get the ACL from the item
$Acl.SetOwner($Account); # Update the in-memory ACL
$isProtected = $false
$preserveInheritance = $false
$Acl.SetAccessRuleProtection($isProtected, $preserveInheritance)
Set-Acl -Path $Item.FullName -AclObject $Acl; # Set the updated ACL on the target item
}
Error: Set-Acl : Cannot bind argument to parameter 'AclObject' because it is null.
Some folders assign properly, however, not all. I suspect it breaks were there is no owner (possibly an account that's been removed from AD.)
Any ideas on how to approach this?
We will end up using this, even though it's not handling the long file paths correctly.
Import-Module -Name NTFSSecurity
#Remove Inheritance on user's root folder
Get-Item $UserRoot | Disable-NTFSAccessInheritance
#Add Domain Admin to user's root folder
Add-NTFSAccess -Path $UserRoot -Account 'BUILTIN\Administrators', 'yourDomain\Domain Admins' -AccessRights FullControl
#Set Inheritance on all sub-folders on user's directory
Get-ChildItem -Path $UserRoot -Recurse | Enable-NTFSAccessInheritance -PassThru
Check SetOwner() method for setting up owner for a folder
# Define the owner account/group
$Account = New-Object -TypeName System.Security.Principal.NTAccount -ArgumentList 'BUILTIN\Administrators';
# Get a list of folders and files
$ItemList = Get-ChildItem -Path c:\test -Recurse;
# Iterate over files/folders
foreach ($Item in $ItemList) {
$Acl = $null; # Reset the $Acl variable to $null
$Acl = Get-Acl -Path $Item.FullName; # Get the ACL from the item
$Acl.SetOwner($Account); # Update the in-memory ACL
Set-Acl -Path $Item.FullName -AclObject $Acl; # Set the updated ACL on the target item
}
Specify Inheritance in FileSystemAccessRule()
$Acl = Get-Acl "\\R9N2WRN\Share"
$Ar = New-Object System.Security.AccessControl.FileSystemAccessRule("user", "FullControl", "ContainerInherit,ObjectInherit", "None", "Allow")
$Acl.SetAccessRule($Ar)
Set-Acl "\\R9N2WRN\Share" $Acl
Check the SO1 and SO2 for further related information.
I would like to do something similar to How to Remove all permissions for a specific user?, but I want to remove all access to the file for everybody except the owner of the file.
Is it possible to do that in a relatively clean way?
I suppose I could call get-acl C:\users\myusername\AppData\Local\Temp\TheFile.txt and then walk through all the users listed there, and remove all rights for each one (as described in the linked question above), but is there an easier way?
Examplecode in a function (Put it simply in the same Scriptfile, above all your own code):
function Remove-ACLEntries
{
[CmdletBinding()]
param(
[string]$File
)
$authusers = ((New-Object System.Security.Principal.SecurityIdentifier 'S-1-5-11').Translate([System.Security.Principal.NTAccount])).Value
$acl = Get-Acl $File
$acl.SetAccessRuleProtection($True, $False)
$owner = $acl.owner;
For($i=$acl.Access.Count - 1; $i -gt 0; $i--)
{
$rule = $acl.Access[$i]
if ($rule.IdentityReference -ne $owner -or $rule.IdentityReference -eq $authusers)
{
$acl.RemoveAccessRule($rule)
}
}
Set-ACL -Path $file -AclObject $acl | Out-Null
}
Usage Single File:
Remove-ACLEntries -File c:\your\path\to\file.txt
Usage Multiple Files:
$files = Get-Childitem c:\your\path -Recurse
foreach ($file in $files){ Remove-ACLEntries -File $file.Fullname }
Attention: The User you are using to operate this function must have fullaccess to the file by himself. If the function don't working, try to run the powershell in Adminmode.
Greetings, Ronny
The example below removes all the ACLs and sets the ACL to allow Full Control for the owner of the file.
$acl = Get-Acl "$filePath"
$object = New-Object System.Security.Principal.Ntaccount($acl.owner)
$AccessRule = New-Object System.Security.AccessControl.FileSystemAccessRule($acl.owner,"FullControl","Allow")
$acl.SetOwner($object)
$acl.SetAccessRuleProtection($true,$false)
$acl.SetAccessRule($AccessRule)
#$acl.SetAccessRule($sysUserAccessRule)
$acl | Set-Acl "$filePath"
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..
I am stumped!
Here is what I need to do. We have migrated to a new domain, I basically need a script that we can run on a server that will re-curse all directories and files looking at the ACL's for each. It will search the ACL for OLDDOMAIN\USER etc. if found change the ACL to NEWDOMAIN\USER but maintain all the permissions
Here is what I have so far
$access = ""
$accessarray = #()
$filesarray = #()
$permarray = #()
$filesarray = Get-ChildItem C:\Users -Recurse
ForEach($path in $filesarray) {
$pathcheck = $path.fullname
$access = get-acl $pathcheck
$accessarray = $access.AccessToString.Split(",")
foreach ($item in $accessarray) {
if ($item -match "OLDDOMAIN") {
Write-Host $pathcheck
Write-Host $item
$item = $item -replace ("OLDDOMAIN","NEWDOMAIN")
$permarray = $item.split(” “) | where-object {$_ -ne ”“}
foreach($perm in $permarray) {
$ar = New-Object system.security.accesscontrol.filesystemaccessrule $perm
$acl.SetAccessRule($ar)
$acl | Set-Acl $pathcheck
}
}
}
}
It works kind of, but the problem is that when it goes to reapply the permissions the array is not in the correct order and it fails at the set-acl command
Any ideas? Pulling my hair out here :P
Thanks
$ar = New-Object system.security.accesscontrol.filesystemaccessrule $perm
The constructor for FileSystemAccessRule takes 3 arguments, and after all your splitting and foreach, $perm will have only one argument and that construction itself will fail.
Avoid the splits etc. Powershell provides you objects. Operate on them. Don't get strings, then split etc.
You can do what you want with something like this:
gci c:\users -recurse | %{
$acl = get-acl $_.fullname
$acl.Access | ?{$_.IdentityReference.Value.StartsWith("OLDDOMAIN")} | %{
$identity = $_.IdentityReference.Value -replace "OLDDOMAIN", "NEWDOMAIN"
$permission = $identity,$_.FileSystemRights,$_.AccessControlType
$ar = New-Object system.security.accesscontrol.filesystemaccessrule $permission
$acl.SetAccessRule($ar)
}
$acl | set-acl $_.fullname
}