Public/Set-LocalRepositoryLink.ps1
function Set-LocalRepositoryLink { <# .SYNOPSIS Create a symlink from OneDrive to the local repository directory. .DESCRIPTION Creates a symbolic link from a OneDrive folder to the local repository, enabling automatic synchronization of packages across devices. .PARAMETER OneDrivePath Path to the OneDrive folder that should be linked to the local repository. .PARAMETER LocalPath Path to the local repository. Defaults to C:\LocalNuGetRepo. .PARAMETER Direction Direction of the symlink: - 'OneDriveToLocal' (default): OneDrive folder points to local repository - 'LocalToOneDrive': Local repository points to OneDrive folder .PARAMETER Force Force creation of symlink, removing existing directories if necessary. .EXAMPLE Set-LocalRepositoryLink -OneDrivePath "C:\Users\username\OneDrive\Packages" Creates a symlink from OneDrive to C:\LocalNuGetRepo. .EXAMPLE Set-LocalRepositoryLink -OneDrivePath "C:\Users\username\OneDrive\Packages" -Direction LocalToOneDrive Creates a symlink from C:\LocalNuGetRepo to OneDrive. .NOTES Requires elevated permissions to create symbolic links on Windows. #> [CmdletBinding(SupportsShouldProcess)] param( [Parameter(Mandatory, Position = 0)] [string]$OneDrivePath, [Parameter(Position = 1)] [string]$LocalPath = $script:DefaultRepositoryPath, [Parameter()] [ValidateSet('OneDriveToLocal', 'LocalToOneDrive')] [string]$Direction = 'OneDriveToLocal', [Parameter()] [switch]$Force ) try { # Check if running as administrator $currentUser = [Security.Principal.WindowsIdentity]::GetCurrent() $principal = New-Object Security.Principal.WindowsPrincipal($currentUser) $isAdmin = $principal.IsInRole([Security.Principal.WindowsBuiltInRole]::Administrator) if (-not $isAdmin) { Write-Warning "Creating symbolic links requires administrator privileges." Write-Host "Please run this command as Administrator or enable Developer Mode in Windows Settings." -ForegroundColor Yellow return } # Set source and target based on direction if ($Direction -eq 'OneDriveToLocal') { $linkPath = $OneDrivePath $targetPath = $LocalPath Write-Host "Creating symlink: OneDrive -> Local Repository" -ForegroundColor Cyan Write-Host " Link: $linkPath" -ForegroundColor Gray Write-Host " Target: $targetPath" -ForegroundColor Gray } else { $linkPath = $LocalPath $targetPath = $OneDrivePath Write-Host "Creating symlink: Local Repository -> OneDrive" -ForegroundColor Cyan Write-Host " Link: $linkPath" -ForegroundColor Gray Write-Host " Target: $targetPath" -ForegroundColor Gray } # Check if target exists if (-not (Test-Path -Path $targetPath)) { if ($PSCmdlet.ShouldProcess($targetPath, "Create target directory")) { New-Item -Path $targetPath -ItemType Directory -Force | Out-Null Write-Host " [OK] Created target directory: $targetPath" -ForegroundColor Green } } # Check if link path exists if (Test-Path -Path $linkPath) { if ($Force) { Write-Host " [FORCE] Removing existing path..." -ForegroundColor Yellow if (Test-Path -Path $linkPath -PathType Container) { # Check if it's a symlink $item = Get-Item -Path $linkPath -Force if ($item.Attributes -band [System.IO.FileAttributes]::ReparsePoint) { # It's a symlink, safe to remove Remove-Item -Path $linkPath -Force Write-Host " - Removed existing symlink" -ForegroundColor Gray } else { # It's a real directory, be more careful $items = Get-ChildItem -Path $linkPath -Force if ($items.Count -eq 0) { Remove-Item -Path $linkPath -Force Write-Host " - Removed empty directory" -ForegroundColor Gray } else { Write-Error "Directory '$linkPath' contains files. Cannot remove without explicit confirmation." return } } } else { Remove-Item -Path $linkPath -Force Write-Host " - Removed existing file" -ForegroundColor Gray } } else { Write-Error "Path '$linkPath' already exists. Use -Force to overwrite." return } } if ($PSCmdlet.ShouldProcess($linkPath, "Create symbolic link to $targetPath")) { # Create the symbolic link try { # Use cmd mklink for reliability $result = cmd /c "mklink /D `"$linkPath`" `"$targetPath`"" if ($LASTEXITCODE -eq 0) { Write-Host " [OK] Symbolic link created successfully" -ForegroundColor Green # Verify the link if (Test-Path -Path $linkPath) { $item = Get-Item -Path $linkPath -Force if ($item.Attributes -band [System.IO.FileAttributes]::ReparsePoint) { Write-Host " [VERIFY] Symlink verification successful" -ForegroundColor Green Write-Host " [TARGET] $($item.Target)" -ForegroundColor Gray } else { Write-Warning "Created path is not a symbolic link" } } else { Write-Warning "Symbolic link was not created successfully" } } else { Write-Error "Failed to create symbolic link: $result" } } catch { Write-Error "Failed to create symbolic link: $($_.Exception.Message)" } } # Show usage instructions if ($Direction -eq 'OneDriveToLocal') { Write-Host "`nUsage:" -ForegroundColor Cyan Write-Host " - Place .nupkg files in: $OneDrivePath" -ForegroundColor White Write-Host " - They will be accessible via: $LocalPath" -ForegroundColor White Write-Host " - Run: Install-ModuleFromLocalRepo" -ForegroundColor White } else { Write-Host "`nUsage:" -ForegroundColor Cyan Write-Host " - Build packages to: $LocalPath" -ForegroundColor White Write-Host " - They will sync to: $OneDrivePath" -ForegroundColor White Write-Host " - Other devices can access via OneDrive sync" -ForegroundColor White } } catch { Write-Error "Failed to create repository link: $($_.Exception.Message)" } } |