Skip to content

Instantly share code, notes, and snippets.

@peteraritchie
Last active January 24, 2026 18:01
Show Gist options
  • Select an option

  • Save peteraritchie/979a8c8b7ee123e5ac58e0a8e51ae6e9 to your computer and use it in GitHub Desktop.

Select an option

Save peteraritchie/979a8c8b7ee123e5ac58e0a8e51ae6e9 to your computer and use it in GitHub Desktop.
#Powershell script to move a file to a new location but leave a #symbolic #link behind
<#
.SYNOPSIS
Move a file to a new location but leave a symbolic link behind
.DESCRIPTION
.
.PARAMETER SourcePath
The path to the existing file to move and replace with a symbolic link.
.PARAMETER TargetPath
The target directory where the non-symbolic link file should be moved.
.PARAMETER Verify
If specified, after the move and link creation, verifies that the file was
.EXAMPLE
C:\PS>
./New-LinkFrom.ps1 script.ps1 $Env:USERPROFILE/Scripts
.NOTES
Author: Peter Ritchie
Date: January 24, 2026
#>
# # testing:
# (get-date).ToShortDateString() > test.txt && md b | Out-Null && . .\New-LinkFrom.ps1 test.txt b -Verbose -Verify -Confirm
# [system.IO.File]::ReadAllText('.\b\test.txt').Contains((get-date).ToShortDateString())
# # cleanup
# del test.txt && rmdir -r -force b
[CmdletBinding(SupportsShouldProcess=$true)]
param(
[Parameter(Mandatory=$true)]
[string]
$SourcePath,
[Parameter(Mandatory=$true)]
[string]
$TargetPath,
[Parameter(Mandatory=$false)]
[switch]
$Verify
)
if(-not (Test-Path -Path $TargetPath -PathType Container))
{
Write-Error "Target directory does not exist: $TargetPath.";
exit 1;
}
if(-not (Test-Path -Path $SourcePath -PathType Leaf))
{
Write-Error "Source file does not exist: $SourcePath.";
exit 1;
}
if([bool]((Get-Item test.txt -Force -ea SilentlyContinue).Attributes -band [System.IO.FileAttributes]::ReparsePoint))
{
Writer-error "$SourcePath is already a symbolic link.";
exit 1;
}
$fileName = Split-Path -Leaf $SourcePath;
Write-Verbose "Moving '$SourcePath' to '$TargetPath/$filename' and creating a symbolic link to '$TargetPath/$filename' as '$SourcePath'.";
if ($PSCmdlet.ShouldProcess("$TargetPath/$filename", 'Move the file to the new location')) {
Move-Item -Path $SourcePath -Destination $TargetPath -Force -Confirm:$false | Out-Null
if ($PSCmdlet.ShouldProcess($SourcePath, 'Create a symbolic link at the original location pointing to the new location')) {
New-Item -ItemType SymbolicLink -Path $SourcePath -Target "$TargetPath/$filename" -Confirm:$false | Out-Null
} else {
Write-Verbose "Action skipped for $SourcePat" -ForegroundColor Yellow
}
} else {
Write-Verbose "Action skipped for $TargetPath/$filename" -ForegroundColor Yellow
}
if($Verify)
{
$result = 0;
if(-not (Test-Path -Path "$TargetPath/$filename" -PathType Leaf))
{
Write-Error "Operation failed: moved file not found at $TargetPath/$filename!";
$result = 1;
}
if(-not [bool]((Get-Item test.txt -Force -ea SilentlyContinue).Attributes -band [System.IO.FileAttributes]::ReparsePoint))
{
Write-Error "Operation failed: new $SourcePath is not a symbolic link!";
$result = 1;
}
exit $result;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment