param( [Parameter(Mandatory=$true)] [string]$Source, [Parameter(Mandatory=$true)] [string]$Destination ) try { # 1. Expand variables in paths. $ResolvedSource = $ExecutionContext.InvokeCommand.ExpandString($Source) $ResolvedDest = $ExecutionContext.InvokeCommand.ExpandString($Destination) # 2. Resolve relative source paths from the project root. if (-not (Test-Path $ResolvedSource) -and (Test-Path "$PWD\$ResolvedSource")) { $ResolvedSource = Join-Path $PWD $ResolvedSource } # 3. Make sure the source file exists. if (-not (Test-Path $ResolvedSource -PathType Leaf)) { Write-Warning "`n[FileCopy] [Skip] File not found: $ResolvedSource" return } # 4. Create destination directory when needed. $DestDir = Split-Path -Path $ResolvedDest -Parent if (-not (Test-Path $DestDir)) { Write-Host "`n[FileCopy] Create dir: $DestDir" -ForegroundColor DarkGray New-Item -Path $DestDir -ItemType Directory -Force | Out-Null } # 5. Copy file. Force overwrites existing files. Copy-Item -Path $ResolvedSource -Destination $ResolvedDest -Force -ErrorAction Stop Write-Host "`n[FileCopy] Success: $ResolvedDest" -ForegroundColor Green } catch { Write-Error "`n[FileCopy] Fail: $_" }