EffectiveAccess.psm1

<#
    ===========================================================================
     Created by: Rhys M
     Contact: RhysM.PS@gmail.com
     PS Gallery: https://www.powershellgallery.com/profiles/RhysM/
 
     Filename: EffectiveAccess.psm1
    -------------------------------------------------------------------------
     Module Name: EffectiveAccess
    ===========================================================================
#>


<#
    .EXTERNALHELP EffectiveAccess.psm1-Help.xml
#>

Function EffectiveAccess
{
    Param (
        [Parameter(Position = 0, Mandatory = $True, HelpMessage = "Folder Path To Recursively Examine")]
        $Path,
        [Parameter(Position = 1, Mandatory = $False, HelpMessage = "Account Permissions To List")]
        $Account,
        [Parameter(Position = 2, Mandatory = $False, HelpMessage = "Perform a recursive examination")]
        [switch]$Recurse,
        [Parameter(Position = 3, Mandatory = $False, HelpMessage = "Include files with the output, otherwise it is just directories")]
        [switch]$IncludeFiles
        
    )
    
    If ($Recurse)
    {
        If ($IncludeFiles)
        {
            $Items = Get-childitem $Path -recurse
        }
        else
        {
            $Items = Get-childitem $Path -recurse | where { $_.psiscontainer }
        }
    }
    Else
    {
        If ($IncludeFiles)
        {
            $Items = Get-childitem $Path
        }
        else
        {
            $Items = Get-childitem $Path | where { $_.psiscontainer }
        }
    }
    $t = 0
    $total = $Items.count
    $Items | Foreach-object {
        $t++
        Write-Progress -Id 1 -Activity "Data Gathering" -Status 'Collecting Directory Data' -PercentComplete ($t/$total * 100) -CurrentOperation 'Storing'
    }
    Write-Progress -id 1 -Activity "Data Gathering" -Completed
    $i = 0
    $tot = $Items.count
    $DataOutput = @()
    foreach ($Item in $Items)
    {
        $i++
        $status = "{0:N0}" -f ($i / $tot * 100)
        Write-Progress -id 2 -Activity "Processing Folders" -status "Processing Item $i of $tot : $status% Completed" -PercentComplete ($i / $tot * 100)
        $acl = Get-Acl -Path $item.FullName
        foreach ($access in $acl.Access)
        {
            $DataResults = New-Object -TypeName PSObject
            $DataResults | Add-Member -MemberType NoteProperty -Name FullName -Value $item.FullName
            $DataResults | Add-Member -MemberType NoteProperty -Name Account -value $access.IdentityReference
            $DataResults | Add-Member -MemberType NoteProperty -Name FileSystemRights -value $access.FileSystemRights
            $DataResults | Add-Member -MemberType NoteProperty -Name Inheritance -value $access.IsInherited
            $DataOutput += $DataResults
        }
    }
    if ($Account)
    {
        foreach ($PermissionListing in $DataOutput)
        {
            if ($PermissionListing.Account -like "$Account")
            {
                write-output $PermissionListing
            }
        }
    }
    Else
    {
        foreach ($PermissionListing in $DataOutput)
        {
            write-output $PermissionListing
        }
    }
    
    Write-Progress -id 2 -Activity "Processing Folders" -Completed
}

