tasks(iis-migration-to-ruvds): partial cutover live — kupimknigi DNS flipped
Session 2026-05-23 evening → 2026-05-24: full snolla site migration windows-recovery-host → RUVDS Win Server 2025 Core, partial DNS cutover для 1 prod hostname (kupimknigi.spb.ru), оставшиеся 24 hostnames pending. What's live on RUVDS: - snolla IIS site catch-all *:80: + 25 HTTPS SNI bindings (1 per hostname, LE certs от 2026-04-23 / valid до 2026-07-22) - 8.66 GB / 44725 files transferred via scp после ISP-block discovery - ApplicationPoolIdentity + ACL grant verified - HTTP/2 auto-negotiated, MSSQL/imgproxy/MinIO connectivity OK from RUVDS Findings (Decisions log в task file для деталей): 1. Outbound 445 блокирует home ISP (не RUVDS FW) — `windows-server-2025-core-bootstrap.md` SMB-section deprecated, SSH/scp = canonical transfer-метод. 2. Home network HTTP-middlebox mangles Host header в outbound external HTTP — тест с source даёт garbled response; тест с VDS (третья сеть) даёт корректный. 3. traefik acme.json → IIS PFX recipe: extract base64 cert+key per cert → openssl pkcs12 -export → Import-PfxCertificate + AddSslCertificate by thumbprint with SslFlags=1 (SNI). Reusable, потенциально новый concept. 4. IIS 10 на Win Server 2025 говорит HTTP/2 by default через TLS. 5. 4 hostnames (maljarka.tandemmebel.ru + 3 rimiz) → 502/404 на RUVDS; на source IIS:8089 возвращают 200 default-page. Pre-existing CMS-tenant config gap, не migration defect. Scripts added: - scripts/iis-migration-to-ruvds/01-ruvds-bootstrap.ps1 (idempotent) - scripts/iis-migration-to-ruvds/02-source-transfer.ps1 (не использовался — SMB не работает; оставлен как reference) - scripts/iis-migration-to-ruvds/README.md Cleanup done: - Plaintext PFX/PEM keys в C:\Users\vitya\iis-backup-pre-ruvds\certs\ удалены (PFX import на RUVDS уже сделан, source-of-truth = traefik acme.json). - `.secrets/` уже удалён ранее в этой session (см. предыдущий commit). Source state: IIS:8089 + traefik routes ALIVE — rollback ready. Decommission после 1-week soak с RUVDS как live prod. Не push'нуто — ждёт user grant per project-discipline Rule 4. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
153
scripts/iis-migration-to-ruvds/01-ruvds-bootstrap.ps1
Normal file
153
scripts/iis-migration-to-ruvds/01-ruvds-bootstrap.ps1
Normal file
@@ -0,0 +1,153 @@
|
||||
#requires -Version 5.1
|
||||
#requires -RunAsAdministrator
|
||||
<#
|
||||
.SYNOPSIS
|
||||
RUVDS bootstrap for IIS migration from windows-recovery-host.
|
||||
|
||||
.DESCRIPTION
|
||||
Run on RUVDS in PowerShell as Administrator (RDP session).
|
||||
|
||||
Steps:
|
||||
1. Install IIS (Web-Server + sub-features + Management Tools).
|
||||
2. Verify .NET Framework 4.8 (Release >= 528040).
|
||||
3. Install URL Rewrite Module 2.1.
|
||||
4. Open Defender Firewall: HTTP/80, HTTPS/443.
|
||||
5. Create C:\sites + SMB share, scoped to source IP 46.151.25.64.
|
||||
6. Print summary.
|
||||
|
||||
Idempotent. Transcript: C:\bootstrap-log.txt
|
||||
#>
|
||||
|
||||
[CmdletBinding()]
|
||||
param(
|
||||
[string]$SourceIp = '46.151.25.64',
|
||||
[string]$SiteRoot = 'C:\sites',
|
||||
[string]$ShareName = 'sites'
|
||||
)
|
||||
|
||||
$ErrorActionPreference = 'Stop'
|
||||
$ProgressPreference = 'SilentlyContinue'
|
||||
Start-Transcript -Path C:\bootstrap-log.txt -Append -Force | Out-Null
|
||||
|
||||
function Step($name) { Write-Host "`n=== $name ===" -ForegroundColor Cyan }
|
||||
function Ok($msg) { Write-Host " [OK] $msg" -ForegroundColor Green }
|
||||
function Skip($msg) { Write-Host " [SKIP] $msg" -ForegroundColor Yellow }
|
||||
function Fail($msg) { Write-Host " [FAIL] $msg" -ForegroundColor Red }
|
||||
|
||||
try {
|
||||
|
||||
Step '1. Install IIS'
|
||||
$iis = Get-WindowsFeature Web-Server
|
||||
if ($iis.Installed) {
|
||||
Skip "Web-Server already installed"
|
||||
} else {
|
||||
Install-WindowsFeature Web-Server -IncludeAllSubFeature -IncludeManagementTools -Restart:$false | Out-Null
|
||||
Ok "Web-Server installed"
|
||||
}
|
||||
$extras = @('Web-Asp-Net45','Web-Net-Ext45','Web-ISAPI-Ext','Web-ISAPI-Filter','Web-Windows-Auth','Web-Mgmt-Console')
|
||||
foreach ($f in $extras) {
|
||||
$st = Get-WindowsFeature $f
|
||||
if ($st.Installed) {
|
||||
Skip "$f already installed"
|
||||
} else {
|
||||
Install-WindowsFeature $f -Restart:$false | Out-Null
|
||||
Ok "$f installed"
|
||||
}
|
||||
}
|
||||
|
||||
Step '2. Verify .NET Framework 4.8'
|
||||
$ndp = Get-ItemProperty 'HKLM:\SOFTWARE\Microsoft\NET Framework Setup\NDP\v4\Full\' -ErrorAction SilentlyContinue
|
||||
if ($ndp -and $ndp.Release -ge 528040) {
|
||||
Ok ".NET 4.8 detected (Release=$($ndp.Release))"
|
||||
} else {
|
||||
Fail ".NET 4.8 NOT found (Release=$($ndp.Release)). Win Server 2025 normally pre-bundles 4.8 -- check Optional Features."
|
||||
Write-Host " Hint: DISM /Online /Add-Capability /CapabilityName:NetFx4.8~~~~" -ForegroundColor Yellow
|
||||
throw "Bootstrap aborted: .NET 4.8 missing"
|
||||
}
|
||||
|
||||
Step '3. Install URL Rewrite Module 2.1'
|
||||
$rewriteInstalled = Test-Path 'HKLM:\SOFTWARE\Microsoft\IIS Extensions\URL Rewrite'
|
||||
if ($rewriteInstalled) {
|
||||
Skip "URL Rewrite already installed"
|
||||
} else {
|
||||
$msiUrl = 'https://download.microsoft.com/download/1/2/8/128E2E22-C1B9-44A4-BE2A-5859ED1D4592/rewrite_amd64_en-US.msi'
|
||||
$msiPath = "$env:TEMP\rewrite_amd64_en-US.msi"
|
||||
if (-not (Test-Path $msiPath)) {
|
||||
Write-Host " Downloading $msiUrl ..."
|
||||
Invoke-WebRequest -Uri $msiUrl -OutFile $msiPath -UseBasicParsing
|
||||
Ok "downloaded ($([math]::Round((Get-Item $msiPath).Length / 1MB, 2)) MB)"
|
||||
}
|
||||
Write-Host " Installing..."
|
||||
$p = Start-Process msiexec.exe -ArgumentList "/i `"$msiPath`" /quiet /norestart" -Wait -PassThru
|
||||
if ($p.ExitCode -ne 0) { throw "msiexec exit $($p.ExitCode)" }
|
||||
Ok "URL Rewrite installed"
|
||||
}
|
||||
|
||||
Step '4. Open Defender Firewall (HTTP/80, HTTPS/443)'
|
||||
foreach ($port in @(80,443)) {
|
||||
$name = "iis-http-$port"
|
||||
$existing = Get-NetFirewallRule -DisplayName $name -ErrorAction SilentlyContinue
|
||||
if ($existing) {
|
||||
Skip "FW rule $name already exists"
|
||||
} else {
|
||||
New-NetFirewallRule -DisplayName $name -Direction Inbound -Protocol TCP -LocalPort $port -Action Allow -Profile Any | Out-Null
|
||||
Ok "FW rule $name added"
|
||||
}
|
||||
}
|
||||
|
||||
Step '5. Open SMB inbound + create share'
|
||||
if (-not (Test-Path $SiteRoot)) {
|
||||
New-Item -ItemType Directory -Path $SiteRoot -Force | Out-Null
|
||||
Ok "Created $SiteRoot"
|
||||
} else {
|
||||
Skip "$SiteRoot already exists"
|
||||
}
|
||||
|
||||
$fileSharingRules = Get-NetFirewallRule -DisplayGroup 'File and Printer Sharing' -ErrorAction SilentlyContinue | Where-Object Enabled -eq 'False'
|
||||
if ($fileSharingRules) {
|
||||
$cnt = $fileSharingRules.Count
|
||||
$fileSharingRules | Set-NetFirewallRule -Enabled True
|
||||
Ok "Enabled built-in 'File and Printer Sharing' group ($cnt rules)"
|
||||
} else {
|
||||
Skip "'File and Printer Sharing' rules already enabled"
|
||||
}
|
||||
|
||||
$smbRule = Get-NetFirewallRule -DisplayName 'smb-from-source' -ErrorAction SilentlyContinue
|
||||
if ($smbRule) {
|
||||
Skip "smb-from-source FW rule already exists"
|
||||
} else {
|
||||
New-NetFirewallRule -DisplayName 'smb-from-source' `
|
||||
-Direction Inbound -Protocol TCP -LocalPort 445 `
|
||||
-RemoteAddress $SourceIp `
|
||||
-Action Allow -Profile Any | Out-Null
|
||||
Ok "smb-from-source FW rule added (source=$SourceIp)"
|
||||
}
|
||||
|
||||
$share = Get-SmbShare -Name $ShareName -ErrorAction SilentlyContinue
|
||||
if ($share) {
|
||||
Skip "SMB share '$ShareName' already exists (path=$($share.Path))"
|
||||
} else {
|
||||
New-SmbShare -Name $ShareName -Path $SiteRoot -FullAccess Administrator | Out-Null
|
||||
Ok "SMB share '$ShareName' created -> $SiteRoot"
|
||||
}
|
||||
|
||||
Step '6. Summary'
|
||||
Write-Host ""
|
||||
Write-Host " IIS (Web-Server): $((Get-WindowsFeature Web-Server).Installed)"
|
||||
Write-Host " ASP.NET 4.5/4.8: $((Get-WindowsFeature Web-Asp-Net45).Installed)"
|
||||
Write-Host " URL Rewrite 2.1: $(Test-Path 'HKLM:\SOFTWARE\Microsoft\IIS Extensions\URL Rewrite')"
|
||||
Write-Host " FW HTTP/80: $([bool](Get-NetFirewallRule -DisplayName 'iis-http-80' -ErrorAction SilentlyContinue))"
|
||||
Write-Host " FW HTTPS/443: $([bool](Get-NetFirewallRule -DisplayName 'iis-http-443' -ErrorAction SilentlyContinue))"
|
||||
Write-Host " FW smb-from-source: $([bool](Get-NetFirewallRule -DisplayName 'smb-from-source' -ErrorAction SilentlyContinue))"
|
||||
Write-Host " SMB share '$ShareName': $([bool](Get-SmbShare -Name $ShareName -ErrorAction SilentlyContinue)) -> $SiteRoot"
|
||||
Write-Host " Disk C: free: $([math]::Round((Get-PSDrive C).Free / 1GB, 2)) GB"
|
||||
Write-Host ""
|
||||
Write-Host "Transcript: C:\bootstrap-log.txt" -ForegroundColor DarkGray
|
||||
|
||||
} catch {
|
||||
Fail $_.Exception.Message
|
||||
Write-Host $_.ScriptStackTrace -ForegroundColor DarkRed
|
||||
exit 1
|
||||
} finally {
|
||||
Stop-Transcript | Out-Null
|
||||
}
|
||||
171
scripts/iis-migration-to-ruvds/02-source-transfer.ps1
Normal file
171
scripts/iis-migration-to-ruvds/02-source-transfer.ps1
Normal file
@@ -0,0 +1,171 @@
|
||||
#requires -Version 5.1
|
||||
#requires -RunAsAdministrator
|
||||
<#
|
||||
.SYNOPSIS
|
||||
Source-side transfer: backup IIS state + robocopy snolla site to RUVDS.
|
||||
|
||||
.DESCRIPTION
|
||||
Run on source (DESKTOP-NSEF0UK / windows-recovery-host) in PowerShell as Administrator.
|
||||
|
||||
Steps:
|
||||
1. Probe RUVDS SMB 445 reachability (fail fast).
|
||||
2. Pull RUVDS Administrator password from pass-store.
|
||||
3. Backup IIS state to C:\Users\vitya\iis-backup-pre-ruvds\:
|
||||
- applicationHost.config
|
||||
- appcmd dump of all sites (for reference)
|
||||
- appcmd dump of snolla site config + apppool (for recreate on RUVDS)
|
||||
4. net-use mount \\80.64.31.36\sites with creds.
|
||||
5. Copy IIS backup files into the share (so RUVDS can grab them for recreate).
|
||||
6. robocopy C:\sites\snolla -> \\80.64.31.36\sites\snolla
|
||||
(/Z resume-on-disconnect, /MT:8 parallel, /R:2 /W:5 retries, /XJ skip junctions)
|
||||
7. Verify count + size match.
|
||||
8. Disconnect SMB.
|
||||
|
||||
Transcript: C:\Users\vitya\iis-backup-pre-ruvds\transfer-log.txt
|
||||
#>
|
||||
|
||||
[CmdletBinding()]
|
||||
param(
|
||||
[string]$RuvdsIp = '80.64.31.36',
|
||||
[string]$ShareName = 'sites',
|
||||
[string]$SiteName = 'snolla',
|
||||
[string]$SourceSite = 'C:\sites\snolla',
|
||||
[string]$BackupDir = 'C:\Users\vitya\iis-backup-pre-ruvds'
|
||||
)
|
||||
|
||||
$ErrorActionPreference = 'Stop'
|
||||
$ProgressPreference = 'SilentlyContinue'
|
||||
|
||||
if (-not (Test-Path $BackupDir)) { New-Item -ItemType Directory -Path $BackupDir -Force | Out-Null }
|
||||
Start-Transcript -Path (Join-Path $BackupDir 'transfer-log.txt') -Append -Force | Out-Null
|
||||
|
||||
function Step($name) { Write-Host "`n=== $name ===" -ForegroundColor Cyan }
|
||||
function Ok($msg) { Write-Host " [OK] $msg" -ForegroundColor Green }
|
||||
function Skip($msg) { Write-Host " [SKIP] $msg" -ForegroundColor Yellow }
|
||||
function Fail($msg) { Write-Host " [FAIL] $msg" -ForegroundColor Red }
|
||||
|
||||
$shareUnc = "\\$RuvdsIp\$ShareName"
|
||||
$mountedShare = $false
|
||||
|
||||
try {
|
||||
|
||||
Step '1. Probe RUVDS SMB 445'
|
||||
$smb = Test-NetConnection -ComputerName $RuvdsIp -Port 445 -InformationLevel Quiet -WarningAction SilentlyContinue
|
||||
if (-not $smb) { throw "RUVDS:445 not reachable. Re-run 01-ruvds-bootstrap.ps1 on RUVDS." }
|
||||
Ok "RUVDS:445 reachable"
|
||||
|
||||
Step '2. Pull RUVDS password from pass-store'
|
||||
$bash = 'C:\Program Files\Git\bin\bash.exe'
|
||||
if (-not (Test-Path $bash)) { throw "bash.exe not found at $bash; pass-store unreachable" }
|
||||
$passOut = & $bash -lc 'pass show ruvds-iis/full-env'
|
||||
$passLine = $passOut | Where-Object { $_ -match '^RUVDS_IIS_PASS=' } | Select-Object -First 1
|
||||
if (-not $passLine) { throw "RUVDS_IIS_PASS not found in pass show ruvds-iis/full-env" }
|
||||
$ruvdsPass = $passLine -replace '^RUVDS_IIS_PASS=',''
|
||||
Ok "credentials loaded from pass-store"
|
||||
|
||||
Step '3. Backup source IIS state'
|
||||
$appcmd = "$env:SystemRoot\system32\inetsrv\appcmd.exe"
|
||||
if (-not (Test-Path $appcmd)) { throw "appcmd.exe not found -- IIS Management Tools not installed on source?" }
|
||||
|
||||
Copy-Item 'C:\Windows\System32\inetsrv\config\applicationHost.config' (Join-Path $BackupDir 'applicationHost.config') -Force
|
||||
Ok "applicationHost.config backed up"
|
||||
|
||||
& $appcmd list site /config:* /xml | Out-File -FilePath (Join-Path $BackupDir 'all-sites.xml') -Encoding UTF8
|
||||
Ok "appcmd list site (all) dumped"
|
||||
|
||||
& $appcmd list site /name:$SiteName /config:* /xml | Out-File -FilePath (Join-Path $BackupDir 'snolla-site.xml') -Encoding UTF8
|
||||
Ok "snolla-site.xml dumped"
|
||||
|
||||
& $appcmd list apppool /xml | Out-File -FilePath (Join-Path $BackupDir 'all-apppools.xml') -Encoding UTF8
|
||||
Ok "all-apppools.xml dumped"
|
||||
|
||||
Step '4. Mount RUVDS share'
|
||||
cmd.exe /c "net use $shareUnc /user:Administrator $ruvdsPass" 2>&1 | Out-Null
|
||||
if ($LASTEXITCODE -ne 0) {
|
||||
cmd.exe /c "net use $shareUnc /delete /y" 2>&1 | Out-Null
|
||||
cmd.exe /c "net use $shareUnc /user:Administrator $ruvdsPass" 2>&1 | Tee-Object -Variable mountOut | Out-Null
|
||||
if ($LASTEXITCODE -ne 0) { throw "net use failed: $mountOut" }
|
||||
}
|
||||
$mountedShare = $true
|
||||
Ok "mounted $shareUnc"
|
||||
|
||||
Step '5. Copy IIS backup files to share (for RUVDS recreate-script access)'
|
||||
$remoteBackupDir = Join-Path $shareUnc '_iis-backup'
|
||||
if (-not (Test-Path $remoteBackupDir)) { New-Item -ItemType Directory -Path $remoteBackupDir -Force | Out-Null }
|
||||
Copy-Item (Join-Path $BackupDir '*.xml') $remoteBackupDir -Force
|
||||
Copy-Item (Join-Path $BackupDir 'applicationHost.config') $remoteBackupDir -Force
|
||||
Ok "IIS backup files copied to $remoteBackupDir"
|
||||
|
||||
Step '6. robocopy snolla site'
|
||||
$srcDir = $SourceSite
|
||||
$dstDir = Join-Path $shareUnc $SiteName
|
||||
if (-not (Test-Path $srcDir)) { throw "source $srcDir not found" }
|
||||
|
||||
$srcSizeGB = [math]::Round(((Get-ChildItem $srcDir -Recurse -File -ErrorAction SilentlyContinue | Measure-Object -Property Length -Sum).Sum / 1GB), 2)
|
||||
Write-Host " Source size: $srcSizeGB GB"
|
||||
Write-Host " Destination: $dstDir"
|
||||
Write-Host " This may take 30-90 min on home uplink. Progress goes to log."
|
||||
Write-Host ""
|
||||
|
||||
$robocopyLog = Join-Path $BackupDir 'robocopy-snolla.log'
|
||||
$robocopyArgs = @(
|
||||
$srcDir, $dstDir,
|
||||
'*.*',
|
||||
'/S', '/E',
|
||||
'/DCOPY:DA', '/COPY:DAT',
|
||||
'/Z',
|
||||
'/MT:8',
|
||||
'/R:2', '/W:5',
|
||||
'/XJ',
|
||||
'/TEE',
|
||||
"/LOG+:$robocopyLog",
|
||||
'/NP', '/NDL'
|
||||
)
|
||||
$rcStart = Get-Date
|
||||
& robocopy.exe @robocopyArgs
|
||||
$rcExit = $LASTEXITCODE
|
||||
$rcDuration = (Get-Date) - $rcStart
|
||||
|
||||
# robocopy exit codes: 0-7 = success/partial, 8+ = error
|
||||
if ($rcExit -ge 8) {
|
||||
throw "robocopy failed with exit $rcExit. See $robocopyLog tail."
|
||||
}
|
||||
Ok ("robocopy done in {0:hh\:mm\:ss} (exit={1})" -f $rcDuration, $rcExit)
|
||||
|
||||
Step '7. Verify count + size'
|
||||
$srcCount = (Get-ChildItem $srcDir -Recurse -File -ErrorAction SilentlyContinue | Measure-Object).Count
|
||||
$dstCount = (Get-ChildItem $dstDir -Recurse -File -ErrorAction SilentlyContinue | Measure-Object).Count
|
||||
$srcBytes = (Get-ChildItem $srcDir -Recurse -File -ErrorAction SilentlyContinue | Measure-Object -Property Length -Sum).Sum
|
||||
$dstBytes = (Get-ChildItem $dstDir -Recurse -File -ErrorAction SilentlyContinue | Measure-Object -Property Length -Sum).Sum
|
||||
Write-Host " Source: $srcCount files, $([math]::Round($srcBytes / 1MB, 0)) MB"
|
||||
Write-Host " Dest: $dstCount files, $([math]::Round($dstBytes / 1MB, 0)) MB"
|
||||
if ($srcCount -ne $dstCount) { Fail "FILE COUNT MISMATCH ($srcCount vs $dstCount)"; throw "count mismatch" }
|
||||
if ($srcBytes -ne $dstBytes) { Fail "SIZE MISMATCH ($srcBytes vs $dstBytes bytes)"; throw "size mismatch" }
|
||||
Ok "count + size match"
|
||||
|
||||
Step '8. Summary'
|
||||
Write-Host ""
|
||||
Write-Host " Source site: $srcDir"
|
||||
Write-Host " RUVDS dest: $dstDir"
|
||||
Write-Host " Files transferred: $dstCount"
|
||||
Write-Host " Bytes transferred: $([math]::Round($dstBytes / 1GB, 2)) GB"
|
||||
Write-Host " Duration: $('{0:hh\:mm\:ss}' -f $rcDuration)"
|
||||
Write-Host " IIS backup local: $BackupDir"
|
||||
Write-Host " IIS backup remote: $remoteBackupDir (on RUVDS as C:\sites\_iis-backup\)"
|
||||
Write-Host ""
|
||||
Write-Host " Transcript: $(Join-Path $BackupDir 'transfer-log.txt')" -ForegroundColor DarkGray
|
||||
Write-Host " Robocopy log: $robocopyLog" -ForegroundColor DarkGray
|
||||
Write-Host ""
|
||||
Write-Host " Next: run 03-ruvds-recreate-sites.ps1 on RUVDS." -ForegroundColor Cyan
|
||||
|
||||
} catch {
|
||||
Fail $_.Exception.Message
|
||||
Write-Host $_.ScriptStackTrace -ForegroundColor DarkRed
|
||||
exit 1
|
||||
} finally {
|
||||
if ($mountedShare) {
|
||||
cmd.exe /c "net use $shareUnc /delete /y" 2>&1 | Out-Null
|
||||
Write-Host "`n [cleanup] SMB share dismounted" -ForegroundColor DarkGray
|
||||
}
|
||||
Stop-Transcript | Out-Null
|
||||
}
|
||||
42
scripts/iis-migration-to-ruvds/README.md
Normal file
42
scripts/iis-migration-to-ruvds/README.md
Normal file
@@ -0,0 +1,42 @@
|
||||
# IIS migration to RUVDS — execution scripts
|
||||
|
||||
Скрипты для миграции IIS-хостинга `windows-recovery-host` (DESKTOP-NSEF0UK) → RUVDS Win Server 2025 Core (`80.64.31.36`).
|
||||
|
||||
Контекст и план целиком — `.tasks/iis-migration-to-ruvds.md` + `.wiki/concepts/windows-server-2025-core-bootstrap.md`.
|
||||
|
||||
## Execution order
|
||||
|
||||
| # | Script | Where to run | Purpose |
|
||||
|---|---|---|---|
|
||||
| 1 | `01-ruvds-bootstrap.ps1` | **на RUVDS** под RDP (PowerShell admin) | Install IIS + URL Rewrite + open FW 80/443 + open SMB scoped to source IP + create C:\sites share. Idempotent. |
|
||||
| 2 | `02-source-transfer.ps1` *(coming next)* | **на source** (DESKTOP-NSEF0UK) | net-use → robocopy snolla → verify. |
|
||||
| 3 | `03-ruvds-recreate-sites.ps1` *(coming next)* | **на RUVDS** | appcmd add site / bindings / web.config conn-string swap → `mssql.kzntsv.site,1433`. |
|
||||
| 4 | `04-pilot-and-swap.md` *(playbook, not script)* | mixed | Pilot kupimknigi.spb.ru через hosts-file → 24h soak → DNS A swap. |
|
||||
| 5 | `99-ruvds-cleanup-smb.ps1` *(after cutover)* | **на RUVDS** | Remove SMB share + FW rule (закрываем 445 после migration). |
|
||||
|
||||
## Pre-reqs
|
||||
|
||||
- RUVDS up + RDP ready (`pass show ruvds-iis/full-env`)
|
||||
- Source public IP **46.151.25.64** уже whitelist'нут в скрипте `#1` (если source IP меняется — `-SourceIp <new>` параметр)
|
||||
- На RUVDS — Administrator-shell PowerShell
|
||||
|
||||
## How to copy scripts to RUVDS
|
||||
|
||||
Два варианта:
|
||||
|
||||
**A. RDP drive-redirect (рекомендуемо):**
|
||||
1. `mstsc /v:80.64.31.36` → Show Options → Local Resources → More → Drives → отметить `C:` → ОК.
|
||||
2. После logon в RUVDS — `\\tsclient\C\` mount'нут. Скопировать `C:\Users\vitya\projects\.admin\scripts\iis-migration-to-ruvds\01-ruvds-bootstrap.ps1` → `C:\bootstrap.ps1`.
|
||||
3. PowerShell admin → `C:\bootstrap.ps1`.
|
||||
|
||||
**B. Paste-friendly:** открыть скрипт в нашей репе локально → copy всё содержимое → в RUVDS `notepad C:\bootstrap.ps1` → paste → save → run.
|
||||
|
||||
## Verification после bootstrap'а
|
||||
|
||||
На source:
|
||||
```powershell
|
||||
Test-NetConnection 80.64.31.36 -Port 445 # должно стать True
|
||||
Test-NetConnection 80.64.31.36 -Port 443 # должно стать True
|
||||
```
|
||||
|
||||
Если оба True — переходим к script #2.
|
||||
Reference in New Issue
Block a user