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.
Related
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
So this might be a little complicated.... I have created a script which generates lists of all the people that have Security permissions on a share. The issue is that the share permission to a share will be different than the security permissions. I want to remove all share permissions and set the share permissions to the same people with the same full control as the security permissions.
I need to run this on four different servers so I need a script that will change that. Any ideas or resources?
Edit: After discussion with my colleagues the objective has slightly changed. Now I want to use Set-Acl to basically remove full control from all users EXCEPT one specific group. This shouldn't be too difficult right? I would simply throw a for each share - for each user- if user not in specific group then set acl to remove full control.
How does one remove permissions? I see commands for setting FC but not for removing.
As per your reply, this way removes all the bugs from GET-ACL and SET-ACL so can be used in earlier versions of PowerShell. Once it's removed, you can change this (reference $PERM) to add back on the group you want to retain access. Let me know if you need it tweaking.
$folderpath = "Somefolderpath"
write-Output "Removing inheritance "
$acl = Get-Acl $Folderpath
$acl.SetAccessRuleProtection($True, $True)
$acl | Set-Acl
$acl = Get-Acl $Folderpath
$acl.Access |where {$_.IdentityReference -eq "NT AUTHORITY\Authenticated
Users"} |%{$acl.RemoveAccessRule($_)}
$acl | Set-Acl
If ($?){
Write-Output "Inheritance Removed"
}
write-Output "Set permissions"
$acl = Get-Acl $Folderpath
$perm = "AddGroupHere","FullControl","Allow"
$accessRule = new-object System.Security.AccessControl.FileSystemAccessRule
$perm
$acl.AddAccessRule($accessRule)
$acl | Set-Acl
If ($?){
Write-Output "ACL set"
}
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
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
}
Trying to use powershell to reset permissions on files/folders copied over from a Linux machine.
Structure looks similar to this
E:\Parent Folder - No inheritance - Group based permissions
|
|
Folder01 - No inheritance
|
|
Subfolders and file - Group based permissions, inheritance
Folder02 - No inheritance
|
|
Subfolders and file - Group based permissions, inheritance
Folder03 - No inheritance
|
|
Subfolders and file - Group based permissions, inheritance
Folder04 - No inheritance
|
|
User Folder - User based permissions, No Inheritance
|
|
Inheritance
The script currently first runs the takeown command, followed by the icacls.
I then loop through the first level of folders to disable the inheritance.
Then the permissions are applied to the folders.
Here is a sample of what I have. It just repeats itself for each specific permission I want to set.
Get-ChildItem -Path "$solidPath" -ErrorAction SilentlyContinue | ForEach-Object {
$Item = $_.FullName
If ( "$Item" -eq "E:\ParentFolder\Folder04" -or "$Item" -eq "E:\ParentFolder\Folder03" )
{
Write-Host "Do Not Touch" -ForegroundColor DarkRed
}
Else
{
$colRightsAdmin = [System.Security.AccessControl.FileSystemRights]"FullControl"
$InheritanceFlagAdmin = [System.Security.AccessControl.InheritanceFlags]::ContainerInHerit -bor [System.Security.AccessControl.InheritanceFlags]::ObjectInHerit
$PropagationFlagAdmin = [System.Security.AccessControl.PropagationFlags]::None
$objTypeAdmin = [System.Security.AccessControl.AccessControlType]::Allow
$objUserAdmin = New-Object System.Security.Principal.NTAccount("BUILTIN\Administrators")
$objACEAdmin = New-Object System.Security.AccessControl.FileSystemAccessRule($objUserAdmin, $colRightsAdmin, $objTypeAdmin)
$objACLAdmin = Get-ACL "$Item"
$objACLAdmin.AddAccessRule($objACEAdmin)
Set-ACL "$Item" $objACLAdmin
I am using takeown + icacls to try and reset all the permissions. This initially worked well because the inheritance flags get reset as well.
I then use the method described in the link to set the appropriate permissions and inheritance on my folders and let the inheritance do the rest - Powershell & .net
The script worked on my test directory structure. But after coping the folders and files over I am getting a permission denied message when the icacls command runs (the takeown command runs without issue). The rest of the script then fails.
I know that I can use the RemoveAccessRule($objACE) to remove permissions from objects, but I haven't been able to figure out how to do it for all the user permissions that are defined.
I would like to start the folders and files off with a clean slate, and then apply permissions. All the examples I have found only show how to remove permissions for a specific user.
Where am I going wrong with the initial permission cleanup?
I ended up going with a bit of messy solution.
After I had a synced copy of the data from the Linux server I used robocopy to "move" all the data from one folder to another. This completely reset all the permissions on all the files.
After having done that I learned a little bit more about setting permissions and realized that I had been making a mistake all along.
I was aimlessly using this object to remove permissions
$acl.RemoveAccessRule($ace) | Out-Null
This was actually removing all privilege on the file before I had a chance to set any other permissions. So I was removing my ability to adjust permissions.
Once I realized this I used a combination of the properties IdentityReference and IsInherited to selectively target which permissions I was going to remove.
The script is big and ugly, but seems to work.