Skip to content

Instantly share code, notes, and snippets.

Show Gist options
  • Save discarn8/fa71bfdf06f314dcb0fc935066572dab to your computer and use it in GitHub Desktop.
Save discarn8/fa71bfdf06f314dcb0fc935066572dab to your computer and use it in GitHub Desktop.
Save Your Windows Bookmarks and Export Your Installed Applications Using PowerShell
# Powershell Script
# Name: Save_Bookmarks_and_Export_Installed_Apps.ps1
# Date: 2022-06-02
# Ver: 1.3
#################################################################################################
#
# PLEASE READ ME FIRST !!!!
#
# PLEASE DEFINE YOUR OWN VARIABLES BEFORE RUNNING
# FOR THE FIRST TIME. CHANCES ARE, THAT THIS MAY
# RUN FINE, BUT ........
#
#################################################################################################
#################################################################################################
#
# D E F I N E T H E S E
# \/ \/ \/ \/ \/ \/ \/ \/ \/
#
#################################################################################################
# WHERE DO YOU WANT YOUR BACKUPS TO GO?
$HTML_File_Root = "d:\archive"
# WHAT DO YOU WANT THE FILENAME, OF THE LIST OF YOUR INSTALLED APPLICATIONS, TO BE?
$Filename = "Installed"
#################################################################################################
# END DEFINE
#################################################################################################
# Get the current Date / Time
$CurrTime = Get-Date -Format 'yyyyMMdd_HH.mm'
#Set this location to where you want the file to be placed
$Archive = "d:\archive"
# Change this filename, if you want a custom name
$Filename = "Installed"
# The final filename product
$Dest = "$($Archive)\$($Filename)_$($CurrTime)"
# Reference-Timestamp needed to convert Timestamps of JSON (Milliseconds / Ticks since LDAP / NT epoch 01.01.1601 00:00:00 UTC) to Unix-Timestamp (Epoch)
$Date_LDAP_NT_EPOCH = Get-Date -Year 1601 -Month 1 -Day 1 -Hour 0 -Minute 0 -Second 0
# Path to Edge Bookmark Files
$EdgeJSON_File_Path = "$($env:localappdata)\Microsoft\Edge\User Data\Default\Bookmarks"
$EdgeHTML_File_Path = "$($HTML_File_Root)\Edge-Bookmarks.backup_$($CurrTime).html"
# Path to Chromium Bookmark and Login Files
$ChromeJSON_File_Path = "$($env:localappdata)\Google\Chrome\User Data\Default\Bookmarks"
$ChromeLoginData = "$($env:localappdata)\Google\Chrome\User Data\Default\Login Data"
$ChromeLoginDataAccount = "$($env:localappdata)\Google\Chrome\User Data\Default\Login Data For Account"
$ChromeHTML_File_Path = "$($HTML_File_Root)\Chrome-Bookmarks.backup_$($CurrTime).html"
# Path to Firefox Bookmark and UserData Files
$FFJSON_File_Path = "$($env:localappdata)\Mozilla\Firefox\Profiles\bookmarkbackups"
$FF_Backups = "$($env:localappdata)\Mozilla\Firefox\Profiles\places.sqlite"
$FF_Passwords1 = "$($env:localappdata)\Mozilla\Firefox\Profiles\key4.db"
$FF_Passwords2 = "$($env:localappdata)\Mozilla\Firefox\Profiles\logins.json"
$FF_Certs = "$($env:localappdata)\Mozilla\Firefox\Profiles\cert9.db"
$FF_Dev = "$($env:localappdata)\Mozilla\Firefox\Profiles\pkcs11.txt"
$FF_PrefsDev = "$($env:localappdata)\Mozilla\Firefox\Profiles\prefs.js"
$FFHTML_File_Path = "$($HTML_File_Root)\Firefox-Bookmarks.backup_$($CurrTime).html"
echo ""
echo "STARTING BACKUPS ....."
echo "------------------------------------------------------------------------------"
# IF THE DESTINATION DOES NOT EXIST - STOP
if (!(Test-Path -Path $HTML_File_Root -PathType Container)) {
throw "Destination-Path $($HTML_File_Path) does not exist! Aborting"
}
#############################################
# BACKUP EDGE BOOKMARKS
#############################################
echo "Checking for Edge Bookmarks..."
# IF THE EDGE SOURCE DOES NOT EXIST - IGNORE THIS FOLDER
if (Test-Path -Path $EdgeJSON_File_Path -PathType Leaf) {
Copy-Item $EdgeJSON_File_Path "$($HTML_File_Root)\Edge_Bookmarks"
echo "Copied Edge Bookmarks File to $($HTML_File_Root)\Edge_Bookmarks ..."
# ---- HTML Header ----
$EdgeBookmarksHTML_Header = @'
<!DOCTYPE NETSCAPE-Bookmark-file-1>
<!-- This is an automatically generated file.
It will be read and overwritten.
DO NOT EDIT! -->
<META HTTP-EQUIV="Content-Type" CONTENT="text/html; charset=UTF-8">
<TITLE>Bookmarks</TITLE>
<H1>Bookmarks</H1>
<DL><p>
'@
echo "Starting convert of the Edge Bookmarks File to an HTML COPY..."
$EdgeBookmarksHTML_Header | Out-File -FilePath $EdgeHTML_File_Path -Force -Encoding utf8
# ---- Convert the JSON Contens (recursive) ----
$data = Get-content $EdgeJSON_File_Path -Encoding UTF8 | out-string | ConvertFrom-Json
$sections = $data.roots.PSObject.Properties | Select-Object -ExpandProperty name
ForEach ($entry in $sections) {
$data.roots.$entry | EdgeGet-BookmarkFolder
}
# ---- HTML Footer ----
'</DL>' | Out-File -FilePath $EdgeHTML_File_Path -Append -Force -Encoding utf8
echo "Edge bookmarks have been backed up to HTML at: $($EdgeHTML_File_Path)"
echo "------------------------------------------------------------------------------"
$sections = ""
$data = ""
$entry = ""
}else {
echo "No Edge Bookmarks folder found."
}
#############################################
# BACKUP CHROME BOOKMARKS
#############################################
echo "Checking for Chrome Bookmarks..."
# IF THE CHROME SOURCE DOES NOT EXIST - IGNORE THIS FOLDER
if (Test-Path -Path $ChromeJSON_File_Path -PathType Leaf) {
Copy-Item $ChromeJSON_File_Path "$($HTML_File_Root)\Chrome_Bookmarks"
Copy-Item $ChromeLoginData "$($HTML_File_Root)\Login Data"
Copy-Item $ChromeLoginDataAccount "$($HTML_File_Root)\Login Data For Account"
echo "Chrome Login Data Files Copied..."
echo "Chrome Bookmarks copied to $($HTML_File_Root)\Chrome_Bookmarks ..."
# ---- HTML Header ----
$BookmarksHTML_Header = @'
<!DOCTYPE NETSCAPE-Bookmark-file-1>
<!-- This is an automatically generated file.
It will be read and overwritten.
DO NOT EDIT! -->
<META HTTP-EQUIV="Content-Type" CONTENT="text/html; charset=UTF-8">
<TITLE>Bookmarks</TITLE>
<H1>Bookmarks</H1>
<DL><p>
'@
echo "Starting convert of the Chrome Bookmark File to an HTML COPY..."
$BookmarksHTML_Header | Out-File -FilePath $ChromeHTML_File_Path -Force -Encoding utf8
# ---- Convert the JSON Contens (recursive) ----
$data = Get-content $ChromeJSON_File_Path -Encoding UTF8 | out-string | ConvertFrom-Json
$sections = $data.roots.PSObject.Properties | Select-Object -ExpandProperty name
ForEach ($entry in $sections) {
$data.roots.$entry | ChromeGet-BookmarkFolder
}
# ---- HTML Footer ----
'</DL>' | Out-File -FilePath $ChromeHTML_File_Path -Append -Force -Encoding utf8
echo "Chrome bookmarks have been backed up to HTML at: $($ChromeHTML_File_Path)"
echo "------------------------------------------------------------------------------"
$sections = ""
$data = ""
$entry = ""
}else {
echo "No Chrome Bookmarks folder found."
}
#############################################
# BACKUP FIREFOX BOOKMARKS
#############################################
echo "Checking for Firefox Bookmarks..."
# IF THE FIREFOX SOURCE DOES NOT EXIST - IGNORE THIS FOLDER
if (Test-Path -Path $FFJSON_File_Path -PathType Leaf) {
Copy-Item $$FF_Backups "$($HTML_File_Root)\places.sqlite"
Copy-Item $$FF_Passwords1 "$($HTML_File_Root)\key4.db"
Copy-Item $$FF_Passwords1 "$($HTML_File_Root)\places.sqlite"
Copy-Item $$FF_Certs "$($HTML_File_Root)\cert9.db"
Copy-Item $$FF_Dev "$($HTML_File_Root)\pkcs11.txt"
Copy-Item $$FF_PrefsDev "$($HTML_File_Root)\prefs.js"
echo "Firefox Data Files Copied..."
echo "Firefox Bookmarks have been copied to $($HTML_File_Root)\places.sqlite ..."
# ---- HTML Header ----
$BookmarksHTML_Header = @'
<!DOCTYPE NETSCAPE-Bookmark-file-1>
<!-- This is an automatically generated file.
It will be read and overwritten.
DO NOT EDIT! -->
<META HTTP-EQUIV="Content-Type" CONTENT="text/html; charset=UTF-8">
<TITLE>Bookmarks</TITLE>
<H1>Bookmarks</H1>
<DL><p>
'@
$BookmarksHTML_Header | Out-File -FilePath $FFHTML_File_Path -Force -Encoding utf8
# ---- Convert the JSON Contents (recursive) ----
$data = Get-content $FFJSON_File_Path -Encoding UTF8 | out-string | ConvertFrom-Json
$sections = $data.roots.PSObject.Properties | Select-Object -ExpandProperty name
ForEach ($entry in $sections) {
$data.roots.$entry | FFGet-BookmarkFolder
}
# ---- HTML Footer ----
'</DL>' | Out-File -FilePath $FFHTML_File_Path -Append -Force -Encoding utf8
echo "Firefox bookmarks have been backed up to HTML at: $($FFHTML_File_Path)"
echo "------------------------------------------------------------------------------"
$sections = ""
$data = ""
$entry = ""
}else {
echo "No Firefox Bookmarks folder found."
}
#############################################
# DEFINE FUNCTIONS
#############################################
# ------ CONVERT NT_EPOCH TO UNIX
function ConvertTo-UnixTimeStamp {
param(
[Parameter(Position = 0, ValueFromPipeline = $True)]
$TimeStamp
)
$date = [Decimal] $TimeStamp
if ($date -gt 0) {
$date = $Date_LDAP_NT_EPOCH.AddTicks($date * 10)
$date = $date | Get-Date -UFormat %s
$unixTimeStamp = [int][double]::Parse($date) - 1
return $unixTimeStamp
}
}
# ---- Enumerate Edge's Bookmark Folders ----
Function EdgeGet-BookmarkFolder {
[cmdletbinding()]
Param(
[Parameter(Position = 0, ValueFromPipeline = $True)]
$Node
)
if ($node.name -like "Favorites Bar") {
$DateAdded = [Decimal] $node.date_added | ConvertTo-UnixTimeStamp
$DateModified = [Decimal] $node.date_modified | ConvertTo-UnixTimeStamp
" <DT><H3 FOLDED ADD_DATE=`"$($DateAdded)`" LAST_MODIFIED=`"$($DateModified)`" PERSONAL_TOOLBAR_FOLDER=`"true`">$($node.name )</H3>" | Out-File -FilePath $EdgeHTML_File_Path -Append -Force -Encoding utf8
" <DL><p>" | Out-File -FilePath $EdgeHTML_File_Path -Append -Force -Encoding utf8
}
foreach ($child in $node.children) {
$DateAdded = [Decimal] $child.date_added | ConvertTo-UnixTimeStamp
$DateModified = [Decimal] $child.date_modified | ConvertTo-UnixTimeStamp
if ($child.type -eq 'folder') {
" <DT><H3 ADD_DATE=`"$($DateAdded)`" LAST_MODIFIED=`"$($DateModified)`">$($child.name)</H3>" | Out-File -FilePath $EdgeHTML_File_Path -Append -Force -Encoding utf8
" <DL><p>" | Out-File -FilePath $EdgeHTML_File_Path -Append -Force -Encoding utf8
EdgeGet-BookmarkFolder $child # Recursive call in case of Folders / SubFolders
" </DL><p>" | Out-File -FilePath $EdgeHTML_File_Path -Append -Force -Encoding utf8
}
else {
# Type not Folder => URL
" <DT><A HREF=`"$($child.url)`" ADD_DATE=`"$($DateAdded)`">$($child.name)</A>" | Out-File -FilePath $EdgeHTML_File_Path -Append -Encoding utf8
}
}
if ($node.name -like "Favorites Bar") {
" </DL><p>" | Out-File -FilePath $EdgeHTML_File_Path -Append -Force -Encoding utf8
}
}
# ---- Enumerate Chrome's Bookmark Folders ----
Function ChromeGet-BookmarkFolder {
[cmdletbinding()]
Param(
[Parameter(Position = 0, ValueFromPipeline = $True)]
$Node
)
if ($node.name -like "Favorites Bar") {
$DateAdded = [Decimal] $node.date_added | ConvertTo-UnixTimeStamp
$DateModified = [Decimal] $node.date_modified | ConvertTo-UnixTimeStamp
" <DT><H3 FOLDED ADD_DATE=`"$($DateAdded)`" LAST_MODIFIED=`"$($DateModified)`" PERSONAL_TOOLBAR_FOLDER=`"true`">$($node.name )</H3>" | Out-File -FilePath $ChromeHTML_File_Path -Append -Force -Encoding utf8
" <DL><p>" | Out-File -FilePath $ChromeHTML_File_Path -Append -Force -Encoding utf8
}
foreach ($child in $node.children) {
$DateAdded = [Decimal] $child.date_added | ConvertTo-UnixTimeStamp
$DateModified = [Decimal] $child.date_modified | ConvertTo-UnixTimeStamp
if ($child.type -eq 'folder') {
" <DT><H3 ADD_DATE=`"$($DateAdded)`" LAST_MODIFIED=`"$($DateModified)`">$($child.name)</H3>" | Out-File -FilePath $ChromeHTML_File_Path -Append -Force -Encoding utf8
" <DL><p>" | Out-File -FilePath $ChromeHTML_File_Path -Append -Force -Encoding utf8
ChromeGet-BookmarkFolder $child # Recursive call in case of Folders / SubFolders
" </DL><p>" | Out-File -FilePath $ChromeHTML_File_Path -Append -Force -Encoding utf8
}
else {
# Type not Folder => URL
" <DT><A HREF=`"$($child.url)`" ADD_DATE=`"$($DateAdded)`">$($child.name)</A>" | Out-File -FilePath $ChromeHTML_File_Path -Append -Encoding utf8
}
}
if ($node.name -like "Favorites Bar") {
" </DL><p>" | Out-File -FilePath $ChromeHTML_File_Path -Append -Force -Encoding utf8
}
}
# ---- Enumerate Firefox's Bookmark Folders ----
Function FFGet-BookmarkFolder {
[cmdletbinding()]
Param(
[Parameter(Position = 0, ValueFromPipeline = $True)]
$Node
)
if ($node.name -like "Favorites Bar") {
$DateAdded = [Decimal] $node.date_added | ConvertTo-UnixTimeStamp
$DateModified = [Decimal] $node.date_modified | ConvertTo-UnixTimeStamp
" <DT><H3 FOLDED ADD_DATE=`"$($DateAdded)`" LAST_MODIFIED=`"$($DateModified)`" PERSONAL_TOOLBAR_FOLDER=`"true`">$($node.name )</H3>" | Out-File -FilePath $FFHTML_File_Path -Append -Force -Encoding utf8
" <DL><p>" | Out-File -FilePath $FFHTML_File_Path -Append -Force -Encoding utf8
}
foreach ($child in $node.children) {
$DateAdded = [Decimal] $child.date_added | ConvertTo-UnixTimeStamp
$DateModified = [Decimal] $child.date_modified | ConvertTo-UnixTimeStamp
if ($child.type -eq 'folder') {
" <DT><H3 ADD_DATE=`"$($DateAdded)`" LAST_MODIFIED=`"$($DateModified)`">$($child.name)</H3>" | Out-File -FilePath $FFHTML_File_Path -Append -Force -Encoding utf8
" <DL><p>" | Out-File -FilePath $FFHTML_File_Path -Append -Force -Encoding utf8
FFGet-BookmarkFolder $child # Recursive call in case of Folders / SubFolders
" </DL><p>" | Out-File -FilePath $FFHTML_File_Path -Append -Force -Encoding utf8
}
else {
# Type not Folder => URL
" <DT><A HREF=`"$($child.url)`" ADD_DATE=`"$($DateAdded)`">$($child.name)</A>" | Out-File -FilePath $FFHTML_File_Path -Append -Encoding utf8
}
}
if ($node.name -like "Favorites Bar") {
" </DL><p>" | Out-File -FilePath $FFHTML_File_Path -Append -Force -Encoding utf8
}
}
echo "------------------------------------------------------------------------------"
Get-ChildItem -Path HKLM:Software\Wow6432Node\Microsoft\Windows\CurrentVersion\Uninstall, HKCU:Software\Microsoft\Windows\CurrentVersion\Uninstall, HKLM:Software\Wow6432Node\Microsoft\Windows\CurrentVersion\Uninstall, HKLM:SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall |
Get-ItemProperty |
Select-Object -Property @{Name="Application";Expression={$_.DisplayName.Trim()}}, @{Name="Version";Expression={$_.DisplayVersion}} |
Sort-Object -Property Application -Unique | Where-Object Application -ne $Null |
Where-Object { $_.Application -inotmatch ("Office|Word|Access|Excel|Outlook|PowerPoint|Publisher|OneDrive|Microsoft Info|Microsoft One|Project|Skype|Edge|Charter") } |
Out-File $Dest
echo "`nBeginning list of Installed Applications... `n`nList of Installed Applications Saved to: $($Dest)"
echo "`n Script finished"
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment