WisherTools.Helpers.psm1

#Region './Public/Get-DirectoryPath.ps1' -1

<#
.SYNOPSIS
Converts a base path to either a local or UNC path format.

.DESCRIPTION
This function converts a base path to a local path if the target is on the local computer, or to a UNC format if the target is on a remote computer.

.PARAMETER BasePath
The base directory path that needs to be converted.

.PARAMETER ComputerName
The name of the computer where the directory is located.

.PARAMETER IsLocal
Boolean value indicating if the target is local. If true, the function returns the local path format; if false, it returns a UNC path.

.EXAMPLE
Get-DirectoryPath -BasePath "C:\Files" -ComputerName "RemotePC" -IsLocal $false

Converts the local path "C:\Files" to a UNC path for the remote computer.

.OUTPUTS
System.String

.NOTES
#>


function Get-DirectoryPath {
    [CmdletBinding()]
    param (
        [Parameter(Mandatory = $true)]
        [string]$BasePath,

        [Parameter(Mandatory = $true)]
        [string]$ComputerName,

        [Parameter(Mandatory = $true)]
        [bool]$IsLocal  # Determines whether to return local or UNC format
    )

    if ($IsLocal) {
        # Convert UNC to local format
        $localPath = $BasePath -replace '(?:.+)\\([a-zA-Z])\$\\', '$1:\'
        return $localPath
    }
    else {
        # Convert local path to UNC format
        $uncPath = $BasePath -replace '^([a-zA-Z]):\\', "\\$ComputerName\`$1`$\"
        return $uncPath
    }
}
#EndRegion './Public/Get-DirectoryPath.ps1' 52
#Region './Public/Get-FunctionScriptBlock.ps1' -1

<#
.SYNOPSIS
Retrieves the script block of a specified PowerShell function.

.DESCRIPTION
This function dynamically retrieves the script block definition of a specified PowerShell function.
It can be used to examine the contents of an existing function in detail, including its implementation.

.PARAMETER FunctionName
The name of the function whose script block is to be retrieved.
This parameter is mandatory. If not provided, the user will be prompted to supply a value.

.EXAMPLE
Get-FunctionScriptBlock -FunctionName 'Get-Process'

Retrieves the script block of the 'Get-Process' function.

.EXAMPLE
Get-FunctionScriptBlock -FunctionName 'Test-Function'

Retrieves the script block of the 'Test-Function' if it exists.

.OUTPUTS
System.String
The full script block of the function as a string.

.NOTES
If the function does not exist or if it exists but has no body, the function will throw an error.
This function uses the `Get-Command` cmdlet to retrieve the function definition.
#>


function Get-FunctionScriptBlock
{
    [CmdletBinding()]
    [OutputType([string])]  # Add the OutputType attribute
    param (
        [Parameter(Mandatory = $true)]
        [string]$FunctionName
    )

    try
    {
        $functionBody = (Get-Command -Name $FunctionName).Definition
        if (-not $functionBody)
        {
            throw "Function '$FunctionName' exists but has no body."
        }

        $fullFunctionScript = @"
function $FunctionName {
    $functionBody
}
"@


        return $fullFunctionScript
    }
    catch
    {
        throw "Failed to retrieve the function '$FunctionName'. Error: $_"
    }
}
#EndRegion './Public/Get-FunctionScriptBlock.ps1' 62
#Region './Public/New-UniqueFilePath.ps1' -1

<#
.SYNOPSIS
Generates a unique file path with a timestamp.

.DESCRIPTION
The New-UniqueFilePath function creates a unique file name with a timestamp and returns the full path
to the specified directory. It uses environment variables as defaults for the directory, prefix, and
file extension, with fallback defaults if the variables are not set. The function checks if the directory
exists and writes a warning if it does not.

.PARAMETER Directory
Specifies the directory where the file will be saved. Defaults to the environment variable `FILE_DIRECTORY`
or the user's TEMP directory if not set.

.PARAMETER Prefix
Specifies the prefix for the file name. Defaults to the environment variable `FILE_PREFIX` or "File".

.PARAMETER Extension
Specifies the file extension, including the dot (e.g., ".txt"). Defaults to the environment variable `FILE_EXTENSION`
or ".txt".

.EXAMPLE
PS> New-UniqueFilePath -Directory "C:\Backups" -Prefix "UserBackup" -Extension ".reg"
C:\Backups\UserBackup_20240909_141500.reg

