Grant permissions to a folder - powershell

How (which command) can I use to grant permissions (full_control) to a user (service_account) on a folder using PowerShell?
Thank you!
I was trying to use icacls in my PowerShell but it's not working.

There are several ways to do this. If you don't want to install a module as James suggests above then:
# Get current access permissions from folder and store in object
$Access = Get-Acl -Path $FolderPath
# Create new object with required new permissions
$NewRule = New-Object System.Security.AccessControl.FileSystemAccessRule("MyDomain\MyUserOrGroup","FullControl","ContainerInherit,ObjectInherit","None","Allow")
# Add new rule to our copy of the current rules
$Access.AddAccessRule($NewRule)
# Apply our new rule object to destination folder
Set-Acl -Path $FolderPath -AclObject $Access -ErrorAction Stop
As James mentions though, using ACLs in Powershell without a module, whilst powerful, is also a pain. I only do it when I'm sharing scripts (so that there isn't a dependency on the module).

I would recommend using the NTFSSecurity Powershell module for setting the permissions as it's much easier to use (and understand) than acls!
To add permissions for a user is just one command.
I've shown two examples for both network paths/domain account and local folder/local user. They can be mixed in any way you can set via the GUI.
Add-NTFSAccess -Path "\\sdk\data\SHAREDIR\$NAME" -Account "Domain\K_NV_TEST_R" -AccessRights FullControl
Add-NTFSAccess -Path "C:\folder\subfolder" -Account "LocalComputerName\LocalUserName" -AccessRights FullControl

Related

Error when changing ownership and transferring access rights

I ran into a problem, wrote a script that compresses pdf files through a program and transfers rights to a new file by copying from the old one to differentiate access to new files.
Here is the part of the code that I have is the problem
$owner = $origFile.GetAccessControl().GetOwner([System.Security.Principal.SecurityIdentifier])
$newFile = Get-Item -Path $PathoutFile
$FileSecurity = new-object System.Security.AccessControl.FileSecurity
$FileSecurity.SetOwner($owner)
[System.IO.File]::SetAccessControl($newFile, $FileSecurity)
Get-Acl -Path $origFile | Set-Acl -Path $newFile
My problem is this:
I execute the script using domain administrator privileges, everything works fine. If I use a domain user account and grant maximum rights to the directory, a compressed file is saved in it, and in this case I get the error “Attempt to perform an unauthorized operation.
I do not want to run the script under the administrator account for a simple reason, I believe that such rights are redundant for this operation. My judgments may not be correct, please help in solving this problem.
P.s actions are performed on a network directory.
Thanks in advance.
I myself found a solution to my main problem using the NTFSSecurity PowerShell module.
The transfer of access rights was performed using the Get-NTFSAccess $filein | Add-NTFSAccess $fileout

temporarily take ownership of a folder

I need to temporarily take ownership of a profilefolder, in order to add permissions(ReadOnly) to members of a securitygroup. I would like to know how to achieve this in powershell.
I have before used TakeOwn.exe, but since it can't give ownership back to the original owner, I can't use it for this.
I tried using a module called PowerShellAccessControl, which I found on technet.
Import-Module $PSScriptRoot\modules\PowerShellAccessControl\PowerShellAccessControl.psd1
$path = "$PSScriptRoot\profileFolders\profile"
$AddAceParams = #{
Principal = "SecurityGroup"
FolderRights = "Read"
}
Get-SecurityDescriptor $path -PacSDOption (New-PacCommandOption -BypassAclCheck) | ForEach-Object {
$OriginalOwner = $_.Owner
$_ | Set-Owner -PassThru -Apply |
Add-AccessControlEntry #AddAceParams -PassThru |
Set-Owner -Principal $OriginalOwner -Apply
}
But this code only resultet in the following error:
New-PacCommandOption : The term 'New-PacCommandOption' is not recognized as the name of a cmdlet, function, script file, or operable program. Check the spelling of the name, or if a path was included, verify that the path is correct and try again.
I dont know if i should continue with this module or if there is a better way.
I tend to use the NTFSSecurity module when dealing with filesystem permissions, it's well written and I've had good success with it so far.
$path = "C:\folder"
$OriginalPermissions = Get-NTFSOwner $path
Set-NTFSOwner -Path $path -Account $env:USERNAME
Add-NTFSAccess -Path $path -Account 'DOMAIN\SecurityGroup' -AccessRights Read
Set-NTFSOwner -Path $path -Account $OriginalPermissions.Owner
Note: You do need to install the module, if you're using a modern version of Powershell this is easy as you can just use Install-Module -Name NTFSSecurity. If it's an older version you will need download and install the module manually.
EDIT:
The other option is to use Enable-Privileges to grant your account the privileges for Backup, Restore, and Security.
With these you will be able to edit the permissions without your own account having explicit permissions to the data. Use of these command is covered in the documentation in the link above. Be sure to Disable-Privileges after enabling them as it's not good practice to run with these all the time.

Remove NTFS permissions of a user in all subdirectories

