I have two very similar scripts for permissions and they keep overwriting each other.
When the two scripts grant permission to the same folder only Supervisor or Logistics group get it(the last script that i have executed.
Supervisor.ps1
$dir = "E:\test\template\"
$acl = Get-Acl $dir
$permissions2 = 'Supervisors', 'ReadAndExecute,Write', 'ContainerInherit,ObjectInherit', 'None', 'Allow'
$permissions3 = 'Supervisors', 'ReadAndExecute', 'ContainerInherit,ObjectInherit', 'None', 'Allow'
$accessRule = New-Object System.Security.AccessControl.FileSystemAccessRule -ArgumentList $permissions3
$acl.SetAccessRule($accessRule)
$acl | Set-Acl "$dir\01.Offers\02.Out\01.Main_Offer\02.Draft"
$acl | Set-Acl "$dir\01.Offers\02.Out\01.Main_Offer\03.Sent"
$acl | Set-Acl "$dir\01.Offers\02.Out\01.Main_Offer\04.Approved"
$acl | Set-Acl "$dir\01.Offers\02.Out\02.Additional_offers\01.Add_offer_1"
$acl | Set-Acl "$dir\02.Projects\01.Drawings"
$acl | Set-Acl "$dir\02.Projects\02.BoQ"
$acl | Set-Acl "$dir\03.Documents\01.Request_for_Offer"
$acl | Set-Acl "$dir\03.Documents\06.Other"
$acl | Set-Acl "$dir\04.Contracts"
$acl | Set-Acl "$dir\08.Logistics"
$accessRule = New-Object System.Security.AccessControl.FileSystemAccessRule -ArgumentList $permissions2
$acl.SetAccessRule($accessRule)
$acl | Set-Acl "$dir\01.Offers\01.In"
$acl | Set-Acl "$dir\01.Offers\02.Out\01.Main_Offer\01.Calc"
$acl | Set-Acl "$dir\02.Projects\03.Reports"
$acl | Set-Acl "$dir\03.Documents\02.Schedules"
$acl | Set-Acl "$dir\03.Documents\03.Reports"
$acl | Set-Acl "$dir\03.Documents\04.Protocols"
$acl | Set-Acl "$dir\03.Documents\05.Construction_Programs"
$acl | Set-Acl "$dir\06.Correspondence"
$acl | Set-Acl "$dir\07.Pictures"
Logistics.ps1
$dir = "E:\test\template"
$acl = Get-Acl $dir
$permissions = 'Logistics', 'ReadAndExecute,Write', 'ContainerInherit,ObjectInherit', 'None', 'Allow'
$accessRule = New-Object System.Security.AccessControl.FileSystemAccessRule -ArgumentList $permissions
$acl.SetAccessRule($accessRule)
$acl | Set-Acl "$dir\01.Offers\01.In"
$acl | Set-Acl "$dir\01.Offers\02.Out\01.Main_Offer\01.Calc"
$acl | Set-Acl "$dir\02.Projects"
$acl | Set-Acl "$dir\03.Documents\04.Protocols"
$acl | Set-Acl "$dir\06.Correspondence"
$acl | Set-Acl "$dir\07.Pictures"
$acl | Set-Acl "$dir\08.Logistics"
$permissions1 = 'Logistics', 'ReadAndExecute', 'ContainerInherit,ObjectInherit', 'None', 'Allow'
$accessRule = New-Object System.Security.AccessControl.FileSystemAccessRule -ArgumentList $permissions1
$acl.SetAccessRule($accessRule)
$acl | Set-Acl "$dir\01.Offers\02.Out\01.Main_Offer\04.Approved"
$acl | Set-Acl "$dir\01.Offers\02.Out\02.Additional_offers\01.Add_offer_1\03.Approved"
$acl | Set-Acl "$dir\03.Documents\02.Schedules"
$acl | Set-Acl "$dir\03.Documents\03.Reports"
Have you tried AddAccessRule instead of SetAccessRule?
The SetAccessRule method adds the specified access control list (ACL) rule or overwrites any identical ACL rules that match the FileSystemRights value of the rule parameter.
Related
My script in a nutshell should create 5 Folders, 1 root level folder, 3 2nd level folders, and 1 3rd level folder.
Permissions are granted at the 2nd level, either ReadWrite or ReadOnly. No user should be able to create anything within the second level or delete a second level.
I seem to be having issues with Set-Acl and permissions. I'm wondering if there's a better way to script this out that I don't need elevated privileges for. Our DA's can run the script fine, and I can do the folder and security group creation manually but its tedious and prone to errors. Any insight into what I'm doing wrong or how I could do it better would be appreciated.
Import-Module ActiveDirectory
$path = "\\earth\data\group\"
$newFolderName = Read-Host -Prompt "Enter Name of New Folder"
$newFolderFull = $path + $newFolderName
Write-Output "New Folder will be: $newFolderFull"
$confirm = Read-Host "Confirm? Y/N"
if (!(($confirm) -ne "y")) {
Write-Output "Create AD Groups"
$groupNamePGroup = "P_$newFolderName"
$groupNameAdminRW = "EG-$newFolderName-Admin-RW"
$groupNameAdminRF = "EG-$newFolderName-Admin-RF"
$groupNameEveryoneRW = "EG-$newFolderName-Everyone-RW"
$groupNameEveryoneRF = "EG-$newFolderName-Everyone-RF"
$groupNameScannedDocsRW = "EG-$newFolderName-ScannedDocs-RW"
New-ADGroup $groupNamePGroup -samAccountName $groupNamePGroup -GroupScope DomainLocal -path "OU=SecurityGroups,OU=Metro,DC=metrogr,DC=org"
New-ADGroup $groupNameAdminRW -samAccountName $groupNameAdminRW -GroupScope DomainLocal -path "OU=SecurityGroups,OU=Metro,DC=metrogr,DC=org"
New-ADGroup $groupNameAdminRF -samAccountName $groupNameAdminRF -GroupScope DomainLocal -path "OU=SecurityGroups,OU=Metro,DC=metrogr,DC=org"
New-ADGroup $groupNameEveryoneRW -samAccountName $groupNameEveryoneRW -GroupScope DomainLocal -path "OU=SecurityGroups,OU=Metro,DC=metrogr,DC=org"
New-ADGroup $groupNameEveryoneRF -samAccountName $groupNameEveryoneRF -GroupScope DomainLocal -path "OU=SecurityGroups,OU=Metro,DC=metrogr,DC=org"
New-ADGroup $groupNameScannedDocsRW -samAccountName $groupNameScannedDocsRW -GroupScope DomainLocal -path "OU=SecurityGroups,OU=Metro,DC=metrogr,DC=org"
Write-Output "Add Folder.."
New-Item $newFolderFull -ItemType Directory
New-Item $newFolderFull\Admin -ItemType Directory
New-Item $newFolderFull\Everyone -ItemType Directory
New-Item $newFolderFull\ScannedDocs -ItemType Directory
New-Item $newFolderFull\Everyone\ScannedDocs -ItemType Directory
Write-Output "Remove Inheritance.."
icacls $newFolderFull /inheritance:d
icacls $newFolderFull\Admin /inheritance:d
icacls $newFolderFull\Everyone /inheritance:d
icacls $newFolderFull\Everyone\ScannedDocs /inheritance:d
#icacls $newFolderFull\ScannedDocs /inheritance:d
# Rights
$readOnly = [Security.AccessControl.FileSystemRights]"ReadAndExecute"
$readWrite = [Security.AccessControl.FileSystemRights]"Write, DeleteSubdirectoriesAndFiles,ReadAndExecute"
# Inheritance
$inheritanceFlag = [Security.AccessControl.InheritanceFlags]"ContainerInherit, ObjectInherit"
# Propagation
$propagationFlag = [Security.AccessControl.PropagationFlags]::None
# User
$PUserRF = New-Object System.Security.Principal.NTAccount($groupNamePGroup)
$AdminUserRW = New-Object System.Security.Principal.NTAccount($groupnameAdminRW)
$AdminUserRF = New-Object System.Security.Principal.NTAccount($groupnameAdminRF)
$EveryoneUserRW = New-Object System.Security.Principal.NTAccount($groupnameEveryoneRW)
$EveryoneUserRF = New-Object System.Security.Principal.NTAccount($groupnameEveryoneRF)
$ScannedDocsUserRW = New-Object System.Security.Principal.NTAccount($groupnameScannedDocsRW)
# Type
$type = [Security.AccessControl.AccessControlType]::Allow
#Add Group membership
Add-ADGroupMember -Identity $groupNamePGroup -Members $groupNameAdminRW,$groupNameAdminRF,$groupNameEveryoneRW,$groupNameEveryoneRF,$groupNameScannedDocsRW
Add-ADGroupMember -Identity $groupNameEveryoneRW -Members NDPSSCAN
Add-ADGroupMember -Identity $groupNameScannedDocsRW -Members NDPSSCAN
# ACL
$accessControlEntryDefault = New-Object System.Security.AccessControl.FileSystemAccessRule #("Domain Users", $readOnly, $inheritanceFlag, $propagationFlag, $type)
$accessControlRootEntryRF = New-Object System.Security.AccessControl.FileSystemAccessRule #($PUserRF, $readOnly, $inheritanceFlag, $propagationFlag, $type)
$accessControlAdminEntryRW = New-Object System.Security.AccessControl.FileSystemAccessRule #($AdminUserRW, $readWrite, $inheritanceFlag, $propagationFlag, $type)
$accessControlAdminEntryRF = New-Object System.Security.AccessControl.FileSystemAccessRule #($AdminUserRF, $readOnly, $inheritanceFlag, $propagationFlag, $type)
$accessControlEveryoneEntryRW = New-Object System.Security.AccessControl.FileSystemAccessRule #($EveryoneUserRW, $readWrite, $inheritanceFlag, $propagationFlag, $type)
$accessControlEveryoneEntryRF = New-Object System.Security.AccessControl.FileSystemAccessRule #($EveryoneUserRF, $readOnly, $inheritanceFlag, $propagationFlag, $type)
$accessControlScannedDocsEntryRW = New-Object System.Security.AccessControl.FileSystemAccessRule #($ScannedDocsUserRW, $readWrite, $inheritanceFlag, $propagationFlag, $type)
$objACL = Get-Acl $newFolderFull
$objACL.RemoveAccessRuleAll($accessControlEntryDefault)
$objACL.AddAccessRule($accessControlRootEntryRF)
Set-Acl $newFolderFull $objACL
$objACL = Get-Acl $newFolderFull\Admin
$objACL.RemoveAccessRuleAll($accessControlEntryDefault)
$objACL.AddAccessRule($accessControlAdminEntryRW)
$objACL.AddAccessRule($accessControlAdminEntryRF)
Set-Acl $newFolderFull\Admin $objACL
$objACL = Get-Acl $newFolderFull\Everyone
$objACL.RemoveAccessRuleAll($accessControlEntryDefault)
$objACL.AddAccessRule($accessControlEveryoneEntryRW)
$objACL.AddAccessRule($accessControlEveryoneEntryRF)
Set-Acl $newFolderFull\Everyone $objACL
$objACL = Get-Acl $newFolderFull\ScannedDocs
$objACL.RemoveAccessRuleAll($accessControlEntryDefault)
$objACL.AddAccessRule($accessControlScannedDocsEntryRW)
Set-Acl $newFolderFull\ScannedDocs $objACL
}
SetAccessControl($objACL) worked for me.
Set-ACL didn't work as my account didn't have elevated permissions.
I'm trying to use a CSV import to create batch users but for it to also create users' home folder and profile folders but with setting permissions at the same time.
I've found a lot of helpful information online, I just don't know how to make the syntax work with what I already have which took me quite a long time to even get to.
This is my script so far for creating accounts on the domain controller and then syncing them with O365. We use a csv as we create tons of users at the same time:
Import-Csv "C:\blablabla\filename.csv" | ForEach-Object {
New-ADUser -Name $_.Name `
-GivenName $_."GivenName" `
-Surname $_."Surname" `
-DisplayName $_."DisplayName" `
-SamAccountName $_."samAccountName" `
-UserPrincipalName $_."UserPrincipalName" `
-Path $_."Path" `
-AccountPassword (ConvertTo-SecureString “Pa$$w0rd” -AsPlainText -force) -Enabled $true `
-EmailAddress $_."EmailAddress" `
-ProfilePath $_."ProfilePath" `
-HomeDrive $_."HomeDrive" `
-HomeDirectory $_."HomeDirectory" `
-ScriptPath $_."ScriptPath" `
-Server $_."Server" `
-OtherAttributes #{ProxyAddresses= $_."ProxyAddresses"} `
}
Start-ADSyncSyncCycle -PolicyType Initial
All the values point to columns in the excel file which auto-complete based on a user's first and last name.
I know I'm supposed to be creating the home and profile folders and setting permissions as per the below for example, I just don't know how to make the syntax work with what I already have?
So far, the values only get set in AD correctly but the folders don't get created and permissions aren't getting applied.
I guess I could just add an other command to create a new folder but I wouldn't know how to do append that to the foreach command?
New-Item -ItemType Directory -Path \\dc\userdata
$ACL = (Get-ACL -Path $HomeDirectory)
$FullControlAccessRule = (New-Object System.Security.AccessControl.FileSystemAccessRule([System.Security.Principal.NTAccount]"hcc.local\$UserName","FullControl", "ContainerInherit, ObjectInherit", "None", "Allow"))
$ACL.AddAccessRule($FullControlAccessRule)
Set-ACL -Path $HomeDirectory $ACL
Any help would be greatly appreciated.
Thanks.
So, as per what NAS said, something like this then
?
-OtherAttributes #{ProxyAddresses= $_."ProxyAddresses"}
New-Item -ItemType Directory -Path $_.HomeDirectory
New-Item -ItemType Directory -Path $_.ProfilePath
$ACL = (Get-ACL -Path $_.HomeDirectory)
$FullControlAccessRule = (New-Object System.Security.AccessControl.FileSystemAccessRule(
[System.Security.Principal.NTAccount]"hcc.local\$($_.samAccountName)",
"FullControl", "ContainerInherit, ObjectInherit", "None", "Allow"))
$ACL.AddAccessRule($FullControlAccessRule)
Set-ACL -Path $_.HomeDirectory $ACL
$ACL = (Get-ACL -Path $_.ProfilePath)
$FullControlAccessRule = (New-Object System.Security.AccessControl.FileSystemAccessRule(
[System.Security.Principal.NTAccount]"hcc.local\$($_.samAccountName)",
"FullControl", "ContainerInherit, ObjectInherit", "None", "Allow"))
$ACL.AddAccessRule($FullControlAccessRule)
Set-ACL -Path $_.ProfilePath $ACL
Import-Csv "C:\blablabla\filename.csv" | ForEach-Object {
New-ADUser -Name $_.Name `
...
-OtherAttributes #{ProxyAddresses= $_."ProxyAddresses"} # Remove backtick
New-Item -ItemType Directory -Path $_.HomeDirectory # create home path if needed
New-Item -ItemType Directory -Path $_.ProfilePath # create profile path if needed
$ACL = (Get-ACL -Path $_.HomeDirectory) # No need for quotes around properties if they do not contain spaces or other special characters
$FullControlAccessRule = (New-Object System.Security.AccessControl.FileSystemAccessRule(
[System.Security.Principal.NTAccount]"hcc.local\$($_.samAccountName)", # replace $UserName with correct variable
"FullControl", "ContainerInherit, ObjectInherit", "None", "Allow"))
$ACL.AddAccessRule($FullControlAccessRule)
Set-ACL -Path $_.HomeDirectory $ACL
# -> # repeat for profile path if needed
}
When I set user access via set-acl I can loop through all existing subfolders. How do I set it to include future subfolders created under the main folder?
Also... Once the access is set it only displays in 'Advanced' settings for the folders. The first security screen shows the user but shows no access rights.
This is in Windows Server 2012 R2.
$SubFolder = "name"
$UserName = "domain\" + $SubFolder
$Folder = "R:\User Files\" + $SubFolder + "\"
$Acl = Get-Acl $Folder
$Ar = New-Object system.security.accesscontrol.filesystemaccessrule($UserName,"FullControl","Allow")
$Acl.SetAccessRule($Ar)
#Get-Variable
Set-Acl -Path $Folder -AclObject $Acl
$Folder = Get-childItem $Folder
foreach ($TempFolder in $Folder)
{
$Folder = $TempFolder.FullName
$Acl = Get-Acl $Folder
$Ar = New-Object system.security.accesscontrol.filesystemaccessrule($UserName,"FullControl","Allow")
$Acl.SetAccessRule($Ar)
#Get-Variable
Set-Acl -Path $Folder -AclObject $Acl
}
You will need to set your Inheritance and Propagation flags in order for it to affect files and folders within your target. Here's my typical template that I use when I'm working on setting up new ACLs for users:
$Rights = [System.Security.AccessControl.FileSystemRights]"FullControl"
$InheritanceFlag = [System.Security.AccessControl.InheritanceFlags]"ObjectInherit,ContainerInherit"
$PropagationFlag = [System.Security.AccessControl.PropagationFlags]::None
$objType =[System.Security.AccessControl.AccessControlType]::Allow
#Define the user's account using their samAccountName
$objUser = New-Object System.Security.Principal.NTAccount("samAccountName")
$objACE = New-Object System.Security.AccessControl.FileSystemAccessRule($objUser, $Rights, $InheritanceFlag, $PropagationFlag, $objType)
$objACL = Get-ACL "C:\Temp"
$objACL.AddAccessRule($objACE)
Set-ACL "C:\Temp" $objACL
The settings here will make future things inherit the settings that you define for the target folder.
i am trying to write a script which adds"CreatorOwner" permission to profile$ folders on all file servers;
i.e , add "CreatorOwner" permissions to "\FileServer\Profile$"
can anybody tell me whats the command and syntax for it?
Please do ask if any questions.
One way of doing this is using WMI and UNC paths.
$AccessRule = New-Object system.security.accesscontrol.filesystemaccessrule("CREATOR OWNER","FullControl","ContainerInherit, ObjectInherit","InheritOnly","Allow")
$profileshare = Get-WmiObject Win32_Share -ComputerName fileserver -Filter "name = 'profile$'"
$driveletter, $path = $profileshare.path
$path = $path.TrimStart("\")
$ACL = Get-Acl "\\fileserver\$driveletter`$\$path"
$ACL.SetAccessRule($AccessRule)
Set-Acl \\fileserver\$driveletter`$\$path -AclObject $ACL
Now if you have a list of server names you could do the following:
$servers = #("fileserver1","fileserver2","fileserver3")
$AccessRule = New-Object system.security.accesscontrol.filesystemaccessrule("CREATOR OWNER","FullControl","ContainerInherit, ObjectInherit","InheritOnly","Allow")
$servers | % {
$profileshare = Get-WmiObject Win32_Share -ComputerName $_ -Filter "name = 'profile$'"
$driveletter, $path = $profileshare.path
$path = $path.TrimStart("\")
$ACL = Get-Acl "\\$_\$driveletter`$\$path"
$ACL.SetAccessRule($AccessRule)
Set-Acl \\$_\$driveletter`$\$path -AclObject $ACL
}
This will do it:
#Change the CSV file path
$Permissions = Import-Csv C:\Test.CSV -delimiter '|'
ForEach ($line in $Permissions)
$inherit = [system.security.accesscontrol.InheritanceFlags]"ContainerInherit,
ObjectInherit"
$propagation = [system.security.accesscontrol.PropagationFlags]"None"
$acl = Get-Acl $line.Path
$acl.SetAccessRuleProtection($True, $False)
$accessrule = New-Object system.security.AccessControl.FileSystemAccessRule("domain users", "Read", $inherit, $propagation, "Allow")
#Adding the Rule
$acl.AddAccessRule($accessrule)
#Setting the Change
Set-Acl $line.Path $acl
What the CSV file looks Like
\SRV01\Folder1\Folder2 etc.
I'm pretty new to powershell scripting (nearly 1 month since I started learning powershell.)
I'm currently working on a script with powershell 2.0 to clean folder NTFS ACL. I want to delete every acl except the administrator one.
My problem is that I can't find a way to delete every acl that are not administrator, without knowing them.
So I came here to sought for powershell pro.
This code remove acl :
$acl = Get-Acl \\remote_server\share_folder\HAL.9000
$acl.Access | %{$acl.RemoveAccessRule($_)}
This code add administrator acl :
#BUILTIN administrator
$acl = Get-Acl \\remote_server\share_folder\HAL.9000
$permission = "BUILTIN\Administrators","FullControl", "ContainerInherit,ObjectInherit","None","Allow"
$accessRule = New-Object System.Security.AccessControl.FileSystemAccessRule $permission
$acl.SetAccessRule($accessRule)
Set-Acl \\remote_server\share_folder\HAL.9000 $acl
#Domain controller administrator
$acl = Get-Acl \\remote_server\share_folder\HAL.9000
$permission = "DOMAINCONTROLLER\Administrators","FullControl", "ContainerInherit,ObjectInherit","None","Allow"
$accessRule = New-Object System.Security.AccessControl.FileSystemAccessRule $permission
$acl.SetAccessRule($accessRule)
Set-Acl \\remote_server\share_folder\HAL.9000 $acl
Hope this will help someone :)
For convenience I've copy/pasted all this stuff together in a function. If it can be of use to anyone, here it is:
Function Remove-ACL {
[CmdletBinding(SupportsShouldProcess=$True)]
Param(
[parameter(Mandatory=$true,ValueFromPipeline=$true,Position=0)]
[ValidateNotNullOrEmpty()]
[ValidateScript({Test-Path $_ -PathType Container})]
[String[]]$Folder,
[Switch]$Recurse
)
Process {
foreach ($f in $Folder) {
if ($Recurse) {$Folders = $(Get-ChildItem $f -Recurse -Directory).FullName} else {$Folders = $f}
if ($Folders -ne $null) {
$Folders | ForEach-Object {
# Remove inheritance
$acl = Get-Acl $_
$acl.SetAccessRuleProtection($true,$true)
Set-Acl $_ $acl
# Remove ACL
$acl = Get-Acl $_
$acl.Access | %{$acl.RemoveAccessRule($_)} | Out-Null
# Add local admin
$permission = "BUILTIN\Administrators","FullControl", "ContainerInherit,ObjectInherit","None","Allow"
$rule = New-Object System.Security.AccessControl.FileSystemAccessRule $permission
$acl.SetAccessRule($rule)
Set-Acl $_ $acl
Write-Verbose "Remove-HCacl: Inheritance disabled and permissions removed from $_"
}
}
else {
Write-Verbose "Remove-HCacl: No subfolders found for $f"
}
}
}
}
Usage:
# For only one folder:
Remove-ACL 'C:\Folder' -Verbose
# For all subfolders:
Remove-ACL 'C:\Folder' -Recurse -Verbose
# Pipe stuff
'C:\Folder 1', 'C:\Folder 2' | Remove-ACL -Verbose
This code remove acl : $acl = Get-Acl
\remote_server\share_folder\HAL.9000 $acl.Access |
%{$acl.RemoveAccessRule($_)}
it does not work until you do
Set-Acl \\remote_server\share_folder\HAL.9000 $acl
Why not create a new list. For example:
$identity = New-Object System.Security.Principal.NTAccount('NT AUTHORITY\SYSTEM')
$acl = New-Object System.Security.AccessControl.DirectorySecurity
$acl.SetOwner($identity)
$acl.SetGroup($identity)
$rule = New-Object System.Security.AccessControl.FileSystemAccessRule('NT AUTHORITY\SYSTEM', ’FullControl’, ’ContainerInherit, ObjectInherit’, ’None’,’Allow’)
$acl.AddAccessRule($rule)
$rule = New-Object System.Security.AccessControl.FileSystemAccessRule('BUILTIN\Administrators', ’FullControl’, ’ContainerInherit, ObjectInherit’, ’None’, ’Allow’)
$acl.AddAccessRule($rule)
Set-Acl -LiteralPath "C:\MyFolder" -AclObject $acl
Get-Acl -LiteralPath "C:\MyFolder" | Format-List