setuptestdir.ps1
<#PSScriptInfo .VERSION 1.0 .GUID 52d7a324-b4ed-4c89-95fb-64e1df90a240 .AUTHOR Paul@sexstone.com .COMPANYNAME Sexstone .COPYRIGHT .TAGS .LICENSEURI .PROJECTURI .ICONURI .EXTERNALMODULEDEPENDENCIES .REQUIREDSCRIPTS .EXTERNALSCRIPTDEPENDENCIES .RELEASENOTES #> <# .DESCRIPTION use setuptestdir.ps1 to create a demo directory to show script working safely. Find and fix folders with broken inheritance and unable to be accessed by admin use fix_no_access_folders.ps1 first, to makde all files visible then use fix_no_access_files.ps1 #> Param()# " # create base directorys and copy 2 files into each, 1 file inherited permissions, 1 file unique permissions # 1:inherited access + subfolder # 2:inherited access + subfolder - restricted file2 in root # 3:inherited access + subfolder - unrestricted folder, restricted subfolder, restricted file2 in root and subfolder # 4:inherited access + subfolder - restricted folder, unrestricted subfolder, restricted file2 in root and subfolder file2 # 5:inherited access + subfolder - restricted folder & subfolder, restricted file2 in root and subfolder total files 5 folder + 5 subfolders * 2 files each = 20 files confirmation of setup = ntfs visible 12 files, 22 directories visible directories = 1/3 of (dir /s count-2) " $testfolderprefix = "folder" #folder prefix for test folders $testroot = "c:\acltestroot\" #where the test files should be created including $testfileSrc = "c:\temp\testfile.png" #testfile to be copied into every folder as file1 and file 2 $restrictaccount = "Guest" #account that will be used to set as owner and access on restricted files and folder # **************************************** function set-owner start Function Set-Owner { <# .SYNOPSIS Changes owner of a file or folder to another user or group. .DESCRIPTION Changes owner of a file or folder to another user or group. .PARAMETER Path The folder or file that will have the owner changed. .PARAMETER Account Optional parameter to change owner of a file or folder to specified account. Default value is 'Builtin\Administrators' .PARAMETER Recurse Recursively set ownership on subfolders and files beneath given folder. .NOTES Name: Set-Owner Author: Boe Prox Version History: 1.0 - Boe Prox - Initial Version .EXAMPLE Set-Owner -Path C:\temp\test.txt Description ----------- Changes the owner of test.txt to Builtin\Administrators .EXAMPLE Set-Owner -Path C:\temp\test.txt -Account 'Domain\bprox Description ----------- Changes the owner of test.txt to Domain\bprox .EXAMPLE Set-Owner -Path C:\temp -Recurse Description ----------- Changes the owner of all files and folders under C:\Temp to Builtin\Administrators .EXAMPLE Get-ChildItem C:\Temp | Set-Owner -Recurse -Account 'Domain\bprox' Description ----------- Changes the owner of all files and folders under C:\Temp to Domain\bprox #> [cmdletbinding( SupportsShouldProcess = $True )] Param ( [parameter(ValueFromPipeline=$True,ValueFromPipelineByPropertyName=$True)] [Alias('FullName')] [string[]]$Path, [parameter()] [string]$Account = 'Builtin\Administrators', [parameter()] [switch]$Recurse ) Begin { #Prevent Confirmation on each Write-Debug command when using -Debug If ($PSBoundParameters['Debug']) { $DebugPreference = 'Continue' } Try { [void][TokenAdjuster] } Catch { $AdjustTokenPrivileges = @" using System; using System.Runtime.InteropServices; public class TokenAdjuster { [DllImport("advapi32.dll", ExactSpelling = true, SetLastError = true)] internal static extern bool AdjustTokenPrivileges(IntPtr htok, bool disall, ref TokPriv1Luid newst, int len, IntPtr prev, IntPtr relen); [DllImport("kernel32.dll", ExactSpelling = true)] internal static extern IntPtr GetCurrentProcess(); [DllImport("advapi32.dll", ExactSpelling = true, SetLastError = true)] internal static extern bool OpenProcessToken(IntPtr h, int acc, ref IntPtr phtok); [DllImport("advapi32.dll", SetLastError = true)] internal static extern bool LookupPrivilegeValue(string host, string name, ref long pluid); [StructLayout(LayoutKind.Sequential, Pack = 1)] internal struct TokPriv1Luid { public int Count; public long Luid; public int Attr; } internal const int SE_PRIVILEGE_DISABLED = 0x00000000; internal const int SE_PRIVILEGE_ENABLED = 0x00000002; internal const int TOKEN_QUERY = 0x00000008; internal const int TOKEN_ADJUST_PRIVILEGES = 0x00000020; public static bool AddPrivilege(string privilege) { try { bool retVal; TokPriv1Luid tp; IntPtr hproc = GetCurrentProcess(); IntPtr htok = IntPtr.Zero; retVal = OpenProcessToken(hproc, TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY, ref htok); tp.Count = 1; tp.Luid = 0; tp.Attr = SE_PRIVILEGE_ENABLED; retVal = LookupPrivilegeValue(null, privilege, ref tp.Luid); retVal = AdjustTokenPrivileges(htok, false, ref tp, 0, IntPtr.Zero, IntPtr.Zero); return retVal; } catch (Exception ex) { throw ex; } } public static bool RemovePrivilege(string privilege) { try { bool retVal; TokPriv1Luid tp; IntPtr hproc = GetCurrentProcess(); IntPtr htok = IntPtr.Zero; retVal = OpenProcessToken(hproc, TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY, ref htok); tp.Count = 1; tp.Luid = 0; tp.Attr = SE_PRIVILEGE_DISABLED; retVal = LookupPrivilegeValue(null, privilege, ref tp.Luid); retVal = AdjustTokenPrivileges(htok, false, ref tp, 0, IntPtr.Zero, IntPtr.Zero); return retVal; } catch (Exception ex) { throw ex; } } } "@ Add-Type $AdjustTokenPrivileges } #Activate necessary admin privileges to make changes without NTFS perms [void][TokenAdjuster]::AddPrivilege("SeRestorePrivilege") #Necessary to set Owner Permissions [void][TokenAdjuster]::AddPrivilege("SeBackupPrivilege") #Necessary to bypass Traverse Checking [void][TokenAdjuster]::AddPrivilege("SeTakeOwnershipPrivilege") #Necessary to override FilePermissions } Process { ForEach ($Item in $Path) { Write-Verbose "FullName: $Item" #The ACL objects do not like being used more than once, so re-create them on the Process block $DirOwner = New-Object System.Security.AccessControl.DirectorySecurity $DirOwner.SetOwner([System.Security.Principal.NTAccount]$Account) $FileOwner = New-Object System.Security.AccessControl.FileSecurity $FileOwner.SetOwner([System.Security.Principal.NTAccount]$Account) $DirAdminAcl = New-Object System.Security.AccessControl.DirectorySecurity $FileAdminAcl = New-Object System.Security.AccessControl.DirectorySecurity $AdminACL = New-Object System.Security.AccessControl.FileSystemAccessRule('Builtin\Administrators','FullControl','ContainerInherit,ObjectInherit','InheritOnly','Allow') $FileAdminAcl.AddAccessRule($AdminACL) $DirAdminAcl.AddAccessRule($AdminACL) Try { $Item = Get-Item -LiteralPath $Item -Force -ErrorAction Stop If (-NOT $Item.PSIsContainer) { If ($PSCmdlet.ShouldProcess($Item, 'Set File Owner')) { Try { $Item.SetAccessControl($FileOwner) } Catch { Write-Warning "Couldn't take ownership of $($Item.FullName)! Taking FullControl of $($Item.Directory.FullName)" $Item.Directory.SetAccessControl($FileAdminAcl) $Item.SetAccessControl($FileOwner) } } } Else { If ($PSCmdlet.ShouldProcess($Item, 'Set Directory Owner')) { Try { $Item.SetAccessControl($DirOwner) } Catch { Write-Warning "Couldn't take ownership of $($Item.FullName)! Taking FullControl of $($Item.Parent.FullName)" $Item.Parent.SetAccessControl($DirAdminAcl) $Item.SetAccessControl($DirOwner) } } If ($Recurse) { [void]$PSBoundParameters.Remove('Path') Get-ChildItem $Item -Force | Set-Owner @PSBoundParameters } } } Catch { Write-Warning "$($Item): $($_.Exception.Message)" } } } End { #Remove priviledges that had been granted [void][TokenAdjuster]::RemovePrivilege("SeRestorePrivilege") [void][TokenAdjuster]::RemovePrivilege("SeBackupPrivilege") [void][TokenAdjuster]::RemovePrivilege("SeTakeOwnershipPrivilege") } } #********************************************* function set-owner end $setuproot = $testroot + $testfolderprefix #concatenated path for setup #Creat directories and copy files and set security on file 2 in each folder For ($i=1; $i -le 5; $i++) { #Rootfolder setup $setupdir = $setuproot + $i md $setupdir #file1 $testfile1 = $setupdir + "\testfile1.png" copy $testfilesrc $testfile1 #file2 $testfile2 = $setupdir + "\testfile2.png" copy $testfileSrc $testfile2 #set restriction on file2, lock to guest fullcontrol and guest ownership $acl = get-acl $testfile2 $acl.SetAccessRuleProtection($true,$false) $Ar = New-Object System.Security.AccessControl.FileSystemAccessRule($restrictaccount, "FullControl", "Allow") $Acl.SetAccessRule($Ar) Set-Acl $testfile2 $acl Set-Owner $testfile2 -account $restrictaccount #subfolder setup $setupsubdir = $setupdir + "\Subfolder" md $setupsubdir #file1 $testfile1sub = $setupsubdir + "\testfile1.png" copy $testfilesrc $testfile1sub #file2 $testfile2sub = $setupsubdir + "\testfile2.png" copy $testfileSrc $testfile2sub #set restriction on file2, lock to guest fullcontrol and guest ownership $acl = get-acl $testfile2sub $acl.SetAccessRuleProtection($true,$false) $Ar = New-Object System.Security.AccessControl.FileSystemAccessRule($restrictaccount, "FullControl", "Allow") $Acl.SetAccessRule($Ar) Set-Acl $testfile2sub $acl Set-Owner $testfile2sub -account $restrictaccount } # restrict folder access : 3 sub $folder3sub = $setuproot + "3\subfolder" $acl = get-acl $folder3sub $acl.SetAccessRuleProtection($true,$false) $Ar = New-Object System.Security.AccessControl.FileSystemAccessRule("guest", "FullControl", "ContainerInherit,ObjectInherit", "None", "allow") $Acl.SetAccessRule($Ar) Set-Acl $folder3sub $acl Set-Owner $folder3sub -account 'guest' # restrict folder access : 4 $folder4 = $setuproot + "4" $acl = get-acl $folder4 $acl.SetAccessRuleProtection($true,$false) $Ar = New-Object System.Security.AccessControl.FileSystemAccessRule("guest", "FullControl", "ContainerInherit,ObjectInherit", "None", "allow") $Acl.SetAccessRule($Ar) Set-Acl $folder4 $acl Set-Owner $folder4 -account 'guest' # restrict folder access : 5 sub $folder5sub = $setuproot + "5\subfolder" $acl = get-acl $folder5sub $acl.SetAccessRuleProtection($true,$false) $Ar = New-Object System.Security.AccessControl.FileSystemAccessRule("guest", "FullControl", "ContainerInherit,ObjectInherit", "None", "allow") $Acl.SetAccessRule($Ar) Set-Acl $folder5sub $acl Set-Owner $folder5sub -account 'guest' # restrict folder access : 5 $folder5 = $setuproot + "5" $acl = get-acl $folder5 $acl.SetAccessRuleProtection($true,$false) $Ar = New-Object System.Security.AccessControl.FileSystemAccessRule("guest", "FullControl", "ContainerInherit,ObjectInherit", "None", "allow") $Acl.SetAccessRule($Ar) Set-Acl $folder5 $acl Set-Owner $folder5 -account 'guest' |