VerifyDIR.psm1

<#
    ===========================================================================
     Created by: Rhys M
     Contact: RhysM.PS@gmail.com
     PS Gallery: https://www.powershellgallery.com/profiles/RhysM/
 
     Filename: VerifyDIR.psm1
    -------------------------------------------------------------------------
     Module Name: VerifyDIR
    ===========================================================================
 
    For example usage and detailed information for each command, Please type:
    Get-Help VerifyDIR -Detailed
    Get-Help VerifyDIR-Create -Detailed
    Get-Help VerifyDIR-CreateStructure -Detailed
    Get-Help VerifyDIR-Delete -Detailed
    Get-Help VerifyDIR-Recurse -Detailed
 
    This will funciton on PowerShell 2.0, However - Filesize component will not.
    Minimum PowerShell version required for Filesize component is PowerShell 3.0
 
#>


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

function VerifyDIR
{
    Param (
        [Parameter(Position = 0, Mandatory = $True, ValueFromPipeline = $true, HelpMessage = "Folder path you want to utilise")]
        $Path
    )
    
    foreach ($Directory in $Path)
    {
        Write-Output ""
        Write-Output "Performing Verification on Directory: "
        Write-Output $Directory
        
        $Path_Verify = Test-Path $Directory
        
        If ($Path_Verify -eq $True)
        {
            Write-Output "Confirmed - Specified Directory Allready Exists"
            Write-Output ""
        }
        Else
        {
            Write-Output ""
            Write-Output "Confirmed - Specified Directory Does Not Exist"
            Write-Output ""
        }
        
    }
    
}

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

function VerifyDIR-Create
{
    Param (
        [Parameter(Position = 0, Mandatory = $True, ValueFromPipeline = $true, HelpMessage = "Folder path you want to utilise")]
        $Path
    )
    
    foreach ($Directory in $Path)
    {
        Write-Output ""
        Write-Output "Creating the following directory structure: "
        Write-Output $Directory
        
        $Path_Verify = Test-Path $Directory
        
        If ($Path_Verify -eq $True)
        {
            
            Write-Output ""
            Write-Output "Specified Directory Allready Exists - Creation Not Required"
            Write-Output ""
        }
        Else
        {
            Write-Output ""
            Write-Output "Confirmed - Specified Directory Does Not Exist - Creating"
            New-Item $Directory -type directory
            Write-Output ""
            Write-Output "Specified Directory: $Directory - Created."
        }
        
    }
    
}

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

