# Hard-coded deploy settings. Fill these in before running. $FtpHost = "ftp.example.com" $FtpUser = "deploy-user" $FtpPassword = "deploy-password" $RemoteDir = "/httpdocs" $ProjectPath = "..\\GameList.csproj" $Configuration = "Release" $Runtime = "win-x64" $PublishDir = "..\\artifacts\\publish" $SelfContained = $false $WinScpPath = "WinSCP.com" # Optional: recycle IIS app pool via WinRM instead of RDP. Set $RecycleAppPool = $false to skip. $RecycleAppPool = $true $AppPoolName = "DefaultAppPool" $WinRmComputer = "your-server-hostname" $WinRmCredentialUser = "DOMAIN\\deploy-user" $WinRmCredentialPass = "P@ssw0rd!" <#! .SYNOPSIS Publish the app and mirror the output to an FTP-deployed IIS site. .DESCRIPTION - Builds with dotnet publish. - Uses WinSCP (ftp) to mirror publish output into $RemoteDir (deletes extraneous remote files). - Optionally recycles the IIS app pool remotely via WinRM (no RDP needed). .PREREQS - WinSCP.com available in PATH or set $WinScpPath. - FTP user must have write/delete rights to $RemoteDir. - WinRM must be enabled for remote app pool recycle (set $RecycleAppPool = $false otherwise). .EXAMPLE pwsh ./scripts/deploy-ftp.ps1 #> Set-StrictMode -Version Latest $ErrorActionPreference = "Stop" function Assert-Tool { param([string]$Name) if (-not (Get-Command $Name -ErrorAction SilentlyContinue)) { throw "Required tool '$Name' not found. Install it or update paths." } } Assert-Tool "dotnet" Assert-Tool $WinScpPath Write-Host "1) Publishing..." -ForegroundColor Cyan New-Item -ItemType Directory -Force -Path $PublishDir | Out-Null $publishArgs = @("publish", $ProjectPath, "-c", $Configuration, "-r", $Runtime, "-o", $PublishDir) if (-not $SelfContained) { $publishArgs += "--self-contained=false" } dotnet @publishArgs Write-Host "2) Syncing via WinSCP (FTP mirror with delete)..." -ForegroundColor Cyan $tempScript = New-TemporaryFile @" option batch continue option confirm off open ftp://$($FtpUser):$($FtpPassword.Replace('`n','').Replace('`r',''))@$FtpHost lcd $PublishDir cd $RemoteDir synchronize remote . -delete exit "@ | Set-Content -Path $tempScript -Encoding UTF8 & $WinScpPath "/ini=nul" "/script=$tempScript" Remove-Item $tempScript -ErrorAction SilentlyContinue if ($RecycleAppPool) { Write-Host "3) Recycling IIS app pool via WinRM..." -ForegroundColor Cyan $sec = ConvertTo-SecureString $WinRmCredentialPass -AsPlainText -Force $cred = New-Object pscredential($WinRmCredentialUser, $sec) Invoke-Command -ComputerName $WinRmComputer -Credential $cred -ScriptBlock { Import-Module WebAdministration Stop-WebAppPool -Name $using:AppPoolName -ErrorAction SilentlyContinue Start-WebAppPool -Name $using:AppPoolName } } Write-Host "Done." -ForegroundColor Green