Shared file area - how can I improve my PowerShell script? - powershell

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.

Related

PowerShell Removing Folder Permission for Deleted AD User Accounts

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

Export Folder Permissions

I want to Export folder Permissions for a subset of folders.
Each Folder in Department has two child's, Public and Internal.
For example, I want the permissions of the folder D:\Data\Department\Science\Public or D:\Data\Department\Sales\Public.
$FolderPath = dir -Directory -Path "D:\Data\Department" -Force
$Report = #()
Foreach ($Folder in $FolderPath)
{
$Folder2 = Join-Path -Path $Folder -ChildPath "Public"
$Acl = Get-Acl $Folder2.FullName
foreach ($Access in $acl.Access)
{
$Properties = [ordered]#{'FolderName'=$Folder2.FullName;'AD
Group or User'=$Access.IdentityReference;'Permissions'=$Access.FileSystemRights;'Inherited'=$Access.IsInherited}
$Report += New-Object -TypeName PSObject -Property $Properties
}
}
$Report | Export-Csv -path "C:\Users\adminrw\FolderPermissions.csv"
Error:
Get-Acl : Cannot validate argument on parameter 'Path'. The argument is null or empty. Provide an argument that is not null or empty, and then try the command again.
At line:7 char:16
+ $Acl = Get-Acl $Folder2.FullName
+ ~~~~~~~~~~~~~~~~~
+ CategoryInfo : InvalidData: (:) [Get-Acl], ParameterBindingValidationException
It looks like the Join-Path in your script is taking the Name of the folder and adding the childpath to it. This results in $Folder2 ending up like SomeFolder\Public
Try using
$Folder2 = Join-Path -Path $Folder.FullName -ChildPath "Public"
This will make $Folder2 : D:\Data\Department\SomeFolder\Public
I've corrected script. Please use below code:
$FolderPath = dir -Directory -Path "D:\Data\Department" -Force | Select *
$Report = #()
Foreach ($Folder in $FolderPath)
{
$Folder2 = Join-Path -Path $Folder.FullName -ChildPath "Public"
$Acl = Get-Acl $Folder2
foreach ($Access in $acl.Access)
{
$Properties = [ordered]#{'FolderName'=$Folder2.FullName;'AD
Group or User'=$Access.IdentityReference;'Permissions'=$Access.FileSystemRights;'Inherited'=$Access.IsInherited}
$Report += New-Object -TypeName PSObject -Property $Properties
}
}
$Report | Export-Csv -path "C:\Users\adminrw\FolderPermissions.csv"

backup and restore permissions

I am currently using the following script to export the permissions, take ownership of a folder and then remove all permissions from that folder. The folder list is taken from a text file.
$InputFile = "C:\temp\Folders.txt"
$OutputFile = "C:\temp\FolderPermissions.txt"
$FolderList = Get-Content $InputFile
foreach ($Folder in $FolderList) {
Get-Acl $folder | Format-List >>$OutputFile
$acl = Get-ACL -Path $folder
$acl.SetAccessRuleProtection($True, $True)
Set-Acl -Path $folder -AclObject $acl
$ACL = Get-ACL -Path $Folder
$Rules = $ACL.Access | Where-Object {$_.IdentityReference -notmatch 'Admin'}
foreach ($Rule in $Rules) {
[void]$ACL.RemoveAccessRule($Rule)
}
Set-Acl -Path $folder -AclObject $acl
}
I really want to be able to reverse this, but cannot figure out how to reapply the permissions from the file that it exports.
List format is okay for human readers, but it's not really suitable for restoring data from a file. Save the full path and SDDL of each folder to a CSV:
foreach ($Folder in $FolderList) {
Get-Acl $folder | Select-Object #{n='Path';e={$Folder.FullName}}, Sddl |
Export-Csv $OutputFile -NoType -Append
...
}
That should allow you to restore the security information like this:
Import-Csv $OutputFile | ForEach-Object {
$acl = Get-Acl -Path $_.Path
$acl.SetSecurityDescriptorSddlForm($_.Sddl)
Set-Acl -Path $_.Path -AclObject $acl
}

