208 lines
9.9 KiB
PowerShell
208 lines
9.9 KiB
PowerShell
$ErrorActionPreference = 'Continue'
|
|
$ProgressPreference = 'SilentlyContinue'
|
|
|
|
function Section($name) { "`n===== $name =====" }
|
|
|
|
# ---------- Resolve sqlcmd up front ----------
|
|
$sqlcmd = (Get-Command sqlcmd -ErrorAction SilentlyContinue).Source
|
|
if (-not $sqlcmd) {
|
|
foreach ($p in @(
|
|
'C:\Program Files\Microsoft SQL Server\Client SDK\ODBC\170\Tools\Binn\sqlcmd.exe',
|
|
'C:\Program Files\Microsoft SQL Server\Client SDK\ODBC\130\Tools\Binn\sqlcmd.exe',
|
|
'C:\Program Files (x86)\Microsoft SQL Server\Client SDK\ODBC\170\Tools\Binn\sqlcmd.exe',
|
|
'C:\Program Files\Microsoft SQL Server\150\Tools\Binn\SQLCMD.EXE',
|
|
'C:\Program Files\Microsoft SQL Server\140\Tools\Binn\SQLCMD.EXE',
|
|
'C:\Program Files\Microsoft SQL Server\130\Tools\Binn\SQLCMD.EXE'
|
|
)) {
|
|
if (Test-Path $p) { $sqlcmd = $p; break }
|
|
}
|
|
}
|
|
"sqlcmd: $sqlcmd"
|
|
|
|
# ---------- TASK 1: AIMSQL ENUMERATION (READ-ONLY) ----------
|
|
|
|
Section 'STEP 1: Service + process state'
|
|
Get-Service 'MSSQL$AIMSQL','SQLAgent$AIMSQL' -ErrorAction SilentlyContinue | Format-Table Name,Status,StartType -AutoSize
|
|
|
|
$svcCim = Get-CimInstance Win32_Service -Filter "Name='MSSQL`$AIMSQL'" -ErrorAction SilentlyContinue
|
|
$aimsqlPid = $null
|
|
if ($svcCim) { $aimsqlPid = [int]$svcCim.ProcessId }
|
|
"MSSQL`$AIMSQL PID (live from CIM): $aimsqlPid"
|
|
"MSSQL`$AIMSQL StartName (service account): $($svcCim.StartName)"
|
|
|
|
if ($aimsqlPid) {
|
|
Get-Process -Id $aimsqlPid -ErrorAction SilentlyContinue |
|
|
Select-Object Id,StartTime,
|
|
@{n='WSMB';e={[math]::Round($_.WorkingSet64/1MB,1)}},
|
|
@{n='VMMB';e={[math]::Round($_.VirtualMemorySize64/1MB,1)}},
|
|
@{n='PrivateMB';e={[math]::Round($_.PrivateMemorySize64/1MB,1)}},
|
|
Handles,@{n='Threads';e={$_.Threads.Count}},CPU |
|
|
Format-List
|
|
} else {
|
|
"No live PID for MSSQL`$AIMSQL"
|
|
}
|
|
|
|
Section 'STEP 2: Listening port + active TCP connections to AIMSQL'
|
|
if ($aimsqlPid) {
|
|
"--- State summary ---"
|
|
Get-NetTCPConnection -OwningProcess $aimsqlPid -ErrorAction SilentlyContinue |
|
|
Group-Object State | Select-Object Name,Count | Format-Table -AutoSize
|
|
|
|
"--- Listening sockets ---"
|
|
Get-NetTCPConnection -OwningProcess $aimsqlPid -State Listen -ErrorAction SilentlyContinue |
|
|
Select-Object LocalAddress,LocalPort | Format-Table -AutoSize
|
|
|
|
"--- Established connections (remote talking to AIMSQL) ---"
|
|
$est = Get-NetTCPConnection -OwningProcess $aimsqlPid -State Established -ErrorAction SilentlyContinue
|
|
if ($est) {
|
|
$est | Select-Object RemoteAddress,RemotePort,LocalAddress,LocalPort,CreationTime |
|
|
Sort-Object RemoteAddress | Format-Table -AutoSize
|
|
|
|
"--- Reverse-resolve unique remote IPs ---"
|
|
$est.RemoteAddress | Sort-Object -Unique | ForEach-Object {
|
|
$ip = $_
|
|
$name = $null
|
|
try { $name = [System.Net.Dns]::GetHostEntry($ip).HostName } catch {}
|
|
[PSCustomObject]@{ RemoteIP=$ip; HostName=$name }
|
|
} | Format-Table -AutoSize
|
|
} else {
|
|
"(no established connections to AIMSQL right now)"
|
|
}
|
|
|
|
"--- UDP endpoints for this PID ---"
|
|
Get-NetUDPEndpoint -OwningProcess $aimsqlPid -ErrorAction SilentlyContinue |
|
|
Select-Object LocalAddress,LocalPort | Format-Table -AutoSize
|
|
} else {
|
|
"No PID — skipping TCP enumeration"
|
|
}
|
|
|
|
Section 'STEP 3: Windows-auth sqlcmd to .\AIMSQL'
|
|
$loginOk = $false
|
|
if ($sqlcmd) {
|
|
$verOut = & $sqlcmd -S '.\AIMSQL' -E -d master -h-1 -W -l 5 -Q "SET NOCOUNT ON; SELECT @@VERSION;" 2>&1
|
|
$verOut
|
|
"---"
|
|
& $sqlcmd -S '.\AIMSQL' -E -d master -h-1 -W -l 5 -Q "SET NOCOUNT ON; SELECT @@SERVERNAME AS server_name, SERVERPROPERTY('InstanceName') AS instance, SERVERPROPERTY('Edition') AS edition, SERVERPROPERTY('ProductVersion') AS product_version, SERVERPROPERTY('Collation') AS collation;" 2>&1
|
|
if ($LASTEXITCODE -eq 0 -and ($verOut -join "`n") -notmatch 'Login failed') { $loginOk = $true }
|
|
}
|
|
"loginOk=$loginOk"
|
|
|
|
Section 'STEP 4: Databases on AIMSQL (sys.databases + sys.master_files)'
|
|
if ($loginOk -and $sqlcmd) {
|
|
"--- sys.databases ---"
|
|
& $sqlcmd -S '.\AIMSQL' -E -d master -h-1 -W -l 5 -Q "SET NOCOUNT ON; SELECT name, database_id, state_desc, recovery_model_desc, create_date, compatibility_level FROM sys.databases ORDER BY database_id;" 2>&1
|
|
|
|
"--- sys.master_files (user DBs only, database_id > 4) ---"
|
|
& $sqlcmd -S '.\AIMSQL' -E -d master -h-1 -W -l 5 -Q "SET NOCOUNT ON; SELECT database_id, type_desc, name AS logical_name, physical_name, size*8/1024 AS size_mb FROM sys.master_files WHERE database_id > 4 ORDER BY database_id, type;" 2>&1
|
|
} else {
|
|
"Skipped (login failed) — will rely on file-system fallback below"
|
|
}
|
|
|
|
Section 'STEP 4b: File-system DB enumeration (fallback / cross-check) — AIMSQL DATA dirs'
|
|
$aimReg = Get-ItemProperty 'HKLM:\SOFTWARE\Microsoft\Microsoft SQL Server\*\Setup' -ErrorAction SilentlyContinue |
|
|
Where-Object { $_.PSChildName -match '^MSSQL\d+\.' } |
|
|
ForEach-Object {
|
|
$instKey = "HKLM:\SOFTWARE\Microsoft\Microsoft SQL Server\$($_.PSChildName)"
|
|
$instName = (Get-ItemProperty -Path $instKey -ErrorAction SilentlyContinue).Name
|
|
[PSCustomObject]@{ Folder=$_.PSChildName; InstanceName=$instName; SqlDataRoot=$_.SqlDataRoot; SQLBinRoot=$_.SQLBinRoot }
|
|
} | Where-Object { $_.InstanceName -eq 'AIMSQL' }
|
|
$aimReg | Format-Table -AutoSize -Wrap
|
|
|
|
$dataDirs = @()
|
|
$dataDirs += $aimReg | Where-Object { $_.SqlDataRoot } | ForEach-Object { Join-Path $_.SqlDataRoot 'MSSQL\DATA' }
|
|
$dataDirs += 'C:\Program Files\Microsoft SQL Server\MSSQL*.AIMSQL\MSSQL\DATA'
|
|
$dataDirs += 'C:\Program Files (x86)\Microsoft SQL Server\MSSQL*.AIMSQL\MSSQL\DATA'
|
|
$dataDirs += 'S:\*AIMSQL*\MSSQL\DATA'
|
|
$dataDirs = $dataDirs | Where-Object { $_ } | Select-Object -Unique
|
|
"--- DATA dir candidates ---"
|
|
$dataDirs
|
|
|
|
"--- .mdf / .ldf / .ndf under AIMSQL DATA dirs ---"
|
|
foreach ($dir in $dataDirs) {
|
|
Get-ChildItem -Path $dir -Include *.mdf,*.ldf,*.ndf -Recurse -ErrorAction SilentlyContinue |
|
|
Select-Object FullName,@{n='SizeMB';e={[math]::Round($_.Length/1MB,1)}},LastWriteTime |
|
|
Format-Table -AutoSize
|
|
}
|
|
|
|
Section 'STEP 5: Active sessions on AIMSQL'
|
|
if ($loginOk -and $sqlcmd) {
|
|
& $sqlcmd -S '.\AIMSQL' -E -d master -h-1 -W -l 5 -Q "SET NOCOUNT ON; SELECT s.session_id, s.login_name, s.host_name, s.program_name, s.client_interface_name, s.login_time, s.last_request_end_time, s.status, c.client_net_address FROM sys.dm_exec_sessions s LEFT JOIN sys.dm_exec_connections c ON s.session_id = c.session_id WHERE s.is_user_process = 1 ORDER BY s.login_time;" 2>&1
|
|
} else {
|
|
"Skipped (login failed)"
|
|
}
|
|
|
|
Section 'STEP 6: AIMSQL ERRORLOG location + tail'
|
|
$el = Get-ChildItem -Path 'C:\Program Files\Microsoft SQL Server\','C:\Program Files (x86)\Microsoft SQL Server\','S:\','D:\','E:\' -Recurse -Filter ERRORLOG -ErrorAction SilentlyContinue |
|
|
Where-Object { $_.FullName -like '*AIMSQL*MSSQL\Log\ERRORLOG' -and $_.FullName -notlike '*SQLEXPRESS*' } |
|
|
Select-Object -First 5
|
|
$el | Select-Object FullName,LastWriteTime,Length | Format-Table -AutoSize
|
|
|
|
$primary = $el | Sort-Object LastWriteTime -Descending | Select-Object -First 1
|
|
if ($primary) {
|
|
"--- ERRORLOG path: $($primary.FullName) (LastWriteTime: $($primary.LastWriteTime)) ---"
|
|
"--- Tail 200 lines ---"
|
|
Get-Content $primary.FullName -Tail 200 -ErrorAction SilentlyContinue
|
|
} else {
|
|
"No AIMSQL ERRORLOG located"
|
|
}
|
|
|
|
Section 'STEP 7: Memory cap (sp_configure read-only)'
|
|
if ($loginOk -and $sqlcmd) {
|
|
& $sqlcmd -S '.\AIMSQL' -E -d master -h-1 -W -l 5 -Q "SET NOCOUNT ON; SELECT name, value, value_in_use, minimum, maximum FROM sys.configurations WHERE name IN ('max server memory (MB)','min server memory (MB)','show advanced options') ORDER BY name;" 2>&1
|
|
} else {
|
|
"Skipped (login failed)"
|
|
}
|
|
|
|
Section 'STEP 8: Sanity — AIMSQL backup folders + .bak files'
|
|
"--- AIMSQL-named directories ---"
|
|
Get-ChildItem -Path 'C:\Program Files\Microsoft SQL Server\','S:\','E:\' -Recurse -Filter '*AIMSQL*' -Directory -ErrorAction SilentlyContinue |
|
|
Select-Object FullName | Format-Table -AutoSize -Wrap
|
|
|
|
"--- .bak files under AIMSQL Backup dirs ---"
|
|
$bakRoots = @(
|
|
'C:\Program Files\Microsoft SQL Server\MSSQL*.AIMSQL\MSSQL\Backup',
|
|
'S:\*AIMSQL*\MSSQL\Backup',
|
|
'S:\Backup',
|
|
'S:\Backups'
|
|
)
|
|
foreach ($r in $bakRoots) {
|
|
Get-ChildItem -Path $r -Filter '*.bak' -Recurse -ErrorAction SilentlyContinue |
|
|
Select-Object FullName,@{n='SizeMB';e={[math]::Round($_.Length/1MB,1)}},LastWriteTime |
|
|
Format-Table -AutoSize
|
|
}
|
|
|
|
# ---------- TASK 2: UNREGISTER SCHEDULED TASK (AUTHORIZED CHANGE) ----------
|
|
|
|
Section 'TASK 2: Unregister AIMSQL_Restart_20260506_0230 scheduled task'
|
|
$task = Get-ScheduledTask -TaskName 'AIMSQL_Restart_20260506_0230' -ErrorAction SilentlyContinue
|
|
if ($task) {
|
|
$info = $task | Get-ScheduledTaskInfo
|
|
"Found task — last run: $($info.LastRunTime), result: $($info.LastTaskResult), next run: $($info.NextRunTime)"
|
|
try {
|
|
Unregister-ScheduledTask -TaskName 'AIMSQL_Restart_20260506_0230' -Confirm:$false -ErrorAction Stop
|
|
"Unregistered successfully."
|
|
} catch {
|
|
"Unregister FAILED: $_"
|
|
}
|
|
"--- Confirm gone ---"
|
|
$check = Get-ScheduledTask -TaskName 'AIMSQL_Restart_20260506_0230' -ErrorAction SilentlyContinue
|
|
if ($check) {
|
|
"STILL PRESENT (failure)"
|
|
} else {
|
|
"Confirmed: task no longer registered."
|
|
}
|
|
} else {
|
|
"Task not found — already removed?"
|
|
}
|
|
|
|
Section 'TASK 2b: Audit-trail artifacts (do NOT delete)'
|
|
"--- aimsql-restart.ps1 ---"
|
|
$ps = Get-Item C:\Windows\Temp\aimsql-restart.ps1 -ErrorAction SilentlyContinue
|
|
if ($ps) { $ps | Select-Object FullName, Length, LastWriteTime | Format-List } else { "MISSING C:\Windows\Temp\aimsql-restart.ps1" }
|
|
"--- aimsql-restart.log ---"
|
|
$lg = Get-Item C:\Windows\Temp\aimsql-restart.log -ErrorAction SilentlyContinue
|
|
if ($lg) { $lg | Select-Object FullName, Length, LastWriteTime | Format-List } else { "MISSING C:\Windows\Temp\aimsql-restart.log" }
|
|
|
|
Section 'DONE'
|
|
"Completed at: $(Get-Date -Format 'yyyy-MM-dd HH:mm:ss zzz')"
|