Skip to content

Instantly share code, notes, and snippets.

@pldmgg
Last active October 8, 2019 12:03
Show Gist options
  • Select an option

  • Save pldmgg/d1657845463554451bc914c8d0420d5d to your computer and use it in GitHub Desktop.

Select an option

Save pldmgg/d1657845463554451bc914c8d0420d5d to your computer and use it in GitHub Desktop.
New-SymFS.ps1
$StartTime = Get-Date
# Setup initial parameters
try {
$UserDirName = $(Get-Item $HOME).Name
$GoogleDrivePath = "$HOME\Google Drive"
$GDUserPath = "$GoogleDrivePath\$UserDirName"
$LogFileName = "NewSymFS_Log_" + $(Get-Date -Format MMddyy_hhmmss) + '.log'
$LogFileDir = "E:\"
$LogFilePath = $LogFileDir + $LogFileName
$FileAgeInMonths = 12
$FileAgeInDays = $FileAgeInMonths*30.5
$FileTimeSpan = New-Timespan -Days $FileAgeInDays
$HomeDirFoldersToExclude = @(
"Google Drive"
#"AppData"
)
$HomeDirItems = Get-ChildItem -Path $HOME -Directory -Force | Where-Object {$HomeDirFoldersToExclude -notcontains $_.Name}
}
catch {
Write-Error $_
if ($LogFileName) {
$_ >> "$HOME\$LogFileName"
}
$global:FunctionResult = "1"
return
}
# Make sure the $LogFileDir exists
try {
if (!$(Test-Path $LogFileDir)) {
$null = New-Item -ItemType Directory -Path $LogFileDir -Force -ErrorAction Stop
}
}
catch {
Write-Error $_
$_ >> "$HOME\$LogFileName"
$global:FunctionResult = "1"
return
}
# Make sure we're running PowerShell 7
if ($PSVersionTable.PSVersion.Major -lt 7) {
$ErrMsg = "This script must be run using PowerShell Core version 7 or greater! Halting!"
Write-Error $ErrMsg
$ErrMsg >> $LogFilePath
$global:FunctionResult = 1
return
}
# Make sure $HOME\Google Drive exists
if (!$(Test-Path $GoogleDrivePath)) {
$ErrMsg = "The path $GoogleDrivePath was not found! Halting!"
Write-Error $ErrMsg
$ErrMsg >> $LogFilePath
$global:FunctionResult = "1"
return
}
# Make sure $GDUserPath exists
if (!$(Test-Path $GDUserPath)) {
try {
$null = New-Item -ItemType Directory -Path $GDUserPath -ErrorAction Stop
if (!$(Test-Path $GDUserPath)) {
throw "The path $GDUserPath still wasn't created eventhough New-Item didn't throw an error!"
}
}
catch {
Write-Error $_
$_ >> $LogFilePath
$global:FunctionResult = "1"
return
}
}
# First, get all directories recursively under $HOME and recreate them (for real) under $GDUserPath so that
# they actually appear in Google Drive
$(Get-Date).ToString() >> $LogFilePath
"`n##### CREATING DIRECTORIES #####`n" >> $LogFilePath
foreach ($HDI in $HomeDirItems) {
try {
$ParentNewPath = $HDI.FullName -replace [regex]::Escape($HOME),$GDUserPath
if (!$(Test-Path $ParentNewPath)) {
$null = New-Item -ItemType Directory -Path $ParentNewPath -ErrorAction Stop
}
Get-ChildItem -Recurse -Path $HDI.FullName -Directory -Force -ErrorAction SilentlyContinue | foreach {
$NewPath = $_.FullName -replace [regex]::Escape($HOME),$GDUserPath
if (!$(Test-Path $NewPath)) {
$null = New-Item -ItemType Directory -Path $NewPath -ErrorAction Stop
}
}
}
catch {
$_ >> $LogFilePath
}
}
# Next, iterate over all files under $HOME.
# If the file is too old, create a symlink under the Google Drive folder so that Google Backup and Sync does NOT actually sync it to Google Drive
# If the file is recent enough, move it to the Google Drive folder and create a hard link from where it was to where it is now (under Google Drive folder)
# Creating a hard link should prevent any problems with programs not expecting a symlink and also not take up any additional space on the HDD
$(Get-Date).ToString() >> $LogFilePath
"`n##### CREATING SYMLINKS AND HARDLINKS #####`n" >> $LogFilePath
foreach ($HDI in $HomeDirItems) {
Get-ChildItem -Recurse -Path $HDI.FullName -File -Force -ErrorAction SilentlyContinue | foreach {
$NewPath = $_.FullName -replace [regex]::Escape($HOME),$GDUserPath
$TestPathCheck = Test-Path $NewPath
try {
if ($_.LastWriteTime -le $(Get-Date).Subtract($FileTimeSpan)) {
# Then the file is too old and should NOT be synced to Google Drive
# If the path doesn't exist, or if it is does exist but is *not* a symlink, create a symlink
if (!$TestPathCheck) {
#Write-Host "$($_.FullName) is too old!"
#Write-Host "LastWriteTime is $($_.LastWriteTime)"
$null = New-Item -ItemType SymbolicLink -Path $NewPath -Target $_.FullName -ErrorAction Stop
}
elseif ($TestPathCheck) {
if ($(Get-Item $NewPath -ErrorAction SilentlyContinue).LinkType -ne 'SymbolicLink') {
$null = Remove-Item $NewPath -Force -ErrorAction SilentlyContinue
$null = New-Item -ItemType SymbolicLink -Path $NewPath -Target $_.FullName -ErrorAction Stop
}
}
}
else {
# The file is recent enough that it SHOULD be synced to Google Drive
# If the path doesn't exist, or if it is does exist but is *not* a hardlink, create a symlink
if (!$TestPathCheck) {
#Write-Host "$($_.FullName) is recent enough!"
#Write-Host "LastWriteTime is $($_.LastWriteTime)"
#$null = Move-Item -Path $_.FullName -Destination $NewPath
#$null = Invoke-Expression "cmd /c mklink /h `"$NewPath`" `"$($_.FullName)`"" -ErrorAction SilentlyContinue >> $LogFilePath
$null = New-Item -ItemType HardLink -Path $NewPath -Target $_.FullName -ErrorAction Stop
}
elseif ($TestPathCheck) {
if ($(Get-Item $NewPath -ErrorAction SilentlyContinue).LinkType -ne 'HardLink') {
$null = Remove-Item $NewPath -Force -ErrorAction SilentlyContinue
$null = New-Item -ItemType HardLink -Path $NewPath -Target $_.FullName -ErrorAction Stop
}
}
}
}
catch {
$_ >> $LogFilePath
}
}
}
$EndTime = Get-Date
"`n##### TOTAL RUNTIME #####`n" >> $LogFilePath
$TotalTime = $EndTime - $StartTime
$TotalTime >> $LogFilePath
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment