ManageDotFiles.psm1

function Backup-DotFiles {
<#
    .SYNOPSIS
    Backup your config files info Tar file.
 
    .DESCRIPTION
    Backup your dot files efficiently by providing an array of files or a text file containing files and folders.
 
    The text file must contains one file or folder by line.
 
    This command uses Tar.exe program, so Tar.exe must be in your Path.
 
    Tar is included in Windows 10 since the build 17063 (1803).
 
    Please use the rules below:
 
    +-----------+--------------------------+----------------------------+
    | | Folder | File |
    +-----------+--------------------------+----------------------------+
    | Text File | c:\temp\folderToBackup | c:\temp\fileToBackup.txt |
    +-----------+--------------------------+----------------------------+
    | Pipeline | "c:\temp\folderToBackup" | "c:\temp\fileToBackup.txt" |
    +-----------+--------------------------+----------------------------+
 
    .PARAMETER File
    Specifies text file containing files and folder you want to backup.
    Note: you cannot provide an array to this parameter. Unless you provide this array with a pipe.
 
    .PARAMETER TarFile
    Specifies the backup file. Tar file is an archive that will contains all files you add to.
 
    .PARAMETER Update
    Specifies if you want to add files or folder to the Tar file. If not specified a new Tar file is created.
 
    .INPUTS
    Object.
 
    .EXAMPLE
    PS> Get-Content YourDotFiles.txt | Backup-DotFiles -TarFile YourBackup.tar
 
    Description
    -----------
    This command take the content of YourDotFiles.txt and pipe the result to Backup-DotFiles to generate the Tar file with all files specified in text file.
 
    .EXAMPLE
    PS> Backup-DotFiles -File AnotherSetOfDotFiles.txt -TarFile YourBackup.tar -Update
 
    Description
    -----------
    With the Update parameter you can add another set of dot files to your Tar file. Identical files are updated only if the file provided has changed.
 
    Note: Tar.exe seems to not have inconsistent behaviour with update or append options. Sometimes, even if the file has not been modified, the file is append into the Tar file.
 
    .EXAMPLE
    PS> "c:\temp\*","C:\Users\yann\AppData\Roaming\alacritty\alacritty.yml" | Backup-DotFiles -TarFile YourBackup.tar -Update
 
    Description
    -----------
    Update your Tar file with an array provided into the pipe.
 
    .LINK
    https://www.freebsd.org/cgi/man.cgi?query=bsdtar&apropos=0&sektion=1&manpath=FreeBSD+12.1-RELEASE&arch=default&format=html
#>

    [CmdletBinding()]
    param (
        [Parameter(
            Mandatory = $true,
            ValueFromPipeline = $true,
            parametersetname = "nopipeline"
        )]
        [string[]]
        $File,
        [Parameter(
            Mandatory = $true
        )]
        [string]
        $TarFile,
        [Parameter(
            Mandatory = $false
        )]
        [Switch]
        $Update
    )

    Begin {
        [bool]$script:isFirst = $true
        $InformationPreference = 'continue'
    }

    Process {
        $ScriptBlockMain = {
            param(
                $TarFile
            )
            if ($Update) {
                if (Test-Path $TarFile) {
                    Start-Process -FilePath tar.exe -ArgumentList "-vPuf",$TarFile,`"$_`" -NoNewWindow -Wait
                } else {
                    Write-Warning "Tar File must exists to update"
                    Break
                }
            } else {
                if ($script:isFirst) {
                    if (Test-Path $TarFile) {
                        $TarFileName = $(get-item .\tarfile.tar).Name
                        Write-Information "Tar file $TarFileName exists."
                        $answer = Read-Host "Do you want to overwrite it?([Y]es/[N]o)"
                        if ($answer -eq 'n') {
                            Write-Information "$TarFileName unchanged."
                            Break
                        } else {
                            Write-Information "Erasing $TarFileName with new data."
                        }
                    }
                    Start-Process -FilePath tar.exe -ArgumentList "-vPcf",$TarFile,`"$_`" -NoNewWindow -Wait
                    $script:isFirst = $false
                } else {
                    Start-Process -FilePath tar.exe -ArgumentList "-vPuf",$TarFile,`"$_`" -NoNewWindow -Wait
                }
            }
        }

        if ($_ -eq $null) {
            Try {
                if (Test-Path -LiteralPath $file -PathType Leaf) {
                    Get-Content $file | ForEach-Object {
                        Invoke-Command -ScriptBlock $ScriptBlockMain -ArgumentList $TarFile
                    }
                } else {
                    Write-Warning "You must provide a valid text file."
                    return
                }
            }
            Catch {
                return $_.Exception.Message
            }
            return
        }

        Invoke-Command -ScriptBlock $ScriptBlockMain -ArgumentList $TarFile,$isFirst
    }
}

function Restore-DotFiles {
<#
    .SYNOPSIS
    Restore your dot files
 
    .DESCRIPTION
    Restore all dot files from a Tar file.
 
    .EXAMPLE
    PS> Restore-DotFiles -TarFile YourBackup.tar
#>

    [CmdletBinding()]
    param (
        [Parameter(
            Mandatory = $true
        )]
        [string]
        $TarFile
    )

    Process {
        Start-Process -FilePath tar.exe -ArgumentList "-vPxf",$TarFile -NoNewWindow -Wait
    } 
}

function Get-DotFiles {
 <#
    .SYNOPSIS
    List files contained in Tar file
 
    .DESCRIPTION
    List all dot files contained in specified Tar file.
 
    .EXAMPLE
    PS> Get-DotFiles -TarFile YourBackup.tar
 
    Description
    -----------
    List all the files contained in Tar file.
 
    .EXAMPLE
    PS> Get-DotFiles YourBackup.tar | Sort-Object
 
    Description
    -----------
    List all the files contained in Tar file then sort them alphabetically.
#>

    [CmdletBinding()]
    param (
        [Parameter(
            Mandatory = $true
        )]
        [string]
        $TarFile
    )

    Begin {
        $ScriptBlockGetDotFiles = {
            param(
                $TarFile
            )
            tar.exe "-tf" $TarFile
        }
    }

    Process {
        Invoke-Command -ScriptBlock $ScriptBlockGetDotFiles -ArgumentList $TarFile
    }
}