Function EffectiveAccess-Duplicate
{
    Param (
        [Parameter(Position = 0, Mandatory = $True, HelpMessage = "Folder Path To Recursively Examine")]
        $Path,
        [Parameter(Position = 1, Mandatory = $False, HelpMessage = "Account Permissions To List")]
        $Account,
        [Parameter(Position = 2, Mandatory = $False, HelpMessage = "Account to have permissions set for")]
        $DuplicateTo,
        [Parameter(Position = 3, Mandatory = $False, HelpMessage = "Include files with the output, otherwise it is just directories")]
        [switch]$IncludeFiles,
        [Parameter(Position = 4, Mandatory = $False, HelpMessage = "Perform a recursive examination")]
        [switch]$Recurse
    )
    
    If ($Recurse)
    {
        If ($IncludeFiles)
        {
            $Items = Get-childitem $Path -recurse
        }
        else
        {
            $Items = Get-childitem $Path -recurse | where { $_.psiscontainer }
        }
    }
    Else
    {
        If ($IncludeFiles)
        {
            $Items = Get-childitem $Path
        }
        else
        {
            $Items = Get-childitem $Path | where { $_.psiscontainer }
        }
    }
    
    $t = 0
    $total = $Items.count
    
    $Items | Foreach-object {
    $t++
    Write-Progress -Id 1 -Activity "Data Gathering" -Status 'Collecting Directory Data' -PercentComplete ($t/$total * 100) -CurrentOperation 'Storing'
    }
    Write-Progress -id 1 -Activity "Data Gathering" -Completed
    $i = 0
    $tot = $Items.count
    $DataOutput = @()
    foreach ($Item in $Items)
    {
        $i++
        $status = "{0:N0}" -f ($i / $tot * 100)
        Write-Progress -id 2 -Activity "Processing Folders" -status "Processing Item $i of $tot : $status% Completed" -PercentComplete ($i / $tot * 100)
        $Acl = (Get-Item -Path $item.FullName).GetAccessControl('Access').Access
        if ($Account)
        {
            if ($DuplicateTo)
            {
                foreach ($Record in $ACL)
                {
                    $FileSystemRights = $Record.FileSystemRights
                    $AccessControlType = $Record.AccessControlType
                    $IdentityReference = $Record.IdentityReference
                    $IsInherited = $Record.IsInherited
                    $InheritanceFlags = $Record.InheritanceFlags
                    $PropagationFlags = $Record.PropagationFlags
                    
                    if ($IdentityReference -like "$Account")
                    {
                        $Path = $HomeFolder.FullName
                        $Acl = (Get-Item -Path $item.FullName).GetAccessControl('Access')
                        $Username = $HomeFolder.Name
                        $Ar = New-Object System.Security.AccessControl.FileSystemAccessRule($DuplicateTo, "$FileSystemRights", "$InheritanceFlags", "$PropagationFlags", "$AccessControlType")
                        $Acl.SetAccessRule($Ar)
                        Set-Acl -path $item.FullName -AclObject $Acl
                        
                        $DataResults = New-Object -TypeName PSObject
                        $DataResults | Add-Member -MemberType NoteProperty -Name Directory -Value $item.FullName
                        $DataResults | Add-Member -MemberType NoteProperty -Name FileSystemRights -Value $FileSystemRights
                        $DataResults | Add-Member -MemberType NoteProperty -Name AccessControlType -value $AccessControlType
                        $DataResults | Add-Member -MemberType NoteProperty -Name IdentityReference -value $IdentityReference
                        $DataResults | Add-Member -MemberType NoteProperty -Name IsInherited -value $IsInherited
                        $DataResults | Add-Member -MemberType NoteProperty -Name InheritanceFlags -Value $InheritanceFlags
                        $DataResults | Add-Member -MemberType NoteProperty -Name PropagationFlags -Value $PropagationFlags
                        $DataOutput += $DataResults
                        $DataOutput
                    }
                }
            }
            else
            {
                foreach ($Record in $ACL)
                {
                    $FileSystemRights = $Record.FileSystemRights
                    $AccessControlType = $Record.AccessControlType
                    $IdentityReference = $Record.IdentityReference
                    $IsInherited = $Record.IsInherited
                    $InheritanceFlags = $Record.InheritanceFlags
                    $PropagationFlags = $Record.PropagationFlags
                    
                    $DataResults = New-Object -TypeName PSObject
                    $DataResults | Add-Member -MemberType NoteProperty -Name Directory -Value $item.FullName
                    $DataResults | Add-Member -MemberType NoteProperty -Name FileSystemRights -Value $FileSystemRights
                    $DataResults | Add-Member -MemberType NoteProperty -Name AccessControlType -value $AccessControlType
                    $DataResults | Add-Member -MemberType NoteProperty -Name IdentityReference -value $IdentityReference
                    $DataResults | Add-Member -MemberType NoteProperty -Name IsInherited -value $IsInherited
                    $DataResults | Add-Member -MemberType NoteProperty -Name InheritanceFlags -Value $InheritanceFlags
                    $DataResults | Add-Member -MemberType NoteProperty -Name PropagationFlags -Value $PropagationFlags
                    $DataOutput += $DataResults
                    
                    if ($IdentityReference -like "$Account")
                    {
                        $DataOutput
                    }
                }
            }
        }
        
        else
        {
            $FileSystemRights = $Record.FileSystemRights
            $AccessControlType = $Record.AccessControlType
            $IdentityReference = $Record.IdentityReference
            $IsInherited = $Record.IsInherited
            $InheritanceFlags = $Record.InheritanceFlags
            $PropagationFlags = $Record.PropagationFlags
            
            $DataResults = New-Object -TypeName PSObject
            $DataResults | Add-Member -MemberType NoteProperty -Name Directory -Value $item.FullName
            $DataResults | Add-Member -MemberType NoteProperty -Name FileSystemRights -Value $FileSystemRights
            $DataResults | Add-Member -MemberType NoteProperty -Name AccessControlType -value $AccessControlType
            $DataResults | Add-Member -MemberType NoteProperty -Name IdentityReference -value $IdentityReference
            $DataResults | Add-Member -MemberType NoteProperty -Name IsInherited -value $IsInherited
            $DataResults | Add-Member -MemberType NoteProperty -Name InheritanceFlags -Value $InheritanceFlags
            $DataResults | Add-Member -MemberType NoteProperty -Name PropagationFlags -Value $PropagationFlags
            $DataOutput += $DataResults
            $DataOutput
        }
    }
    
    Write-Progress -id 2 -Activity "Processing Folders" -Completed
    
}

Export-ModuleMember -Function EffectiveAccess, EffectiveAccess-Duplicate