function VerifyDIR-CreateStructure
{
    Param (
        [Parameter(Position = 0, Mandatory = $True, ValueFromPipeline = $true, HelpMessage = "Folder path you want to utilise")]
        $Path,
        [Parameter(Position = 1, Mandatory = $True, HelpMessage = "Folder(s) you would like created within the specified Path")]
        $Structure
    )
    
    
    
    Function RecursiveStructureCreation
    {
        
        $RequiredStructure = @($Structure)
        
        $RecursiveExamination = @(Get-Item $Path -Exclude $Structure -Force) + (Get-ChildItem $Path -Exclude $Structure -Recurse -Force) | sort pspath -Descending -unique
        
        foreach ($Directory in $RecursiveExamination)
        {
            
            $FullName = $Directory.FullName
            
            foreach ($NewFolderName in $RequiredStructure)
            {
                
                $NewStructure = ($FullName + "\" + $NewFolderName)
                
                $Path_Verify = Test-Path $NewStructure
                
                If ($Path_Verify -eq $False)
                {
                    New-Item -ItemType Directory -Path $NewStructure | out-null
                    
                    Write-Output "Directory Created: $NewFolderName"
                    Write-Output "Path: $NewStructure"
                }
                else
                {
                    
                    Write-Output ""
                    Write-Output "Directory: $NewFolderName Allready Exists - Skipping"
                    Write-Output "Path: $NewStructure"
                    
                }
            }
            
        }
        
    }
    
    Write-Output ""
    Write-Output "Creating the following directory structure"
    Write-Output $Path
    
    $Path_Verify = Test-Path $Path
    
    If ($Path_Verify -eq $True)
    {
        
        Write-Output ""
        Write-Output "Specified Top Level Directory Allready Exists - Creation Not Required"
        Write-Output ""
        Write-Output "Performing Sub Content Creation"
        RecursiveStructureCreation
    }
    Else
    {
        Write-Output ""
        Write-Output "Confirmed - Specified Top Level Directory Does Not Exist - Creating"
        New-Item -ItemType Directory -Path $Path | out-null
        RecursiveStructureCreation
    }
    
}

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

function VerifyDIR-Delete
{
    [cmdletbinding()]
    Param (
        [Parameter(Position = 0, Mandatory = $True, ValueFromPipeline = $true, HelpMessage = "Folder path you want to utilise")]
        $Path
    )
    
    foreach ($Directory in $Path)
    {
        Write-Output ""
        Write-Output "Validating the specified directory structure exists:"
        Write-Output $Directory
        
        $Path_Verify = Test-Path $Directory
        
        If ($Path_Verify -eq $False)
        {
            
            Write-Output ""
            Write-Output "Specified Directory Does Not Exist - Deletion Not Required"
            Write-Output ""
        }
        Else
        {
            Write-Output ""
            Write-Output "Confirmed - Specified Directory Exists - Deleting"
            
            function RecursiveDelete
            {
                $RecursiveExamination = @(Get-Item $Directory -Force) + (Get-ChildItem $Directory -Recurse -Force) | sort pspath -Descending -unique
                $GLOBAL:FolderCount = 0
                $GLOBAL:FileCount = 0
                
                foreach ($Item in $RecursiveExamination)
                {
                    
                    $FullName = $Item.FullName
                    $ItemName = $Item.Name
                    
                    $TypeExamination = (get-item $FullName) -is [System.IO.DirectoryInfo]
                    
                    if ($TypeExamination -eq $True)
                    {
                        Write-Output ""
                        Write-Output "Directory: $ItemName"
                        Write-Output $FullName
                        $GLOBAL:FolderCount++
                        Write-Output "Removing: $ItemName"
                        Remove-Item $FullName -recurse -force -ErrorAction SilentlyContinue
                        Write-Output "$ItemName - Removed"
                        
                    }
                    else
                    {
                        Write-Output ""
                        Write-Output "File: $ItemName"
                        Write-Output $FullName
                        $GLOBAL:FileCount++
                        Write-Output "Removing: $ItemName"
                        Remove-Item $Item -recurse -force -ErrorAction SilentlyContinue
                        Write-Output "$ItemName - Removed"
                    }
                    
                    
                }
                Write-Output ""
                Write-Output "---------------------"
                Write-Output "Directories Removed: $GLOBAL:FolderCount"
                Write-Output "Files Removed: $GLOBAL:FileCount"
                Write-Output "---------------------"
            }
            RecursiveDelete
            
            
            Write-Output ""
            Write-Output "Specified Directory Structure: $Directory - Deleted."
        }
        
    }
    
}

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

function VerifyDIR-Recurse
{
    Param (
        [Parameter(Position = 0, Mandatory = $True, ValueFromPipeline = $true, HelpMessage = "Folder path you want to utilise")]
        $Path
    )
    
    foreach ($Directory in $Path)
    {
        Write-Output ""
        Write-Output "Validating the specified directory structure exists:"
        Write-Output $Directory
        
        $Path_Verify = Test-Path $Directory
        
        If ($Path_Verify -eq $True)
        {
            
            Write-Output ""
            Write-Output "Confirmed - Specified Directory Allready Exists"
            Write-Output ""
            Write-Output "Items Discovered: "
            
            function RecursiveSearch
            {
                
                function Get-FolderSize
                {
                    # Function created by:
                    # Michael Simmons
                    # http://ilovepowershell.com/2015/09/10/get-a-folder-size-with-powershell/
                    
                    # Embedded within this module to ensure output results provide reletive informaiton.
                    
                    [CmdletBinding()]
                    Param (
                        [Parameter(Mandatory = $true, ValueFromPipeline = $true)]
                        $ExaminePath,
                        [ValidateSet("KB", "MB", "GB")]
                        $Units = "MB"
                    )
                    if ((Test-Path $ExaminePath) -and (Get-Item $ExaminePath -force).PSIsContainer)
                    {
                        $Measure = Get-ChildItem $Path -Recurse -Force -ErrorAction SilentlyContinue | Measure-Object -Property Length -Sum
                        $Sum = $Measure.Sum / "1$Units"
                        [PSCustomObject]@{
                            "Path"              = $ExaminePath
                            "Size($Units)"    = $Sum
                        }
                    }
                }
                function Get-FileSize
                {
                    # Function created by:
                    # Martin Schvartzman
                    # https://blogs.technet.microsoft.com/pstips/2017/05/20/display-friendly-file-sizes-in-powershell/
                    
                    # Embedded within this module to ensure output results provide reletive informaiton.
                    
                    param ($Bytes)
                    $sizes = 'Bytes,KB,MB,GB,TB,PB,EB,ZB' -split ','
                    for ($i = 0; ($Bytes -ge 1kb) -and
                        ($i -lt $sizes.Count); $i++) { $Bytes /= 1kb }
                    $N = 2; if ($i -eq 0) { $N = 0 }
                    "{0:N$($N)} {1}" -f $Bytes, $sizes[$i]
                }
                
                $RecursiveExamination = @(Get-Item $Directory -Force) + (Get-ChildItem $Directory -Recurse -Force) | sort pspath -Descending -unique
                $GLOBAL:FolderCountGLOBAL:FolderCount = 0
                $GLOBAL:FileCount = 0
                
                foreach ($Item in $RecursiveExamination)
                {
                    
                    $FullName = $Item.FullName
                    $ItemName = $Item.Name
                    $ItemAttributes = $Item.Attributes
                    
                    $TypeExamination = (get-item $FullName -Force) -is [System.IO.DirectoryInfo]
                    
                    if ($TypeExamination -eq $True)
                    {
                        
                        if ($ItemAttributes -like "*Hidden*")
                        {
                            
                            $FileSizeOutput = Get-FolderSize $FullName -erroraction silentlycontinue
                            $TotalFileSize = $FileSizeOutput.'Size(MB)'
                            Write-Output ""
                            Write-Output "Hidden Directory: $FolderName"
                            Write-Output "Size (MB): $TotalFileSize"
                            Write-Output $FullName
                            $GLOBAL:FolderCount++
                            Write-Output ""
                            
                            
                        }
                        
                        else
                        {
                            
                            $FileSizeOutput = Get-FolderSize $FullName -erroraction silentlycontinue
                            $TotalFileSize = $FileSizeOutput.'Size(MB)'
                            Write-Output ""
                            Write-Output "Directory: $ItemName"
                            Write-Output "Size (MB): $TotalFileSize"
                            Write-Output $FullName
                            $GLOBAL:FolderCount++
                            Write-Output ""
                        }
                        
                    }
                    else
                    {
                        if ($ItemAttributes -like "*Hidden*")
                        {
                            
                            $FileSizeOutput = Get-Item -path $FullName -force | Select-Object -Property @{ N = 'FileSize'; E = { Get-FileSize -Bytes $_.Length } }
                            $FileSizeOutput_FileSize = $FileSizeOutput.FileSize
                            Write-Output "Hidden File: $ItemName"
                            Write-Output "File Size: $FileSizeOutput_FileSize"
                            $GLOBAL:FileCount++
                        }
                        else
                        {
                            
                            $FileSizeOutput = Get-Item -path $FullName -force | Select-Object -Property @{ N = 'FileSize'; E = { Get-FileSize -Bytes $_.Length } }
                            $FileSizeOutput_FileSize = $FileSizeOutput.FileSize
                            Write-Output "File: $ItemName"
                            Write-Output "File Size: $FileSizeOutput_FileSize"
                            $GLOBAL:FileCount++
                        }
                    }
                }
                
                Write-Output ""
                Write-Output "---------------------"
                Write-Output "Directories Discovered: $GLOBAL:FolderCount"
                Write-Output "Files Discovered: $GLOBAL:FileCount"
                Write-Output "---------------------"
            }
            
            
            
            RecursiveSearch
        }
        
        Else
        {
            Write-Output ""
            Write-Output "Confirmed - Specified Directory Does Not Exist"
            Write-Output ""
        }
        
    }
}

function VerifyDIR-DuplicateStructure
{
    Param (
        [Parameter(Position = 0, Mandatory = $True, ValueFromPipeline = $true, HelpMessage = "Folder path you want to Duplicate")]
        $Path,
        [Parameter(Position = 1, Mandatory = $True, ValueFromPipeline = $true, HelpMessage = "Destination Directory")]
        $Destination,
        [Parameter(Position = 2, Mandatory = $False, HelpMessage = "Maintain Directory Permissions")]
        [switch]$MaintainPermissions
    )
    
    foreach ($Directory in $Path)
    {
        Write-Output ""
        Write-Output "Creating the following directory structure: "
        Write-Output $Directory
        
        $Path_Verify = Test-Path $Directory
        
        If ($Path_Verify -eq $True)
        {
            If ($MaintainPermissions)
            {
                Write-Output ""
                Write-Output "Specified Directory Exists - Proceeding With Structure Duplication."
                Write-Output "Maintaining Permissions."
                Get-ChildItem -Path $Path | Where-Object { $_.PSIsContainer } | ForEach-Object{
                    $newFolder = Copy-Item -LiteralPath $_.FullName -Destination $Destination -Filter { PSIsContainer } -PassThru -Recurse -Force
                    Get-Acl -Path $_.FullName | Set-Acl -Path $newFolder.FullName
                }
            }
            Else
            {
                Write-Output ""
                Write-Output "Specified Directory Exists - Proceeding With Structure Duplication."
                Write-Output ""
                Copy-Item -Path $Path -Destination $Destination -Filter { PSIsContainer } -Recurse -Force
            }
            
        }
        Else
        {
            Write-Output ""
            Write-Output "Specified Directory Does Not Exist - $Directory"
            Write-Output ""
        }
    }
    
}


Export-ModuleMember -Function VerifyDIR,
                    VerifyDIR-Create,
                    VerifyDIR-CreateStructure,
                    VerifyDIR-Delete,
                    VerifyDIR-Recurse,
                    VerifyDIR-DuplicateStructure