Files
inquiry_robot/deploy/_remote_mysql_recover_root.ps1
T

130 lines
5.2 KiB
PowerShell

# Recover local MySQL root from logs / admin-login-recovery; never print secrets.
$ErrorActionPreference = "Continue"
$mysql = "C:\yutongda\tools\mysql-8.0.39-winx64\bin\mysql.exe"
function Test-Root([string]$pass, [string[]]$hostArgs) {
if ([string]::IsNullOrWhiteSpace($pass)) { return $false }
$argList = @() + $hostArgs + @("-uroot","-p$pass","--connect-timeout=8","--batch","-N","-e","SELECT 1")
$out = & $mysql @argList 2>&1
$text = ($out | ForEach-Object { "$_" }) -join "`n"
if ($text -match "ERROR\s+\d+") { return $false }
$lines = $out | ForEach-Object { "$_".Trim() } | Where-Object { $_ -ne "" -and $_ -notmatch "Warning" }
return ($lines -contains "1")
}
Write-Output "=== admin-login-recovery files ==="
Get-ChildItem "C:\yutongda\secure\admin-login-recovery" -Recurse -EA SilentlyContinue |
ForEach-Object { $_.FullName }
Write-Output "=== e2e env keys ==="
$e2e = "C:\yutongda\secure\e2e-business-20260826-205407.env"
if (Test-Path $e2e) {
Get-Content $e2e | ForEach-Object { if ($_ -match '^([^=]+)=') { $matches[1] } }
}
Write-Output "=== collect candidate passwords from recovery (names only) ==="
$cands = New-Object System.Collections.Generic.List[object]
function Add-Cand([string]$src, [string]$pass) {
if ([string]::IsNullOrWhiteSpace($pass)) { return }
$pass = $pass.Trim().Trim("'").Trim('"')
if ($pass.Length -lt 4) { return }
$cands.Add([pscustomobject]@{ src = $src; pass = $pass; len = $pass.Length })
}
Get-ChildItem "C:\yutongda\secure\admin-login-recovery" -Recurse -File -EA SilentlyContinue | ForEach-Object {
$f = $_
Write-Output ("file=" + $f.Name + " size=" + $f.Length)
$raw = Get-Content $f.FullName -Raw -EA SilentlyContinue
if (-not $raw) { return }
if ($f.Extension -eq ".json") {
try {
$j = $raw | ConvertFrom-Json
foreach ($p in $j.PSObject.Properties) {
Write-Output (" key=" + $p.Name)
if ($p.Name -match '(?i)pass|secret|pwd|root' -and $p.Value -is [string]) {
Add-Cand ("recovery." + $f.Name + "." + $p.Name) ([string]$p.Value)
}
}
} catch {}
} else {
foreach ($line in ($raw -split "`r?`n")) {
if ($line -match '(?i)^(MYSQL_ROOT_PASSWORD|MYSQL_ROOT|ROOT_PASSWORD|password)\s*=\s*(.+)$') {
Add-Cand ("recovery." + $f.Name + "." + $Matches[1]) $Matches[2]
}
if ($line -match '(?i)temporary password is[^:]*:\s*(\S+)') {
Add-Cand ("recovery." + $f.Name + ".temp") $Matches[1]
}
}
}
}
# error log temporary passwords
Get-ChildItem "C:\yutongda\data\mysql" -Recurse -Include *.err,*.log,*.txt -EA SilentlyContinue |
ForEach-Object {
Write-Output ("logscan=" + $_.Name)
Select-String -Path $_.FullName -Pattern "temporary password|A temporary password for" -EA SilentlyContinue |
ForEach-Object {
if ($_.Line -match '(?i)temporary password[^\r\n]*?:\s*(\S+)') {
Add-Cand ("errlog." + $_.Filename) $Matches[1]
}
}
}
# also common install docs under ops
Get-ChildItem "C:\yutongda\ops" -Recurse -Include *.md,*.txt,*.env,*.ps1 -EA SilentlyContinue -Depth 4 |
Select-String -Pattern "MYSQL_ROOT|mysqld.*password|root@localhost" -EA SilentlyContinue |
Select-Object -First 30 |
ForEach-Object {
Write-Output ("ops_hit=" + $_.Filename + ":" + $_.LineNumber)
if ($_.Line -match '(?i)(MYSQL_ROOT_PASSWORD|password)\s*=\s*(\S+)') {
Add-Cand ("ops." + $_.Filename) $Matches[2]
}
if ($_.Line -match '(?i)temporary password[^\r\n]*?:\s*(\S+)') {
Add-Cand ("ops." + $_.Filename + ".temp") $Matches[1]
}
}
Write-Output ("candidates=" + $cands.Count)
$hostModes = @(
@{ n = "socket"; a = @() },
@{ n = "127"; a = @("-h127.0.0.1","-P3306") }
)
$hit = $null
foreach ($c in $cands) {
foreach ($h in $hostModes) {
if (Test-Root $c.pass $h.a) {
Write-Output ("HIT src=" + $c.src + " len=" + $c.len + " mode=" + $h.n)
$hit = $c
Set-Content "E:\wwwroot\ops\.mysql_root_stash.tmp" -Value $c.pass -Encoding ascii -NoNewline
Set-Content "E:\wwwroot\ops\.mysql_root_mode.txt" -Value $h.n -Encoding ascii
break
}
}
if ($hit) { break }
}
if (-not $hit) { Write-Output "NO_ROOT_HIT" }
Write-Output "=== two mysqld processes detail ==="
Get-CimInstance Win32_Process -Filter "Name='mysqld.exe'" | ForEach-Object {
# redact possible password in cmdline
$cmd = $_.CommandLine -replace '(?i)password[=\s]+\S+','password=***'
"pid=$($_.ProcessId) $cmd"
}
Write-Output "=== remote ytd_jeecg: can create? ==="
$dbCred = Get-Content "C:\yutongda\secure\application-database-credentials.json" -Raw | ConvertFrom-Json
$u = [string]$dbCred.mysql_username
$p = [string]$dbCred.mysql_password
$h = [string]$dbCred.mysql_host
$grants = & $mysql "-h$h" -P3306 "-u$u" "-p$p" --batch -e "SHOW GRANTS FOR CURRENT_USER()" 2>&1 | Out-String
($grants -split "`r?`n" | Where-Object { $_ -match "GRANT" }) | ForEach-Object { $_ }
$createTry = & $mysql "-h$h" -P3306 "-u$u" "-p$p" --batch -e "CREATE DATABASE IF NOT EXISTS inquiry_robot_probe_x" 2>&1 | Out-String
if ($createTry -match "ERROR") {
($createTry -split "`r?`n" | Where-Object { $_ -match "ERROR" } | Select-Object -First 1)
} else {
Write-Output "UNEXPECTED_CREATE_OK"
& $mysql "-h$h" -P3306 "-u$u" "-p$p" -e "DROP DATABASE IF EXISTS inquiry_robot_probe_x" 2>&1 | Out-Null
}
Write-Output "DONE"