Here is code I have to create a directory for my users. I was wondering how to skip the ACL part if the directory already exists.
#Search AD for Elem Students
$elem = Get-ADUser -Filter 'company -eq "1479"'
$path = "\\hs-ss\students\elem"
foreach ($user in $elem)
{
$Username = $User.SamAccountName
#Create user directory of Storage Server
New-Item -Path $path -Name $Username -ItemType "directory" -Force | Out-Null
$ACL = Get-Acl "$path\$Username"
$ACL.SetAccessRuleProtection($true, $false)
$ACL.Access | ForEach { [Void]$ACL.RemoveAccessRule($_) }
$ACL.AddAccessRule((New-Object System.Security.AccessControl.FileSystemAccessRule("$NTDomain\Domain Admins", "FullControl", "ContainerInherit, ObjectInherit", "None", "Allow")))
$ACL.AddAccessRule((New-Object System.Security.AccessControl.FileSystemAccessRule("$NTDomain\$username", "Modify", "ContainerInherit, ObjectInherit", "None", "Allow")))
Set-Acl "$Path\$username" $ACL
}
Check if the directory exists:
if (-not (Test-Path -LiteralPath "$path\$Username" -Type Container)) {
...
}
Related
I am trying to create a folder and set permissions on those folders within one PowerShell script. The script won't change the permissions when run the first time. I have to run the script twice to set the permissions. Not sure what could be causing this odd behavior.
$desired_install_loc = ${env:ProgramFiles}
$base_path = Join-Path $desired_install_loc 'Base_Test';
$install_path = Join-Path $base_path 'Install_Test';
function Create-Directory {
if( !(Test-Path $base_path )){
New-Item -ItemType Directory -Force -Path $base_path;
}
if( !(Test-path $install_path) ){
New-Item -ItemType Directory -Force -Path $install_path;
}
}
function Replace-FolderPerms($folder_path) {
$acl = (Get-Acl -Path $folder_path);
$add_rule = (New-Object System.Security.AccessControl.FileSystemAccessRule("BUILTIN\Users","Read", "Allow"));
$acl.SetAccessRuleProtection($true,$true)
$acl.SetAccessRule($add_rule)
Set-ACL $folder_path $acl;
}
Create-Directory;
Replace-FolderPerms $base_path;
Replace-FolderPerms $install_path;
Creates the folders, but does not set the permissions afterwards.
I was attempting to keep old permissions by setting SetAccessRuleProtection($true, $true). Setting the second argument to $false and fully building out the permissions did the trick.
$desired_install_loc = ${env:ProgramFiles}
$base_path = Join-Path $desired_install_loc 'Base_Test';
$install_path = Join-Path $base_path 'Install_Test';
function Create-Directory {
if( !(Test-Path $base_path )){
New-Item -ItemType Directory -Force -Path $base_path;
}
if( !(Test-path $install_path) ){
New-Item -ItemType Directory -Force -Path $install_path;
}
}
function Replace-FolderPerms($folder_path) {
$acl = (Get-Acl -Path $folder_path);
$add_rule = (New-Object System.Security.AccessControl.FileSystemAccessRule("BUILTIN\Users","Read", "Allow"));
$add_rule_admin = (New-Object System.Security.AccessControl.FileSystemAccessRule("BUILTIN\Administrators", "FullControl", "ContainerInherit,ObjectInherit", "None", "Allow"));
$add_rule_system = (New-Object System.Security.AccessControl.FileSystemAccessRule("SYSTEM", "FullControl", "ContainerInherit,ObjectInherit", "None", "Allow"));
$acl.SetAccessRuleProtection($true,$false);
$acl.AddAccessRule($add_rule);
$acl.AddAccessRule($add_rule_admin);
$acl.AddAccessRule($add_rule_system);
$acl | Set-ACL -Path $folder_path;
}
Create-Directory;
Replace-FolderPerms $base_path;
Replace-FolderPerms $install_path;
Attempting to set the owner of a folder as Domain Admins and force inheritance on all sub-folder/files. Using a combination of scripts I've found:
$Account = New-Object -TypeName System.Security.Principal.NTAccount -ArgumentList $DomainAdmins;
#Get a list of folders and files
$ItemList = Get-ChildItem -Path $Dir -Recurse;
#Iterate over files/folders
foreach ($Item in $ItemList) {
$Acl = $null; # Reset the $Acl variable to $null
$Acl = Get-Acl -Path $Item.FullName; # Get the ACL from the item
$Acl.SetOwner($Account); # Update the in-memory ACL
$isProtected = $false
$preserveInheritance = $false
$Acl.SetAccessRuleProtection($isProtected, $preserveInheritance)
Set-Acl -Path $Item.FullName -AclObject $Acl; # Set the updated ACL on the target item
}
Error: Set-Acl : Cannot bind argument to parameter 'AclObject' because it is null.
Some folders assign properly, however, not all. I suspect it breaks were there is no owner (possibly an account that's been removed from AD.)
Any ideas on how to approach this?
We will end up using this, even though it's not handling the long file paths correctly.
Import-Module -Name NTFSSecurity
#Remove Inheritance on user's root folder
Get-Item $UserRoot | Disable-NTFSAccessInheritance
#Add Domain Admin to user's root folder
Add-NTFSAccess -Path $UserRoot -Account 'BUILTIN\Administrators', 'yourDomain\Domain Admins' -AccessRights FullControl
#Set Inheritance on all sub-folders on user's directory
Get-ChildItem -Path $UserRoot -Recurse | Enable-NTFSAccessInheritance -PassThru
Check SetOwner() method for setting up owner for a folder
# Define the owner account/group
$Account = New-Object -TypeName System.Security.Principal.NTAccount -ArgumentList 'BUILTIN\Administrators';
# Get a list of folders and files
$ItemList = Get-ChildItem -Path c:\test -Recurse;
# Iterate over files/folders
foreach ($Item in $ItemList) {
$Acl = $null; # Reset the $Acl variable to $null
$Acl = Get-Acl -Path $Item.FullName; # Get the ACL from the item
$Acl.SetOwner($Account); # Update the in-memory ACL
Set-Acl -Path $Item.FullName -AclObject $Acl; # Set the updated ACL on the target item
}
Specify Inheritance in FileSystemAccessRule()
$Acl = Get-Acl "\\R9N2WRN\Share"
$Ar = New-Object System.Security.AccessControl.FileSystemAccessRule("user", "FullControl", "ContainerInherit,ObjectInherit", "None", "Allow")
$Acl.SetAccessRule($Ar)
Set-Acl "\\R9N2WRN\Share" $Acl
Check the SO1 and SO2 for further related information.
I am trying to make a script that creates file areas for different groups in a company. All the members in the group need to have full access to the shared files, but any member from the other groups can not have access - not even see them. This is what I have. For the "Limit access" section you need to change up the name of the group, and repeat this for each group. Can I put this in a foreach loop?
I am new to Powershell and really want to learn how to improve my script. So how can I improve and automate this code?
# Creates file areas
$folders = ('C:\shares\it-drift','C:\shares\dev-team','C:\shares\regnskap','C:\shares\renhold','C:\shares\HR')
mkdir -path $folders
$folders | Where-Object {$_ -like "*shares*"} | ForEach-Object {$name = (Get-Item $_).name; $DfsPath = (‘\\sec.core\files\’ + $name); $targetPath = (‘\\dc1\’ + $name);New-DfsnFolderTarget -Path $dfsPath -TargetPath $targetPath}
# Limits access
$folder = ('C:\shares\dev-team')
$ACL = Get-Acl -path \\sec.core\files\dev-team
$AccessRule = New-Object System.Security.AccessControl.FileSystemAccessRule("sec.core\g_dev_team","FullControl","Allow")
$ACL.SetAccessRule($AccessRule)
$ACL | Set-Acl -Path "\\sec.core\files\dev-team"
$ACL.SetAccessRuleProtection($true,$true)
$ACL = Get-Acl "\\sec.core\files\dev-team"
$ACL.Access | where {$_.IdentityReference -eq "BUILTIN\Users" } | foreach { $acl.RemoveAccessRuleSpecific($_) }
Set-Acl "\\sec.core\files\dev-team" $acl
(Get-ACL -Path "\\sec.core\files\dev-team").Access | Format-Table IdentityReference,FileSystemRights,AccessControlType,IsInherited,InheritanceFlags -AutoSize
Appreciate all tips:)
Here is how you can automate set of the same ACL for each shared folder:
# Creates file areas
$folders = #(
'C:\shares\it-drift'
'C:\shares\dev-team'
'C:\shares\regnskap'
'C:\shares\renhold'
'C:\shares\HR'
)
mkdir -path $folders
$folders | Where-Object {$_ -like "*shares*"} |
ForEach-Object {
$name = (Get-Item $_).name
$DfsPath = '\\sec.core\files\' + $name
$targetPath = '\\dc1\' + $name
New-DfsnFolderTarget -Path $dfsPath -TargetPath $targetPath
}
# Limits access
foreach($folder in $folders)
{
$leaf = Split-Path $folder -Leaf
$path="\\sec.core\files\$leaf"
$acl = Get-Acl -Path $path
$AccessRule = New-Object System.Security.AccessControl.FileSystemAccessRule("sec.core\g_dev_team","FullControl","Allow")
$acl.SetAccessRule($AccessRule)
Set-Acl -Path $path -AclObject $acl
$acl.SetAccessRuleProtection($true,$true)
$acl = Get-Acl "\\sec.core\files\dev-team"
$acl.Access.where({$_.IdentityReference -eq "BUILTIN\Users"}).foreach({
$acl.RemoveAccessRuleSpecific($_)
})
Set-Acl -Path $path -AclObject $acl
(Get-ACL -Path $path).Access |
Format-Table IdentityReference,FileSystemRights,AccessControlType,IsInherited,InheritanceFlags -AutoSize
}
Try to use vertical coding instead of horizontal coding. People reading your code will be thankful.
I am trying to create the user folder for each AD Users. For each folder, I want the folder only accessed by that AD users only.
The finally result I want:
FolderName: "UserAFolder"
Goal: only UserA in "UserAFolder"
But the result is
FolderName: "UserAFolder"
UserA, UserB, UserC ... are all in "UserAFolder"
$folderpath = "\\san\Shares\UserFolders\"
$ulist =import-csv -Path C:\aduserlist.csv
foreach($list in $ulist)
{
$users = $list.username
$newpath = $folderpath+$users
New-Item -ItemType Directory -Path $folderpath -Name $users
$rights = "Modify"
$inheritanceFlag = "ContainerInherit,ObjectInherit"
$propagationFlag = "None"
$type = "Allow"
$objACL = Get-Acl $newpath
$entries = $users, $rights,$inheritanceFlag,$propagationFlag,$type
$rule = New-Object -TypeName System.Security.AccessControl.FileSystemAccessRule -ArgumentList $entries
$objACL.SetAccessRule($rule)
$objACL | Set-Acl -Path $newpath
}
The original Code of ACL is work. Just Parent Folder inheritance issue.
The NTFS Security
$folderpath = "\\san\Shares\UserFolders\"
$ulist =import-csv -Path C:\aduserlist.csv
foreach($list in $ulist){
$users = $list.username
$newpath = $folderpath+$users
New-Item -ItemType Directory -Path $folderpath -Name $users
$users = $list.username
$ADUser = $list.email
$newpath = $folderpath+$users
Add-NTFSAccess $newpath -Account $ADUser -AccessRights Modify -PassThru
}
Once a User is removed in AD their name is changes to a S-X-XX-XXX
I have a script to pull all folders where the S-X-XX-XXX has permissions, what I am trying to do is take that list of Folders and remove all S-X-XX-XXX's.
Code
<# The S-* is to represent the User ID that I am wanting to remove their folder permissions #>
$TargetUser = "S-*"
$TargetPath = "C:\Depts"
$Paths = get-childitem -path $TargetPath -Recurse -Directory
$FolderList = $Paths.FullName
ForEach ($Folder in $FolderList) {
$ACL = Get-Acl -Path $Folder
$ACLlist = $ACL.Access | where {$_.IdentityReference -like "*mike*"}
$RemoveUser = $ACLlist.IdentityReference
if ($ACLlist.IdentityReference -like "$TargetUser") {
Write-Host $Folder
Write-Host $RemoveUser
$ACE = New-Object System.Security.Accesscontrol.FileSystemAccessRule($RemoveUser, "None", "ContainerInherit,ObjectInherit", "InheritOnly", "Deny")
$ACL.AddAccessRule($ACE)
Set-Acl -Path $Folder -AclObject $ACL
}
}
I have found code on how to set folder permission from another folders permissions, however this are users that were not added through inheritance.
I know I am missing something simple so any help would be great.
Folder Permissions
Big thanks to everyone that replied, I appreciate you guys taking the time to help.
You can check what type of user login in acl, you don't need template.And you must go for each access rule in each folder to check this,because removeaccesrule method take only one object at time.
$DebugPreference = 'Continue'
$TargetPath = "D:\testdir"
$Paths = get-childitem -path $TargetPath -Recurse -Directory
$FolderList = $Paths.FullName
ForEach ($Folder in $FolderList) {
$ACLs = Get-Acl -Path $Folder
foreach($acl in $ACLs.Access){
If (($acl.IdentityReference -is [System.Security.Principal.SecurityIdentifier]) -and (-not $acl.IsInherited)){
Write-Debug ("Removing ACl for {0}`r`n" -f $acl.IdentityReference.Value)
[Void]$ACLs.RemoveAccessRule($acl)
}
}
Write-Debug ("Setting ACL for {0}`r`n" -f $folder.FullName)
Set-Acl -path $folder -aclObject $ACLs
}
I have one more solution:
Use module ntfsSecurity(folder and files management manual)
Lists all permissions that can no longer be resolved. This normally happens if the account is no longer available so the permissions show up as a SID and not as an account name.
To remove all non-resolvable or orphaned permissions you can use the following line. But be very careful with that as maybe the account is not resolvable due to a network problem.
Install-Module -Name NTFSSecurity
dir -Recurse | Get-NTFSOrphanedAccess | Remove-NTFSAccess
The answer for the problem is below.
Clear
$TargetUser = Read-Host -Prompt "Enter the target account you are targeting [Full or Parital works]"
$RootPath = Read-Host -Prompt "Enter the root folder to start looking in and removing permissions"
$SubPaths = Get-ChildItem -Path $RootPath -Recurse -Directory
$SubFolderList = $SubPaths.FullName
$rootdone = $false
$FolderPurgeList = #()
if ($rootdone -eq $false) {
$ACL = Get-Acl -Path $RootPath
$ACLlist = $ACL.Access | where {$_.IdentityReference -like "*$TargetUser*"}
$RemoveUser = $ACLlist.IdentityReference
$count = $RemoveUser.count
ForEach ($UserName in $RemoveUser ) {
$UserID = New-Object System.Security.Principal.Ntaccount ($UserName)
$ACL.PurgeAccessRules($UserID)
$ACL | Set-Acl $RootPath
$itemHasPerm = New-Object –TypeName PSObject
$itemHasPerm | Add-Member –MemberType NoteProperty –Name "Target User" -Value $UserName
$itemHasPerm | Add-Member –MemberType NoteProperty –Name "Folder Path" -Value $RootPath
$FolderPurgeList += $itemHasPerm
$count -= 1
}
if ($count -eq 0 ) {
$rootdone = $true
}
}
if ($rootdone -eq $true) {
ForEach ($SubFolder in $SubFolderList) {
$ACL = Get-Acl -Path $SubFolder
$ACLlist = $ACL.Access | where {$_.IdentityReference -like "*$TargetUser*"}
$RemoveUser = $ACLlist.IdentityReference
ForEach ($UserName in $RemoveUser ) {
$UserID = New-Object System.Security.Principal.Ntaccount ($UserName)
$ACL.PurgeAccessRules($UserID)
$ACL | Set-Acl $SubFolder
$itemHasPerm = New-Object –TypeName PSObject
$itemHasPerm | Add-Member –MemberType NoteProperty –Name "Target User" -Value $UserName
$itemHasPerm | Add-Member –MemberType NoteProperty –Name "Folder Path" -Value $SubFolder
$FolderPurgeList += $itemHasPerm
}
}
}
$FolderPurgeList
$DateStamp = Get-Date -Format "dd-MMM-yyyy - hh-ss"
$FolderPurgeList | Export-CSV $env:USERProfile\Documents\Purged_Permission_List_$DateStamp.csv