powershell permissions

I am currently using this to get a list of all permissions for specific folders.
`$InputFile = "C:\temp\Folders.txt"
$OutputFile = "C:\temp\FolderPermissions.txt"
$FolderList = Get-Content $InputFile
ForEach ($Folder in $FolderList)
{
Get-Acl $folder | Format-list >>$OutputFile
}
`
What i would like is for it to then remove all access apart from administrator from each of the specified folders.
I have looked at using SetAccessControl but can only manage to get it to remove all.
Could someone please point me in the right direction.
Thanks
The following code will remove any user execpt users matching 'administrator'
If you want to add more accounts add it to the Where-Object filter, for example:
Where-Object {$_.IdentityReference -match 'Administrator' -or $_.IdentityReference -eq 'NT AUTHORITY\SYSTEM'}
$InputFile = "C:\temp\Folders.txt"
$OutputFile = "C:\temp\FolderPermissions.txt"
$FolderList = Get-Content $InputFile
ForEach ($Folder in $FolderList)
{
Get-Acl $folder | Format-list >>$OutputFile
### Remove all ACL Rules exepet 'Administrator(s)'
$ACL = Get-ACL -Path $Folder
$Rules = $ACL.Access | Where-Object {$_.IdentityReference -notmatch 'Administrator'}
Foreach ($Rule in $Rules)
{
[Void]$ACL.RemoveAccessRule($Rule)
}
Set-Acl -Path $folder -AclObject $acl
}

Change ACL - Recurse All Directories Powershell

I am stumped!
Here is what I need to do. We have migrated to a new domain, I basically need a script that we can run on a server that will re-curse all directories and files looking at the ACL's for each. It will search the ACL for OLDDOMAIN\USER etc. if found change the ACL to NEWDOMAIN\USER but maintain all the permissions
Here is what I have so far
$access = ""
$accessarray = #()
$filesarray = #()
$permarray = #()
$filesarray = Get-ChildItem C:\Users -Recurse
ForEach($path in $filesarray) {
$pathcheck = $path.fullname
$access = get-acl $pathcheck
$accessarray = $access.AccessToString.Split(",")
foreach ($item in $accessarray) {
if ($item -match "OLDDOMAIN") {
Write-Host $pathcheck
Write-Host $item
$item = $item -replace ("OLDDOMAIN","NEWDOMAIN")
$permarray = $item.split(” “) | where-object {$_ -ne ”“}
foreach($perm in $permarray) {
$ar = New-Object system.security.accesscontrol.filesystemaccessrule $perm
$acl.SetAccessRule($ar)
$acl | Set-Acl $pathcheck
}
}
}
}
It works kind of, but the problem is that when it goes to reapply the permissions the array is not in the correct order and it fails at the set-acl command
Any ideas? Pulling my hair out here :P
Thanks
$ar = New-Object system.security.accesscontrol.filesystemaccessrule $perm
The constructor for FileSystemAccessRule takes 3 arguments, and after all your splitting and foreach, $perm will have only one argument and that construction itself will fail.
Avoid the splits etc. Powershell provides you objects. Operate on them. Don't get strings, then split etc.
You can do what you want with something like this:
gci c:\users -recurse | %{
$acl = get-acl $_.fullname
$acl.Access | ?{$_.IdentityReference.Value.StartsWith("OLDDOMAIN")} | %{
$identity = $_.IdentityReference.Value -replace "OLDDOMAIN", "NEWDOMAIN"
$permission = $identity,$_.FileSystemRights,$_.AccessControlType
$ar = New-Object system.security.accesscontrol.filesystemaccessrule $permission
$acl.SetAccessRule($ar)
}
$acl | set-acl $_.fullname
}