<#


    .SYNOPSIS  

        Reset ownership and permissions for existing user data repository..

        Intended for folder redirection, roaming profiles, or simple home directory locations.


    .DESCRIPTION  


        Runs through a parent directory that contains folders named by Active Directory

        usernames. It assumes the folder name exactly aligns with existing SAMAccountName.

        If a match to an AD user is not made it will skip the folder.

        

        Also works with scenarios like student directories located in a root under separate

        subfolders like E:\Students\2020\user.name, E:\Students\2021\user.name, etc.


        Recursively takes ownership of each user directory and resets them to inherit

        permissions from the parent. After that it gives the username, System,

        Creator Owner, and Domain Admins. Then it sets ownership of each folder to the

        username.


        Giving the user ownership can be particularly important for folder redirection.


    .NOTES  


        File Name  : ResetPermissions.ps1

        Modified   : 01/06/2020

        Author     : Andrew Schott - andrew@joletec.com

        Requires   : PowerShell V3


    .LINK


        http://www.joletec.com


#>




# Add VB for input prompts

[void][Reflection.Assembly]::LoadWithPartialName('Microsoft.VisualBasic')


# Install/Import ActiveDirectory PS module if needed

if (Get-Module -ListAvailable -Name ActiveDirectory) {

    Import-Module ActiveDirectory

else {

    # Module not yet installed

    Install-WindowsFeature RSAT-AD-PowerShell

    Import-Module ActiveDirectory

}


# Domain name prompt

$domainTitle = 'Domain Name'

$domaintMsg = 'Enter the name of the Active Directory domain:'

$domainDefault = $(Get-ADDomain).DNSRoot

$domainAnswer = [Microsoft.VisualBasic.Interaction]::InputBox($domaintMsg, $domainTitle, $domainDefault)

If ($domainAnswer -eq ""){ EXIT } # Exit if user presses the cancel button or enters no string


# Target directory prompt

$targetTitle = 'Target Directory'

$targetMsg   = 'Enter the target root directory:'

$targetDefault = $PSScriptRoot

$targetAnswer = [Microsoft.VisualBasic.Interaction]::InputBox($targetMsg, $targetTitle, $targetDefault)

If ($targetAnswer -eq ""){ EXIT } # Exit if user presses the cancel button or enters no string


# Multiple roots like Student grad years 

$a = new-object -comobject wscript.shell

$addLevelAnswer = $a.popup("Is there a second level of directories between `nthe root and the user directories? `nEx) $targetAnswer\2020\user.name\",0,"Multiple Roots?",4)

if($addLevelAnswer -eq 6){

    $addLevel = $true

}Else{

    $addLevel = $false

    $addLevelNo = "out"

}


# Pause between each user folder?

$stepUsersAnswer = $a.popup("Pause between each user folder? `nWill ask to change at each interupt.",0,"Pause Between Users?",4)

if($stepUsersAnswer -eq 6){

    $global:stepUsers = $true

    $stepUsersIntroText = "Will pause after the first user folder is processed."

}Else{

    $global:stepUsers = $false

    $stepUsersIntroText = "Will not pause after the first user folder is processed."

}



Write-Host ""

Write-Host "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!" -ForegroundColor Red

Write-Host "!! DANGER This script will reassign ownership and permissions in the target path. !!" -ForegroundColor Red

Write-Host "!! Can take hours to run due to multiple recursive operations.                    !!" -ForegroundColor Red

Write-Host "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!" -ForegroundColor Red

Write-Host ""

Write-Host "=============================================="

Write-Host "Targeting $targetAnswer" -ForegroundColor Yellow

Write-Host "With$addLevelNo second tier sub-root folders" -ForegroundColor Yellow

Write-Host "On the $domainAnswer domain" -ForegroundColor Yellow

Write-Host $stepUsersIntroText -ForegroundColor Yellow

Write-Host "=============================================="

Write-Host ""

Write-Host "Ctrl-C to quit"



PAUSE



Function ProcessDirectories($target){

    ForEach ($d in $target){


        If ($d.Name -match '.V\d$'){


            # This directory is a profile version folder. Ex) andrew.schott.V6


            # Extract username by removing the version qualifier from the end of the directory name


            $dFullName = $d.FullName

            $dLength = $d.Name.Length

            $i = $d.Name.Substring(0,$dLength-3)



            # icacls options

            $Path = "$dFullName"

            $Continue = "/C"

            $Grant = "/grant:r"

            $Recursive = "/T"

            $Inherit = "/inheritance:e"

            $permission = ":(OI)(CI)(F)"

            $useraccount1 = "$domainDnsRoot\$i"

            $useraccount2 = "$domainDnsRoot\Domain Admins"

            $useraccount3 = "SYSTEM"

            $useraccount4 = "CREATOR OWNER"


            if (!(Get-ADUser -Filter "sAMAccountName -eq '$i'")) {

                "User $i does not exist in Active Directory."


            } else {


                # Take  ownership

                Invoke-Expression -Command ('takeown /F $Path /A /R /D Y')


                # Reset permissions to inherited

                Invoke-Expression -Command ('icacls $Path $Reset $Continue $Recursive')


                # Set permissions

                Invoke-Expression -Command ('icacls $Path $Continue $Inherit $Grant "${useraccount1}${permission}" $Recursive $Inherit $Grant "${useraccount2}${permission}" $Recursive $Inherit $Grant "${useraccount3}${permission}" $Recursive $Inherit $Grant "${useraccount4}${permission}" $Recursive')


                # Set ownership

                Invoke-Expression -Command ('icacls $Path $Owner $useraccount1 $Continue $Recursive')


            }


        }Else{


            # Primary user profile directory. Ex) andrew.schott


            $dName = $d.Name

            $dFullName = $d.FullName




            # icacls options


            $Path = "$dFullName"

            $Continue = "/C"

            $Grant = "/grant:r"

            $Inherit = "/inheritance:e"

            $Owner = "/setowner"

            $permission = ":(OI)(CI)(F)"

            $Recursive = "/T"

            $Reset = "/reset"

            $useraccount1 = "$domainDnsRoot\$dName"

            $useraccount2 = "$domainDnsRoot\Domain Admins"

            $useraccount3 = "SYSTEM"

            $useraccount4 = "CREATOR OWNER"


            if (!(Get-ADUser -Filter "sAMAccountName -eq '$dName'")) {

                "User $dName does not exist in Active Directory."


            } else {


                # Take recursive ownership

                Invoke-Expression -Command ('takeown /F $Path /A /R /D Y')


                # Reset Permissions to inherited

                Invoke-Expression -Command ('icacls $Path $Reset $Continue $Recursive')

 

                # Set permissions

                Invoke-Expression -Command ('icacls $Path $Continue $Inherit $Grant "${useraccount1}${permission}" $Recursive $Inherit $Grant "${useraccount2}${permission}" $Recursive $Inherit $Grant "${useraccount3}${permission}" $Recursive $Inherit $Grant "${useraccount4}${permission}" $Recursive')


                # Set ownership

                Invoke-Expression -Command ('icacls $Path $Owner $useraccount1 $Continue $Recursive')


            }


        }



        If ($global:stepUsers -eq $true) {

            # Chance to continue pausing between users or opt out of it

            $stepUsersAnswer = $a.popup("Pause between each user folder? `nWill ask to change at each interupt.",0,"Pause Between Users?",4)

            if($stepUsersAnswer -eq 6){

                $global:stepUsers = $true

            }Else{

                $global:stepUsers = $false

            }

        }



    }

}



# Check target root directory

try{

    $dir = Get-ChildItem $targetAnswer -Directory -ErrorAction Stop

}catch{

    Write-Host "ERROR - Target path incorrect, does not exist, or inaccessible." -ForegroundColor Red

    PAUSE

    EXIT

}



# Kick off process in root or process each subfolder in root as

If ($addLevel -eq $true){

    ForEach ($i in $dir){

        $ii = Get-ChildItem $i -Directory

        ProcessDirectories($ii)

    }

}Else{

    ProcessDirectories($dir)

}