.EXAMPLE
PS> New-UniqueFilePath -Directory "C:\Logs" -Prefix "Log" -Extension ".log"
C:\Logs\Log_20240909_141500.log

#>

function New-UniqueFilePath
{
    [CmdletBinding(SupportsShouldProcess = $true, ConfirmImpact = 'Medium')]
    param (
        [string]$Directory = $env:FILE_DIRECTORY, # Default to environment variable
        [string]$Prefix = $env:FILE_PREFIX, # Default to environment variable
        [string]$Extension = $env:FILE_EXTENSION  # Default to environment variable
    )

    # Set fallback defaults if environment variables are not set
    if (-not $Directory)
    {
        $Directory = [System.IO.Path]::GetTempPath()  # Fallback to TEMP directory
        Write-Warning "Directory not specified. Using the fallback directory: $Directory"
    }

    if (-not $Prefix)
    {
        $Prefix = "File"  # Fallback to default prefix
    }

    if (-not $Extension)
    {
        $Extension = ".txt"  # Fallback to default file extension
    }

    # Check if the directory exists and use ShouldProcess for creating the directory
    if (-not (Test-Path -Path $Directory))
    {
        if ($PSCmdlet.ShouldProcess("Directory '$Directory'", "Creating new directory"))
        {
            Write-Warning "Directory '$Directory' does not exist. Creating it now."
            New-Item -Path $Directory -ItemType Directory -Force | Out-Null
        }
    }

    # Generate a unique file name with a timestamp
    $dateTimeStamp = (Get-Date -Format "yyyyMMdd_HHmmss")
    $fileName = "$Prefix`_$dateTimeStamp$Extension"
    $filePath = Join-Path -Path $Directory -ChildPath $fileName

    return $filePath
}
#EndRegion './Public/New-UniqueFilePath.ps1' 74
#Region './Public/Test-ComputerPing.ps1' -1

<#
.SYNOPSIS
Pings a computer to check if it is online.

.DESCRIPTION
This function sends a ping request to the specified computer and returns a boolean value indicating whether the computer is reachable. A configurable timeout can be specified for the ping.

.PARAMETER ComputerName
The name of the computer to be pinged.

.PARAMETER Timeout
The timeout value for the ping request in milliseconds. The default value is 2000 ms (2 seconds).

.EXAMPLE
Test-ComputerPing -ComputerName "RemotePC" -Timeout 3000

Pings the computer "RemotePC" with a timeout of 3 seconds to check if it's online.

.OUTPUTS
System.Boolean

.NOTES
#>


function Test-ComputerPing
{
    [CmdletBinding()]
    [OutputType([bool])]
    param (
        [Parameter(Mandatory = $true)]
        [string]$ComputerName,

        [Parameter(Mandatory = $false)]
        [int]$Timeout = 2000
    )

    try
    {
        $query = "Address='$ComputerName' AND Timeout=$Timeout"
        $pingResult = Get-CimInstance -ClassName Win32_PingStatus -Filter $query -ErrorAction Stop
        if ($pingResult.StatusCode -eq 0)
        {
            Write-Verbose "Computer '$ComputerName' is online."
            return $true
        }
        else
        {
            Write-Verbose "Computer '$ComputerName' is offline or unreachable (StatusCode: $($pingResult.StatusCode))."
            return $false
        }
    }
    catch
    {
        Write-Verbose "Failed to ping computer '$ComputerName'. Error: $_"
        return $false
    }
}
#EndRegion './Public/Test-ComputerPing.ps1' 58
#Region './Public/Test-DirectoryExistence.ps1' -1

<#
.SYNOPSIS
Ensures that a specified directory exists, and creates it if necessary.

.DESCRIPTION
This function checks whether a directory exists. If the directory does not exist, it creates the directory at the specified path.

.PARAMETER Directory
The path of the directory to check or create.

.EXAMPLE
Test-DirectoryExistence -Directory "C:\Backups"

Checks if the directory "C:\Backups" exists. If not, the function creates it.

.OUTPUTS
None

.NOTES
#>


function Test-DirectoryExistence {
    param (
        [string]$Directory
    )

    if (-not (Test-Path $Directory)) {
        New-Item -Path $Directory -ItemType Directory -Force | Out-Null
    }
}
#EndRegion './Public/Test-DirectoryExistence.ps1' 31