powershell add user permission to a folder in windows server - powershell

So I've got the next path: C:\folder1\folder2\fileName. Looking in the security tab on the C:\folder1 there is Alice username with full permissions. But going to the C:\folder1\folder2\fileName Alice isn't there yet. How can I insert with powershell v2 Alice member recursively in C:\folder1 so that all the files under root C:\folder1 will also have the same Alice username set with full permissions.
I've tried:
$acl = Get-Acl C:\folder1
$permission = "domain\Alice","FullControl","Allow"
$accessRule = New-Object System.Security.AccessControl.FileSystemAccessRule $permission
$acl.SetAccessRule($accessRule)
$acl | Set-Acl C:\folder1
But it doesn't seem to apply for the C:\folder1\folder1\fileName. Guess I'm trying to apply permissions for Alice, which doesn't exist yet in the last fileName item.

As you can see in the FileSystemAccessRule documentation, the class has a property for inheritance.
You have to add the property to your $permission
$permission = "domain\Alice",
"FullControl",
[System.Security.AccessControl.InheritanceFlags]"ContainerInherit",
[system.security.accesscontrol.PropagationFlags]"None",
"Allow"
$accessRule = New-Object System.Security.AccessControl.FileSystemAccessRule $permission

You could also recursively add the permissions by getting all child items with the Get-ChildItems cmdlet and piping them to the Set-Acl cmdlet like they have done in an examle in the documentation on microsoft site here: Set-Acl. Look at "Example 3: Apply a security descriptor to multiple files" or read below (copied from the page):
PS C:\> $NewAcl = Get-Acl File0.txt
PS C:\> Get-ChildItem -Path "C:\temp" -Recurse -Include "*.txt" -Force | Set-Acl - AclObject $NewAcl
These commands apply the security descriptors in the File0.txt file to all text files in the C:\Temp directory and all of its subdirectories.
The first command gets the security descriptor of the File0.txt file in the current directory and uses the assignment operator (=) to store it in the $NewACL variable.
The first command in the pipeline uses the Get-ChildItem cmdlet to get all of the text files in the C:\Temp directory. The Recurse parameter extends the command to all subdirectories of C:\temp. The Include parameter limits the files retrieved to those with the ".txt" file name extension. The Force parameter gets hidden files, which would otherwise be excluded. (You cannot use "c:\temp*.txt", because the -Recurse parameter works on directories, not on files.)
The pipeline operator (|) sends the objects representing the retrieved files to the Set-Acl cmdlet, which applies the security descriptor in the AclObject parameter to all of the files in the pipeline.
In practice, it is best to use the Whatif parameter with all Set-Acl commands that can affect more than one item. In this case, the second command in the pipeline would be "Set-Acl -AclObject $NewAcl -WhatIf". This command lists the files that would be affected by the command. After reviewing the result, you can run the command again without the Whatif parameter.
This is an example using ".txt" files but can be modified to apply to directories as well.

Related

Adding an AD Group to a large Public drive via Powershell

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.

Powershell taking ownership of folder before set-acl

Can I take over ownership and then set-acl to a folder? I have a folders.txt file where I have the location of the folder.
For Example:
D:\Dept\CC\NorthRiver\16-17\StaffAdministration
Then I am creating a new year of the previous year folder structure and copying the rights and permissions of the previous years folders to the new folder years matching folder. I ran into an issue though because of ownership of the folder. If I am not the owner I can not duplicate the permissions of certain folders and I receive Set-ACL : The security identifier is not allowed to be the owner of this object. Is there any way around this?
I tried adding the line (to change the owner to me but that did not work either):
get-item $currentFolder.Replace("16-17", "15-16") | set-owner -Account 'VDB-TST1\Administrators'
Does anyone have any ideas of how I may accomplish this?
This is the full script I have:
Function Get-FileName{
[CmdletBinding()]
Param(
[String]$Filter = "|*.*",
[String]$InitialDirectory = "C:\")
[void][System.Reflection.Assembly]::LoadWithPartialName("System.windows.forms")
$OpenFileDialog = New-Object System.Windows.Forms.OpenFileDialog
$OpenFileDialog.initialDirectory = $InitialDirectory
$OpenFileDialog.filter = $Filter
[void]$OpenFileDialog.ShowDialog()
$OpenFileDialog.filename
}
#Get and Set the ACL to the new years folder structure
foreach ($currentFolder in (GC (Get-FileName -InitialDirectory $env:USERPROFILE\Desktop -Filter "Text files (*.txt)|*.txt|All files (*.*)|*.*"))) {
md $currentFolder # Create Folder
get-item $currentFolder.Replace("16-17", "15-16") | set-owner -Account 'VDB-TST1\Administrators'
Get-ACL $currentFolder.Replace("16-17", "15-16") | Set-ACL $currentFolder
}
I think you are running into the same limitations of Set-ACL and Get-ACL described in this post. try changing
Get-ACL $currentFolder.Replace("16-17", "15-16") | Set-ACL $currentFolder
to
(Get-Item $currentFolder.Replace("16-17", "15-16")).GetAccessControl('Access') | Set-ACL $currentFolder
As an alternative you can use robocopy to copy the ntfs permissions from one directory and then apply them to another.
robocopy $currentFolder.Replace("16-17", "15-16") $currentfolder /copy:S /SECFIX
Hope this helps.
The Set-ACL cmdlet native to powershell is pretty terrible. I would suggest using the NTFS module that is available. I have tried playing with Set-ACL several times and it always wastes more of my time rather than actually being useful.

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
}

