I try to implement a script which changes folder structure permission depending on some conditions. So far I set permissions with
$accessRule = New-Object System.Security.AccessControl.FileSystemAccessRule("$($group.Name)", #("$($group.Value.rights)"), "ContainerInherit, ObjectInherit", "None", "$($group.Value.type)")
$aclFolder.AddAccessRule($accessRule)
Set-Acl $folder $aclFolder
So far it works. But the script currently assumes, that a permission does exist. It it does not, the AddAccessRule command throws and error.
Is there any way recognize a permission exists?
Use Get-Acl $folder to read the current ACL and to verify if there are any permissions applied already.
Related
We have a large file share that houses about 1tb of data.
The following location has about 600 folders beneath it.
F:\Data
The task is to assign a specific AD group read permissions to every folder inside of the data folder, the subfolders do not matter.
I am trying to see if the script below would be the best approach?
my concern is this is a file server and I don't want to break anything
or mess up any rights, also not to sure if while the script is running and their
is a file open would it cause am error.
I have tried running this script in a test environment and it worked great , but there is no error log where even if it stopped somewhere i would be able to check.
I could be overthinking it, but just wanted to see if anyone has experienced anything like this?
$StartingPath = "PATH"
$Right = "Read"
$Principal = "Domain\ADGroup"
$Rule = New-Object System.Security.AccessControl.FileSystemAccessRule($Principal,$Right,"Allow")
foreach ($Folder in $(Get-ChildItem -Directory $StartingPath -Recurse)) {
$Acl=Get-Acl $Folder.FullName
$Acl.SetAccessRule($Rule)
Set-Acl $folder.Fullname $Acl
}
You need to experiment with Inheritance and Propagation (use your test environment for that) and use the overloaded method with 5 parameters to create your new accessrule for that.
That way, you only add the new rule to the main data share folder and do not have to iterate all subfolders.
# FileSystemRights: https://learn.microsoft.com/en-us/dotnet/api/system.security.accesscontrol.filesystemrights
# Inheritance flags: https://learn.microsoft.com/en-us/dotnet/api/system.security.accesscontrol.inheritanceflags
# Propagation flags: https://learn.microsoft.com/en-us/dotnet/api/system.security.accesscontrol.propagationflags
$Principal = "TheADGroupWithReadPermissions"
$accessRule = New-Object System.Security.AccessControl.FileSystemAccessRule($Principal, "Read", "ContainerInherit,ObjectInherit", "None", "Allow")
$acl = Get-Acl "F:\Data"
$acl.SetAccessRule($accessRule)
Set-Acl -Path "F:\Data" -ACLObject $acl
Difference between AddAccessRule() and SetAccessRule():
AddAccessRule
SetAccessRule
This method will add this access rule to the ACL. If a user or group has Modify permission and we use AddAccessRule() to create a new rule with Read permission the user or group will still also have Modify permissions.
This method removes any existing access and replaces that access with the specified rule. If a user or group has Modify permission and a new rule is created using SetAccessRule() specifying Read permission, that user or group will now only have Read permission.
I use PDQ Deploy for deployments and part of an install requires a share and permissions to be set for the engineering team. I made a script successfully however it overwrites what is currently there. I like to the the group. I can't seem to find any real way of doing this.
$acl = get-acl "c:\program files (x86)\Test\"
$Ar = New-Object System.Security.AccessControl.FileSystemAccessRule("manftest", "FullControl", "ContainerInherit,ObjectInherit", "None", "Allow")
$acl.setaccessrule($ar)
set-acl "c:\program files (x86)\Test\" $acl
New-SmbShare -Name "Test" -Path "C:\Program Files (x86)\Test" -FullAccess "DOMAIN\manftest"
Have you tried AddAccessRule instead of SetAccessRule ?
https://learn.microsoft.com/en-us/dotnet/api/system.security.accesscontrol.filesystemsecurity.addaccessrule?view=netframework-4.7.2
if I was you I will try to use icalc.exe
icacls.exe $path /grant "<domain\account>:(OI)(CI)(M)"
I have had a lot of challenges with PowerShell and setting access control lists in the past, and so I resort to using icacls in my PowerShell scripts.
I'm applying "Read" permissions to a folder for a certain user. I want them to be able to read notepad files inside.
$Acl = Get-Acl "C:\Test"
$Ar = New-Object system.security.accesscontrol.filesystemaccessrule("MyUser","Read","Allow")
$Acl.SetAccessRule($Ar)
Set-Acl "C:\Test" $Acl
My code properly applies the read permissions to the folder (I can manually check the "Security tab to see this), but does not grant access to the files inside. Access is denied when "MyUser" tries to open a notepad file.
You need to use another constructor so you can set InheritanceFlags for containers and leaf objects. Try:
$Ar = New-Object system.security.accesscontrol.filesystemaccessrule("MyUser","Read","ContainerInherit,ObjectInherit", "None", "Allow")
New-Item -Type Directory -Path "C:\MyFolder"
$Acl = Get-Acl "C:\MyFolder"
$Ar = New-Object System.Security.AccessControl.FileSystemAccessRule("username", "FullControl", "Allow")
$Acl.SetAccessRule($Ar)
Set-Acl -Path "C:\MyFolder" -AclObject $Acl
Hi, when I got the above code and applied it using my own settings - the user account entries are added for the folder but, no Permissions are applied (none ticked)
Can anyone help with why this might be?
Thanks
Your comment describes the following behaviour:
Your PowerShell script succeeds but if you check the permissions with the explorers properties dialog, you will see the following:
This is pretty confusing as a PowerShell query will confirm:
PS> Get-Acl .|fl
Path : Microsoft.PowerShell.Core\FileSystem::D:\temp\myfolder
Owner : clijsters\clijsters
Group : clijsters\Kein
Access : clijsters\NEWUSER Allow FullControl
VORDEFINIERT\Administratoren Allow FullControl
VORDEFINIERT\Administratoren Allow 268435456
NT-AUTORITÄT\SYSTEM Allow FullControl
[...]
Your ACL changed. If you scroll down the list of your checkboxes you will notice, that "Special permissions" is checked and if you click on "Advanced" you will notice, your permissions are set.
EDIT:
As mentioned by #AnsgarWiechers, I missed a part describing why the permissions added with New-Object System.Security.AccessControl.FileSystemAccessRule("username", "FullControl", "Allow") are listed as Special permissions.
Like described on MSDN, FileSystemAccessRule has 4 constructors, where some accept InheritanceFlags and PropagationFlags (e.g. this one fits your needs). If you use them and define inheritance behaviour, the permissions will show up as normal ones.
Today I was trying to compile ILSpy and encountered AL1078: Error signing assembly which is a permissions issue. An amalgamation of answers is shown.
This powershell script assigns $CurUsr to the token for the currently logged in user and $CurTgt as the folder whose permissions are being altered. Change them as required.
Add permission:
$CurTgt = "C:\Users\All Users\Microsoft\Crypto\RSA\MachineKeys"
$CurUsr = [System.Security.Principal.WindowsIdentity]::GetCurrent().Name
$acl = Get-Acl $CurTgt
$AccessRule = New-Object System.Security.AccessControl.FileSystemAccessRule($CurUsr,"FullControl","ContainerInherit,ObjectInherit","None","Allow")
$acl.SetAccessRule($AccessRule)
$acl | Set-Acl $CurTgt
Remove permission:
$CurTgt = "C:\Users\All Users\Microsoft\Crypto\RSA\MachineKeys"
$CurUsr = [System.Security.Principal.WindowsIdentity]::GetCurrent().Name
$acl = Get-Acl $CurTgt
$usersid = New-Object System.Security.Principal.Ntaccount ($CurUsr)
$acl.PurgeAccessRules($usersid)
$acl | Set-Acl $CurTgt
References:
Manage ACLs
Inheritance
Current User
The problem I need to solve is I need to make a folder on a network share for a newly created user. This is done by System Center Orchestrator, after the user is created I need to copy a dummy folder with certain rights, add the newly created user in the ACL's and delete the workflow account from those ACL's. (the user that creates the folder gets added automaticly.)
The folder gets created succesfully and gets the same permissions as the dummy folder, now I need to add 1 ACL rule to those permissions.
Here is some sample code I'm using:
$colRights = [System.Security.AccessControl.FileSystemRights]"Read, Write"
$InheritanceFlag = [System.Security.AccessControl.InheritanceFlags]::None
$PropagationFlag = [System.Security.AccessControl.PropagationFlags]::None
$objType =[System.Security.AccessControl.AccessControlType]::Allow
$objUser = New-Object System.Security.Principal.NTAccount("domain\createdUser1")
$objACE = New-Object System.Security.AccessControl.FileSystemAccessRule (
$objUser, $colRights, $InheritanceFlag, $PropagationFlag, $objType
)
$originalACL = Get-ACL "\\shares\createdUser1"
#$orignalACL.SetAccessRuleProtection($True,$False)#doesn't help either
$originalACL.AddAccessRule($objACE)
Set-ACL "\\shares\createdUser1" $objACL
The only problem I'm having is that it doesn't add the ACL rule but it overwrites all rules that this folder currently has. How can I add 1 rule to to an existing ACL without overwriting the original rules?
source sample code: https://technet.microsoft.com/en-us/library/ff730951.aspx
EDIT1:
Using the module provided on https://blogs.technet.microsoft.com/heyscriptingguy/2014/11/22/weekend-scripter-use-powershell-to-get-add-and-remove-ntfs-permissions/ does the same thing. Am I doing something wrong?
$colRights = "Read, Write"
$objUser = New-Object System.Security.Principal.NTAccount("domain\createdUser1")
Add-NTFSAccess -Path $folderPath -Account $objUser -AccessRights $colRights
There's nothing in your code that would remove ACLs except for the (now commented) line
#$orignalACL.SetAccessRuleProtection($True,$False)
That line will remove inherited ACLs, so of course it won't help.
From the documentation:
Syntax
public void SetAccessRuleProtection(
bool isProtected,
bool preserveInheritance
)
Parameters
isProtected
true to protect the access rules associated with this ObjectSecurity object from inheritance; false to allow inheritance.
preserveInheritance
true to preserve inherited access rules; false to remove inherited access rules. This parameter is ignored if isProtected is false.
I suspect you ran that line once before, thus removing inherited ACLs. To correct that mistake you need to re-enable inheritance first, either manually or by calling SetAccessRuleProtection() with the first parameter set to $false:
$orignalACL.SetAccessRuleProtection($false, $true)
This piece of code worked for me:
$colRights = "Read, Write"
$objUser = New-Object System.Security.Principal.NTAccount("domain\createdUser1")
add-NTFSAccess -Path $folderPath -Account $objUser -AccessRights $colRights
We ran it from an other user account and suddenly the code worked. This was found by testing the script on local folders. Here it didn't delete any other ACL's. This will probably be something with share permissions or security permissions. (locally I'm full admin but on the shares I'm not.)
The problem is here:
Set-ACL "\\shares\createdUser1" $objACL
Change to this:
Set-ACL "\\shares\createdUser1" $originalACL
You had modified the $originalACL when you ran $originalACL.AddAccessRule($objACE)