pf-encrypt.ps1

# TODO: To be partially replaced with https://www.powershellgallery.com/packages/Microsoft.PowerShell.SecretManagement
# Install-Module -Name Microsoft.PowerShell.SecretManagement -AllowPrerelease
# Import-Module -Name Microsoft.PowerShell.SecretManagement

[string]$global:UnencryptedMark = 'Unencrypted'
[string]$global:EncryptedMark = 'Encrypted'

function New-Credential($username, [SecureString] $password) {
    $credPassword   = ConvertTo-SecureString $PASSWORD -AsPlainText -Force
    $cred = New-Object System.Management.Automation.PSCredential ($username, $credPassword )
    return $cred
}

function Get-SecureKey_Plain {
    param( 
        [Parameter(ValueFromPipeline=$true)]
        $secureKey
    )
    if ($secureKey -is [string]) {
        return $secureKey
    }
    $Ptr = [System.Runtime.InteropServices.Marshal]::SecureStringToCoTaskMemUnicode($secureKey)
    $plainValue = [System.Runtime.InteropServices.Marshal]::PtrToStringUni($Ptr)
    [System.Runtime.InteropServices.Marshal]::ZeroFreeCoTaskMemUnicode($Ptr)
    return $plainValue
}

function Set-SecureKey($name, $secureKey ){
    Set-Secret -Name $name -Secret $secureKey
}
function Set-SecureKey:::Test{
    $testKey = 'TestSet-SecureKey'
    $secret = 'AnySecret'
    Set-SecureKey -name $testKey -secureKey $secret
    $result = Get-SecureKey -name $testKey
    $result | Get-SecureKey_Plain | should -be $secret
}

function Get-SecureKey{
    param ( 
        [string]$name,
        [string]$prompt
    )

    $storedKey = Get-Secret -Name $name -AsPlainText  -ErrorAction SilentlyContinue
    if ($storedKey) {
        return $storedKey
    }

    if ( Test-Powershell_Editor ) {
        if ( -not $prompt) {
            $prompt =  $MyInvocation.InvocationName + " $name ?"
        }
        $secureKey = Read-Host -Prompt $prompt -AsSecureString
        Set-SecureKey -name $name -secureKey $secureKey
        $storedKey = Get-Secret -Name $name -AsPlainText 
        return $secureKey
    }

    throw "Secure String not found for $name`nRun the script in ISE to specify one or use Set-SecureKey"
}

function Set-Content_Encrypt {
   [CmdletBinding()]
    Param(
        [Parameter(ValueFromPipeline=$true)]
        $path,
        [validateLength(5,20)]
        [SecureString]$password,
        [string]$EncryptedMark = $EncryptedMark,
        [string]$UnencryptedMark = $UnencryptedMark
    )
    process {
        $path = Get-Path -path $path
        $filelist = Get-ChildItem -path $path -Filter "*.$UnencryptedMark.*" -re | Get-Path
    
        foreach($file in $filelist) {
            $outFileName = $file -replace $UnencryptedMark, $EncryptedMark
            $outFileName = "$outFileName.zip" | Update-String_Enclose '"'
            if ( test-path $outFileName ) {
                Remove-Item $outFileName -Force
            }
            $file = $file | Update-String_Enclose '"'
            Invoke-Exe 7z a $outFileName "$file" "-p$password" -y | Out-Null #nooutput
        }
    }
}

function Get-Unzip_Path {
    $unzip = (Get-Command unzip -ErrorAction SilentlyContinue).Source
    if (-not $unzip) {
        $unzip = 'C:\Program Files\Git\usr\bin\unzip.exe'
        if(-not (Test-Path $unzip)) {
            throw 'Unzip.exe not found'
        }
    }
    return $unzip
}

function Set-Content_UnEncrypt {
   [CmdletBinding()]
    Param(
        [Parameter(ValueFromPipeline=$true)]
        $path,
        [validateLength(5,20)]
        [SecureString]$password
    )
    begin {
        $unzip = Get-Unzip_Path
    }
    process {
        $path = Get-Path -path $path
        $outFolder = Split-Path $path -Parent
        $path = $path | Update-String_Enclose '"'
        $outFolder = $outFolder | Update-String_Enclose '"'
        Invoke-Exe $unzip -o -q -P $password $path -d $outFolder | Out-Null
    }
}

function Remove-UnEncrypted {
   [CmdletBinding()]
    Param(
        [Parameter(ValueFromPipeline=$true)]
        $path,
        $EncryptedMark = $EncryptedMark,
        $UnencryptedMark = $UnencryptedMark
    )
    process {
        $toRemove = Get-ChildItem -Path $path -Filter "*.$UnencryptedMark.*" -Recurse
        $toRemove | Remove-Item -Force -Verbose
    }
}

function Set-Content_Encrypt:::Example {
    $EncryptPassword = '1234567890'
    Set-Content_Encrypt -path $src -password $EncryptPassword
    Set-Content_UnEncrypt -path $src -password $EncryptPassword
}