Removing ALL user object permissions form ACL / Folder structure - powershell

I want to remove ALL AD User objects from a directory/folder security.
So, this maybe a stupid post and i appologise if it is...but basically i want to recurse through a directoery and remove all user objects from permissions. Folder permissions should be secured using groups, buit occasionally there are user onjects directly being added to folders breaking the rules. I've got a simple little script that works great for specific users, but i'm having trouble setting this to use a variable, eg all domain user accounts. If i specify the $user variable as an AD search for instance it just doesnt work, eg $USER = 'Get-ADuser -filter * -Server 'DOMAIN -properties SamAccountName | Select SamAccountName
I'm assumign this doesnt like the variable field set this way. Any help or advise much appreciated. Thanks.
$filepath = 'C:\Temp\ACLTesting'
$user = 'DOMAIN\USER'
Get-ChildItem $filePath -Recurse -Directory | ForEach-Object {
$acl = Get-Acl -Path $_.FullName
$acl.Access | Where-Object {
$_.IdentityReference.Value -eq $user
} | ForEach-Object {
$acl.RemoveAccessRule($_) | Out-Null
}
Set-Acl -Path $_.FullName -AclObject $acl
}
Unfortunately still cant get this to work using user variables... am i missing something or is this not a possible function? Thanks....
Putting this to one side for now as still cant get it to work and other things have cropped up to look at. Will revisit this at somepoint though. Any suggestions always welcome. Thanks.

Slightly modifying what you posted, try this …
$filepath = 'C:\Temp\ACLTesting'
$DomainUsers = (Get-ADUser -Filter *).SamAccountName
ForEach ($DomainUser in $DomainUsers)
{
Get-ChildItem $filePath -Recurse -Directory |
ForEach-Object {
$acl = Get-Acl -Path $_.FullName
$acl.Access |
Where-Object {
$_.IdentityReference.Value -eq $DomainUser
} |
ForEach-Object {
$acl.RemoveAccessRule($_) | Out-Null
}
Set-Acl -Path $_.FullName -AclObject $acl
}
}

Related

Powershell, Get access rights of shared files, format output?

I have some shared files set up for me for testing purposes, on a Windows Server 2016.
My given task is to get all the users, and their access rights to there shared files/folders.
I get the shared files with
Get-SmbShare | Select-Object -Property Name, Path
What I think I should do, is passing each share's path into
Get-Acl
So I came up with this:
$shares = Get-SmbShare | Where-Object Name -notlike "*$" | Select-Object Name
foreach ($share in $shares){
$path = "\\$env:COMPUTERNAME\" + $share.Name.ToString()
$FolderPath = dir -Directory -Path $path -Recurse -Force
Foreach ($Folder in $FolderPath) {
$Acl = Get-Acl -Path $Folder.FullName
foreach ($Access in $acl.Access)
{
$Folder.FullName;
$Access.IdentityReference;
$Access.FileSystemRights;
$Access.IsInherited
}
}
}
My question is: How could I format this output, so it looks readable, and/or is there a simpler, maybe cleaner to do what I intend to do?

Powershell get-acl from childitems that not equals foldername

At work we have a folder with lots of subfolders named like "MeyerS". (Lastname and the first letter of surname)
When I take a look at Get-ChildItem $path | Get-Acl the username equals the subfolder-name. But there is also a "SCHUELER\" in front of "MeyerS". This is what the output looks like a.e.: SCHUELER\MeyerS Allow Write, ReadAndExecute, Synchronize
Some subfolders don't have this kind of username. Now I want to output all these subfolders without this username- "combination".
With my first codesnippet I get all of them, but I really just want these specific ones.
I checked some similar questions, and found something. I modified it, but it shows all subfolders just without SCHUELER\MeyerS. I think I just need a small push to the right way.
The code so far:
$path = "R:\HOME"
$folders = Get-ChildItem $path | where {$_.psiscontainer}
foreach ($folder in $folders){
$domain = "domname"
$aclname = "ACLname"
$aclfullname ="$domain\$aclname"
Get-Acl | select -ExpandProperty Access | where {$_.identityreference -notcontains $aclfullname}
Write-Host $folder.FullName}
Short note: I tried a lot of variations with -noteq or -notlike.
What do I have to change?
If there is already an answer I really didn't know.
Sometimes it's really hard to enunciate yourself in another language. I hope you get my point.
Thanks.
$path = "R:\HOME"
$folders = Get-ChildItem $path | where {$_.psiscontainer}
foreach ($folder in $folders)
{
$domain = "domname"
$aclname = "ACLname"
$aclfullname ="$domain\$aclname"
$FoldersWithAclFullName = $null
$FoldersWithAclFullName = Get-Acl -Path $Folder `
| Select-Object -ExpandProperty Access `
| Where-Object -Property IdentityReference -ne -Value $aclfullname
if ( -not $FoldersWithAclFullName )
{
Write-Host $folder.FullName
}
}

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
}

