Knowledge Base

Preserving for the future: Shell scripts, AoC, and more

Save firefox profile to 7zip file

Because one of my workstations is a non-persistent environment, I wrote a script to backup my Firefox profile. It uses a few tricks to do what I want it to do-- serialize the filename, and encrypt even the filenames in the compressed file.

# File: \\storage2\c$\users\bgstack15\u_drive\vdi\save-firefox.ps1
# License: CC-BY-SA 4.0
# Author: bgstack15
# Startdate: 2019-11-05 11:24
# Title: Script that Saves Firefox Profile from VDI
# Purpose: Backup the entire Firefox directory because the VDI has nonpersistent sessions
# History:
# Usage:
# Reference:
#    https://stackoverflow.com/questions/20886243/press-any-key-to-continue/20886446#20886446
#    https://stackoverflow.com/questions/28352141/convert-a-secure-string-to-plain-text/28353003#28353003
# Improve:
# Documentation:
#  Assumptions:
#   The network location  has already been accessed, particularly because this script is hosted there and we need to dump a file there without having to authenticate.
#   7zip is installed in the VDI

# Define variables
# it is assumed I already access this network location so I do not need to authenticate
$outdir = "\\storage2\c$\users\bgstack15\u_drive\vdi"
$7z = "${env:ProgramFiles}\7-zip\7z.exe"
$today = Get-Date -Format yyyy-MM-dd
$indir = "${env:APPDATA}\Mozilla\Firefox"

# Functions
Function MyWait {
   Write-Host -NoNewLine 'Press any key to continue...'
   $null = $Host.UI.RawUI.ReadKey('NoEcho,IncludeKeyDown')
}

Function ToPlainText {
    param(
        [Parameter(ValueFromPipeline=$true)]$inSecureString
    )
    #$inSecureString = ConvertTo-SecureString $PlainPassword
    $BSTR = [System.Runtime.InteropServices.Marshal]::SecureStringToBSTR($inSecureString)
    $outPlainString = [System.Runtime.InteropServices.Marshal]::PtrToStringAuto($BSTR)
    [System.Runtime.InteropServices.Marshal]::ZeroFreeBSTR($BSTR)
    Return $outPlainString
}

######
# Main

# learn filename to use
$outfile = $outdir + "\firefox." + $today
# if file exists, change name.
$num=0
while (Test-Path "${outfile}.${num}.7z")
{
   write-Host "Incrementing because ${outfile}.${num}.7z exists..."
   $num++;
}
$outfile="${outfile}.${num}.7z"

# prompt for password
$pass1 = Read-Host -AsSecureString -Prompt "Generate a password"
$pass2 = Read-Host -AsSecureString -Prompt "Enter the password again"

# validate passwords
if (($pass1 | ToPlainText) -ne ($pass2 | ToPlainText))
{
   Write-Error -Category InvalidData -ErrorId "PasswordsMismatched" "Passwords do not match. Aborted."
   Exit 1
}
$passparam="-p$($pass1 | ToPlainText)"

# archive
Write-Host "$7z" -ArgumentList $passparam,"a","${outfile}",$indir
Start-Process -Wait -NoNewWindow "$7z" -ArgumentList "-mhe=on","$passparam","a","${outfile}",$indir

Comments