I am writing a script which would delete a specific user if the account is older than 7 days.
But when the user is deleted the NTFS permissions on my file server remain.
How can I delete all the permission for a specific user with PowerShell?
You should never grant permissions to individual users (with the exception of home directories and user profiles). As you can see for yourself it's a mess to clean up. Always create groups representing the particular functions/roles that require access, and grant permissions to those groups.
You can clean up the permissions via icacls:
icacls C:\root\folder /remove DOMAIN\user /t /c
Note, however, that you MUST do this before deleting the account, because for some reason icacls can't clean up SIDs of deleted accounts.
If you have already deleted the account you can try to fix permissions with Get-Acl and Set-Acl:
Get-ChildItem C:\root\folder -Recurse -Force | ForEach-Object {
$acl = Get-Acl -LiteralPath $_.FullName
$ace = $acl.Access | Where-Object { $_.IdentityReference -like 'S-1-5-*' }
$acl.RemoveAccessRule($ace) | Out-Null
Set-Acl -LiteralPath $_.FullName -AclObject $acl
}
Note that you may need to adjust the condition for selecting the ACE to remove from the file or folder's ACL.
Note also, that the above will fail for files/folders where the owner isn't either the user running the code or one of his groups. In a situation like that you can use tools like subinacl or SetACL as a last resort, as described in the answers to this question on ServerFault.

Create and Map Home Directory for AD Users using PowerShell

I used to create and map the home directory for new AD users in Active Directory Users and Computers GUI with following syntax:
\FileServer\users\%username%
This trick automatically creates home directory for user in FileServer and automatically grant full control to user on the directory. I was wondering what could be the PowerShell way of doing the same.
I think first of all you should get the User.
$user = get-ADUser -Filter { Name -like "Mike" }
Then create a Folder New-Item, something like:
$sac = $user.SamAccountName
$folder = New-Item \\Server\Filesystem\$sac -Type Directory
And then you have to set the permissions via Set-ACL
create new acl object
$AclOb = New-Object
System.Security.AccessControl.FileSystemAccessRule("domain\$sac", 'FullControl', 'ContainerInherit,ObjectInherit', 'None', 'Allow')
The security identifier (domain$sac);The right (FullControl);
Inheritance settings (ContainerInherit,ObjectInherit) which means to force all folders and files underneath the folder to inherit the permission we’re setting here;
Propagation settings (None) which is to not interfere with the inheritance settings;
Type (Allow).
and set-acl
Set-Acl -Path $folder.FullName -AclObject $AclOb
Greetz Eldo.Ob

Removing just one inherit permission using PowerShell

I'm trying to write a script that can remove access rights for just one (e.g. Everyone) on folders that have inherited permissions in place.
The other inherit permissions should stay intact. I can remove the inherit permissions and then remove access for that group, but inheritance is then broken. I don't want to enable inheritance after this action because of subfolders having no inheritance being broken.
How do I just remove this group without messing with the rest of the permissions?
You cannot (by design) remove an inherited permission, "without messing with the rest of the permissions".
What you can do is
Disallow inheritance, but preserve already inherited rules
Remove/modify the EVERYONE ACE after removing inheritance
Like this:
$FilePath = "C:\parentFolder\childItem.ext"
$FileACL = Get-Acl $FilePath
# Remove inheritance but preserve existing entries
$FileACL.SetAccessRuleProtection($true,$true)
Set-Acl $FilePath -AclObject $FileACL
# Retrieve new explicit set of permissions
$FileACL = Get-Acl $FilePath
# Retrieve "everyone" rule
$EveryoneRule = $FileACL.GetAccessRules($true,$true,[System.Security.Principal.NTAccount]) | Where-Object {$_.IdentityReference -eq [System.Security.Principal.NTAccount]"EVERYONE"}
# Remove it - or modify it and use SetAccessRule() instead
$FileACL.RemoveAccessRule($EveryoneRule)
# Set ACL on file again
Set-Acl $FilePath -AclObject $FileACL
To remove groups or users ACE without disabling inheritance, use CACLS folder /E /R group/user. I know that CACLS is deprecated but I have not found any equivalent when using iCacls or SETACL.
Actually you don't have to delete inheritance.
It is possible to just remove this one little mistake. Had the same error and it was successful on a Windows 2016 Fileserver.
I modified the Script from Mathias R. Jessen a bit. If you want to do this just to one Folder, replace "$folders = Get-Childitem" with "$filepath = Get-Item" and only use the commands inside the foreach loop.
Open Powershell as Admin
$folders = Get-ChildItem "C:\Path\To\Folder" | where {$_.psiscontainer -eq $true}
foreach ($FilePath in $folders)
{
$FileACL = Get-Acl $FilePath.FullName
$EveryoneRule = $FileACL.GetAccessRules($true,$true,[System.Security.Principal.NTAccount]) | Where-Object {$_.AccessControlType -eq "Deny"}
$FileACL.RemoveAccessRule($EveryoneRule)
Set-Acl $FilePath.FullName -AclObject $FileACL
}