Search AD users for a user

I have a query regarding searching AD.
I have written this piece of code for moving HomeDrives of users which does not have an AD account in the AD.
Get-ChildItem -LiteralPath "\\server1\path" -Force |
Where-Object {$_.PSIsContainer} |
ForEach-Object {
$Name = Split-Path -Path $_ -Leaf
$ADResult = ([adsisearcher]"(samaccountname=$Name)").Findone()
if (!($ADResult)) {
$sNewPath = "\\server1\newpath"
Move-Item -Path $_.Fullname -Destination $sNewPath -Force
}
}
The thing is that I want to run this from another server and the AD is on another server.But this:
$ADResult = ([adsisearcher]"(samaccountname=$Name)").Findone()
will run only if AD is on this server.
So I want to replace this line with a solution that can access AD which is on server2.
Can I use Get-ADUser or Search-ADAccount to achieve this?
I use:
Get-WmiObject Win32_UserAccount
You can specify the username with a filter.
Get-WmiObject Win32_UserAccount -filter 'name="username"'

Get names of folders not inheriting permissions

I'm trying to find all folders which do not inherit permissions.
This seems to work, sorta:
DIR "C:\temp" -directory -recurse | GET-ACL | select -ExpandProperty Access | ? -property IsInherited -eq $false
...but it leaves out the actual folder name.
How do I include folder names in the final output? It gets a little tricky for me because I need to filter on a property on an object (Access) within an object (whatever GET-ACL returns).
Any ideas?
Scratch that, I'm an idiot.
DIR "C:\temp" -directory -recurse | GET-ACL | where {$_.Access.IsInherited -eq $false}
I think other answers don't really match your request: the commands suggested give you all non-inherited access rule, but also an inheriting folder may have such rules.
I was looking for a better way to achieve your same goal, but at the moment this is the only way I've found:
Get-ChildItem C:\temp -recurse | Select #{Name='Path';Expression={$_.FullName}},#{Name='InheritedCount';Expression={(Get-Acl $_.FullName | Select -ExpandProperty Access | Where { $_.IsInherited }).Count}} | Where { $_.InheritedCount -eq 0 } | Select Path
The concept is: if a folder has at least 1 inherited access rule, then inheritance is enabled, if it has 0 inherited rules, inheritance is disabled.
All answers still seem like a workaround to me. I found this solution to actually answer the question asked (folders only):
$folders = gci -recurse C:\My\Path\Here
foreach ($path in $folders)
{
if ($path.PSIsContainer -eq $false)
{
continue
}
if ((get-acl $path.fullname).AreAccessRulesProtected -eq $true)
{
$path.fullname
}
}
For the .AreAccessRulesProtected property of the returned get-acl object:
True = inheritance has been disabled
False = inheritance is still enabled
Source for .AreAccessRulesProtected property:
https://petri.com/identify-folders-with-blocked-inheritance-using-powershell
I also confirmed with my own testing that this is the correct property for folder inheritance.
You can use Add-Member to add the path as a property on each ACE object:
dir c:\temp -Directory -Recurse | ForEach-Object {
$Path = $_.FullName
try {
Get-Acl $Path |
select -ExpandProperty Access |
where { $_.IsInherited -eq $false } |
Add-Member -MemberType NoteProperty -Name Path -Value $Path -PassThru
}
catch {
Write-Error $_
}
}
I also wrapped Get-Acl in a try block because it throws terminating errors.
Luca's answer gave me false positives for folders with [ in their names. Not sure why.
Adapted Rohn's script to print how many acls are actually not inherited from the parent. If folder has some out of all - it means the inheritance is enabled but some permissions are added manually, if all out of all - it means the inheritance is disabled.
Write-Output "`nNoninheritable permissions:`n"
dir "E:\Projects" -Directory -Recurse | ForEach-Object {
$Path = $_.FullName
try {
$TotalACLs = (Get-Acl $Path | select -ExpandProperty Access).Count
$InheritedCount = (Get-Acl $Path | select -ExpandProperty Access | where { $_.IsInherited -eq $false } | Add-Member -MemberType NoteProperty -Name Path -Value $Path -PassThru | Select Path).Count
if ($InheritedCount) {
Write-Output $InheritedCount" out of "$TotalACLs" in "$Path
}
}
catch {
Write-Error $_
}
}
The example result:
Noninheritable permissions:
2 out of 7 in E:\Projects\Active Project
2 out of 8 in E:\Projects\Active Projects\Claire\7. CHRISTMAS\
4 out of 4 in E:\Projects\Active Projects\Closed
Projects\Andrea\IT\14.07 Kath - CIMS