How to set NTFS permissions to specific folders in a folder structure?

I am looking for a way, where i run a script using powersell, that goes through a folder structure and set certain NTFS permissions only to a folder with a name "Submissions", so if there is any folder called "Submissions" within the folder structure, it will set it to NTFS permissions that i specified..
Any info will help me to start this!
http://s22.postimg.org/r769bcr01/Capture.png
Lets say i have this many folders, and in each folder, the structure is the same:
http://s15.postimg.org/pqh8leph7/sasa.png
So i need to aim at 04_architecture for example, and apply certain NTFS permissions, using powershell.
Maybe this is a starting point:
# find all submissions directories
$submissions = Get-ChildItem -Path "YOUR START PATH e.g. c:\test" -Recurse -Filter "Submissions" -directory
foreach($submission in $submissions)
{
# get the current submission directory acl
$acl = Get-ACL $submission.FullName
# create a new acl. Example:
$accessRule = New-Object System.Security.AccessControl.FileSystemAccessRule('Administrators','FullControl','ContainerInherit, ObjectInherit', 'None', 'Allow')
# add and set the new created acl to the directory
$acl.AddAccessRule($accessRule)
Set-Acl $submission.FullName $acl
}

How to remove an User from a file, using Cywin or Powershell

Thank you very much in advance for helping.
So I have hundreds of files and folders from which I'd like to remove the user: C850-108.
I can do this using Windows interface, but it'd take me days to do it in every file.
The reason I'd like to do this is because Cobian Backup tool can't have access to this files (Permission denied) and I think that user is the problem.
So I have Cygwin (bash) an PowerShell to help me in this tedious task.
I attach 3 screenshots:
Windows Security tab
PowerShell output of the command get-acl | format-list
Cygwin output of getfacl
I'm more experienced with bash, so I tried adding an user like this:
setfacl.exe -m u:rafaelgp:rwx myfile
Which apparently did nothing, but when I check with PowerShell, I saw that it actually worked and added a new user (rafaelgp) with the specified permissions. You can see this in the screenshots. So after this I lost some trust in Cygwin.
I've also tried deleting the user like this:
setfacl.exe -d u:C850-108 myfile
But I get the following message:
setfacl: illegal acl entries
So what can I do? As I said, I'm happy trying anything using bash or PowerShell.
Cheers!
UPDATE:
Screenshot of Musaab Al-Okaidi solution. There seems to be a problem with the '$file' parameter
The simplest way would arguably be icacls:
icacls file /remove C850-180
You can't remove permissions that were inherited from the parent folder with this, though. I suspect that this is the reason why setfacl failed. Unfortunately the inheritance information is suppressed when you pipe the output of Get-Acl into Format-List. Try this instead:
Get-Acl file | % { $_.Access } | ? { $_.IdentityReference -match 'C850-180' }
The IsInherited property will show you whether or not the ACL is inherited. If the ACL is inherited, you have to disable inheritance first before you can remove an ACL:
icacls file /inheritance:d
icacls is available since Windows Server 2003 SP2.
Update:
You can apply this recursively to a folder tree by adding the option /t:
icacls C:\some\folder\* /t /inheritance:d
icacls C:\some\folder\* /t /remove C850-180
Be advised, though, that it's not a good idea to recursively disable inheritance as it will make managing permissions a nightmare. Depending on your folder structure it might be better to simply remove inheritance and that particular ACE from the parent folder:
icacls C:\some\folder /inheritance:d
icacls C:\some\folder /remove C850-180
The subfolders and files will automatically inherit their parent folder's changed permissions. If necessary you can enforce that by resetting permissions on subfolders and files:
icacls C:\some\folder\* /reset /t /c
Add the following function to your shell, simply copy and paste, then you will have Remove-UserAccess as a usable Cmdlet
Function Remove-UserAccess()
{
Param
(
[Parameter(Mandatory=$true)][String]$Path,
[Parameter(Mandatory=$true)][String]$User
)
$Files = New-Object System.Collections.ArrayList
$Files.Add($Path) | Out-Null
#Add all files and folders to an array
$PathSubtree = Get-ChildItem -Path $Path -Recurse
Foreach ( $File in $PathSubtree )
{
$Files.Add($File.FullName) | Out-Null
}
# Remove access of the $User from each file in the array
Foreach ( $File in $Files )
{
$AccessRule = Get-Acl $File | % { $_.Access } | ? { $_.IdentityReference -eq $User}
IF ( $AccessRule -eq $null )
{
Write-Host "$User does not have access to $File" -ForegroundColor Yellow
}
ELSE
{
$ACL = Get-Acl $File
$ACL.RemoveAccessRule($AccessRule) | out-Null
Set-Acl -Path $File -AclObject $ACL -ErrorAction Stop
Write-Host "Permissions for $user have been removed from the following path: $File" -ForegroundColor Green
}
}
}
Execute the command as follows:
Remove-UserAccess -Path C:\temp -User RAFALAPTOP\C850-108
This will remove the access for the user from C:\temp and all sub-files and folders.