sync: auto-sync from HOWARD-HOME at 2026-05-06 13:46:20
Author: Howard Enos Machine: HOWARD-HOME Timestamp: 2026-05-06 13:46:20
This commit is contained in:
@@ -0,0 +1,201 @@
|
||||
$ErrorActionPreference = 'Continue'
|
||||
$ProgressPreference = 'SilentlyContinue'
|
||||
|
||||
function Section($name) { "`n===== $name =====" }
|
||||
|
||||
Section 'STEP 1: Service + process view'
|
||||
Get-Service 'MSSQL$SQLEXPRESS','SQLAgent$SQLEXPRESS','SQLBrowser','SQLWriter' -ErrorAction SilentlyContinue | Format-Table Name,Status,StartType -AutoSize
|
||||
|
||||
$svcCim = Get-CimInstance Win32_Service -Filter "Name='MSSQL$SQLEXPRESS'" -ErrorAction SilentlyContinue
|
||||
$sqlexp_pid = $null
|
||||
if ($svcCim) { $sqlexp_pid = [int]$svcCim.ProcessId }
|
||||
"MSSQL`$SQLEXPRESS PID (live from CIM): $sqlexp_pid"
|
||||
|
||||
if ($sqlexp_pid) {
|
||||
Get-Process -Id $sqlexp_pid -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`$SQLEXPRESS"
|
||||
}
|
||||
|
||||
Section 'STEP 2: Registry — installed SQL bits'
|
||||
Get-ItemProperty 'HKLM:\SOFTWARE\Microsoft\Microsoft SQL Server\Instance Names\SQL' -ErrorAction SilentlyContinue | Select-Object * -ExcludeProperty PS* | Format-List
|
||||
|
||||
"--- Per-instance Setup keys ---"
|
||||
Get-ItemProperty 'HKLM:\SOFTWARE\Microsoft\Microsoft SQL Server\*\Setup' -ErrorAction SilentlyContinue |
|
||||
Select-Object PSChildName, Edition, Version, PatchLevel, SqlProgramDir, SqlDataRoot, SQLBinRoot |
|
||||
Format-Table -AutoSize -Wrap
|
||||
|
||||
Section 'STEP 3: Locate sqlcmd'
|
||||
$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"
|
||||
|
||||
Section 'STEP 3a: @@VERSION / SERVERPROPERTY (Windows auth via .\SQLEXPRESS)'
|
||||
$loginOk = $false
|
||||
if ($sqlcmd) {
|
||||
$verOut = & $sqlcmd -S '.\SQLEXPRESS' -E -d master -h-1 -W -l 5 -Q "SET NOCOUNT ON; SELECT @@VERSION; SELECT CAST(@@SERVERNAME AS varchar(200)) + '|' + CAST(SERVERPROPERTY('InstanceName') AS varchar(200)) + '|' + CAST(SERVERPROPERTY('Edition') AS varchar(200)) + '|' + CAST(SERVERPROPERTY('ProductVersion') AS varchar(200)) + '|' + CAST(SERVERPROPERTY('Collation') AS varchar(200));" 2>&1
|
||||
$verOut
|
||||
if ($LASTEXITCODE -eq 0 -and ($verOut -join "`n") -notmatch 'Login failed') { $loginOk = $true }
|
||||
}
|
||||
"loginOk=$loginOk"
|
||||
|
||||
Section 'STEP 3b: ERRORLOG location + tail (always run)'
|
||||
$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 '*SQLEXPRESS*MSSQL\Log\ERRORLOG' -or $_.FullName -like '*MSSQL*SQLEXPRESS*Log*ERRORLOG*' }
|
||||
$el | Select-Object FullName,LastWriteTime,Length | Format-Table -AutoSize
|
||||
|
||||
# Pick most-recently-written one for the tail
|
||||
$primary = $el | Sort-Object LastWriteTime -Descending | Select-Object -First 1
|
||||
if ($primary) {
|
||||
"--- ERRORLOG path: $($primary.FullName) (LastWriteTime: $($primary.LastWriteTime)) ---"
|
||||
"--- Tail 400 lines ---"
|
||||
Get-Content $primary.FullName -Tail 400 -ErrorAction SilentlyContinue
|
||||
} else {
|
||||
"No SQLEXPRESS ERRORLOG located"
|
||||
}
|
||||
|
||||
Section 'STEP 4: sys.databases + sys.master_files (if loginOk)'
|
||||
if ($loginOk -and $sqlcmd) {
|
||||
& $sqlcmd -S '.\SQLEXPRESS' -E -d master -h-1 -W -l 5 -Q "SET NOCOUNT ON; SELECT CAST(name AS varchar(80)) + '|' + CAST(database_id AS varchar(10)) + '|' + state_desc + '|' + recovery_model_desc + '|' + CAST(create_date AS varchar(30)) + '|' + CAST(compatibility_level AS varchar(10)) FROM sys.databases ORDER BY database_id;" 2>&1
|
||||
"--- master_files (user DBs only) ---"
|
||||
& $sqlcmd -S '.\SQLEXPRESS' -E -d master -h-1 -W -l 5 -Q "SET NOCOUNT ON; SELECT CAST(DB_NAME(database_id) AS varchar(80)) + '|' + type_desc + '|' + CAST(name AS varchar(80)) + '|' + CAST(physical_name AS varchar(260)) + '|' + CAST(size*8/1024 AS varchar(20)) + 'MB' FROM sys.master_files WHERE database_id > 4 ORDER BY database_id, type;" 2>&1
|
||||
} else {
|
||||
"Skipped (login failed) — will use file-system fallback below"
|
||||
}
|
||||
|
||||
Section 'STEP 4b: File-system DB enumeration (fallback / cross-check)'
|
||||
# Pull SQLDataRoot from registry for SQLEXPRESS
|
||||
$sqlexpReg = 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 }
|
||||
}
|
||||
$sqlexpReg | Format-Table -AutoSize -Wrap
|
||||
|
||||
$dataDirs = @()
|
||||
$dataDirs += $sqlexpReg | Where-Object { $_.SqlDataRoot } | ForEach-Object { Join-Path $_.SqlDataRoot 'MSSQL\DATA' }
|
||||
$dataDirs += 'C:\Program Files\Microsoft SQL Server\MSSQL*.SQLEXPRESS\MSSQL\DATA'
|
||||
$dataDirs += 'C:\Program Files (x86)\Microsoft SQL Server\MSSQL*.SQLEXPRESS\MSSQL\DATA'
|
||||
$dataDirs = $dataDirs | Where-Object { $_ } | Select-Object -Unique
|
||||
|
||||
"--- DATA dir candidates ---"
|
||||
$dataDirs
|
||||
|
||||
"--- .mdf / .ldf / .ndf under SQLEXPRESS 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 (if loginOk)'
|
||||
if ($loginOk -and $sqlcmd) {
|
||||
& $sqlcmd -S '.\SQLEXPRESS' -E -d master -h-1 -W -l 5 -Q "SET NOCOUNT ON; SELECT CAST(s.session_id AS varchar(10)) + '|' + ISNULL(CAST(s.login_name AS varchar(80)),'-') + '|' + ISNULL(CAST(s.host_name AS varchar(80)),'-') + '|' + ISNULL(CAST(s.program_name AS varchar(120)),'-') + '|' + ISNULL(CAST(s.client_interface_name AS varchar(60)),'-') + '|' + CAST(s.login_time AS varchar(30)) + '|' + CAST(s.last_request_end_time AS varchar(30)) + '|' + ISNULL(CAST(s.status AS varchar(20)),'-') + '|' + ISNULL(CAST(c.client_net_address AS varchar(50)),'-') + '|' + ISNULL(CAST(DB_NAME(s.database_id) AS varchar(80)),'-') 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) — TCP step below provides remote IP evidence"
|
||||
}
|
||||
|
||||
Section 'STEP 6: TCP — listening port + established connections for SQLEXPRESS PID'
|
||||
if ($sqlexp_pid) {
|
||||
"--- State summary ---"
|
||||
Get-NetTCPConnection -OwningProcess $sqlexp_pid -ErrorAction SilentlyContinue | Group-Object State | Select-Object Name,Count | Format-Table -AutoSize
|
||||
|
||||
"--- Listening sockets ---"
|
||||
Get-NetTCPConnection -OwningProcess $sqlexp_pid -State Listen -ErrorAction SilentlyContinue |
|
||||
Select-Object LocalAddress,LocalPort | Format-Table -AutoSize
|
||||
|
||||
"--- Established connections (remote talking to SQLEXPRESS) ---"
|
||||
$est = Get-NetTCPConnection -OwningProcess $sqlexp_pid -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 SQLEXPRESS right now)"
|
||||
}
|
||||
|
||||
"--- UDP (SQL Browser / instance discovery) for this PID ---"
|
||||
Get-NetUDPEndpoint -OwningProcess $sqlexp_pid -ErrorAction SilentlyContinue |
|
||||
Select-Object LocalAddress,LocalPort | Format-Table -AutoSize
|
||||
} else {
|
||||
"No PID — skipping TCP enumeration"
|
||||
}
|
||||
|
||||
Section 'STEP 7: Installed apps (filtered)'
|
||||
$apps = Get-ItemProperty HKLM:\Software\Microsoft\Windows\CurrentVersion\Uninstall\*, HKLM:\Software\WOW6432Node\Microsoft\Windows\CurrentVersion\Uninstall\* -ErrorAction SilentlyContinue |
|
||||
Where-Object { $_.DisplayName } |
|
||||
Select-Object DisplayName, Publisher, InstallDate, DisplayVersion |
|
||||
Sort-Object DisplayName -Unique
|
||||
|
||||
"--- Likely SQL-Express-using apps (AIM, Tri-Tech, MSP360, Cloudberry, Syncro, QuickBooks, Sage, Peachtree, Veeam, Backup, Music, POS, Retail, ScreenConnect) ---"
|
||||
$apps | Where-Object { $_.DisplayName -match 'AIM|Tri-Tech|TriTech|MSP360|Cloudberry|Syncro|QuickBooks|Sage|Peachtree|Veeam|Backup|Music|POS|Retail|ScreenConnect|ConnectWise|Datto|N-able|Acronis|StorageCraft|ShadowProtect|Mozy|Carbonite|WSUS|RDS|Reporting Services|SSRS|Telerik|OpenAccess|Crystal' } |
|
||||
Format-Table -AutoSize -Wrap
|
||||
|
||||
"--- Full SQL-related installs ---"
|
||||
$apps | Where-Object { $_.DisplayName -match 'SQL|Express|Database' } | Format-Table -AutoSize -Wrap
|
||||
|
||||
"--- TOTAL apps installed: $($apps.Count) ---"
|
||||
|
||||
Section 'STEP 8: Connection-string grep — find apps with SQLEXPRESS in their config'
|
||||
$paths = @('C:\ProgramData','C:\Program Files\','C:\Program Files (x86)\','C:\inetpub')
|
||||
$hits = @()
|
||||
foreach ($root in $paths) {
|
||||
if (-not (Test-Path $root)) { continue }
|
||||
try {
|
||||
$files = Get-ChildItem -Path $root -Recurse -Include *.config,*.ini,*.xml,*.json,*.udl -ErrorAction SilentlyContinue -Force -File
|
||||
foreach ($f in $files) {
|
||||
try {
|
||||
$m = Select-String -Path $f.FullName -Pattern 'SQLEXPRESS' -List -ErrorAction SilentlyContinue
|
||||
if ($m) {
|
||||
$hits += [PSCustomObject]@{ Path = $f.FullName; LastWriteTime = $f.LastWriteTime }
|
||||
}
|
||||
} catch {}
|
||||
if ($hits.Count -ge 60) { break }
|
||||
}
|
||||
} catch {}
|
||||
if ($hits.Count -ge 60) { break }
|
||||
}
|
||||
"--- Files referencing SQLEXPRESS (first 60) ---"
|
||||
$hits | Format-Table -AutoSize -Wrap
|
||||
|
||||
# For top hits, show the actual matching line
|
||||
"--- Sample matching lines (first 25 hits) ---"
|
||||
foreach ($h in ($hits | Select-Object -First 25)) {
|
||||
try {
|
||||
$line = (Select-String -Path $h.Path -Pattern 'SQLEXPRESS' -ErrorAction SilentlyContinue | Select-Object -First 1).Line
|
||||
if ($line) {
|
||||
$line = $line.Trim()
|
||||
if ($line.Length -gt 240) { $line = $line.Substring(0,240) + '...' }
|
||||
"$($h.Path) :: $line"
|
||||
}
|
||||
} catch {}
|
||||
}
|
||||
|
||||
Section 'STEP 9: Memory cap (read-only — sp_configure show only, NO RECONFIGURE)'
|
||||
if ($loginOk -and $sqlcmd) {
|
||||
& $sqlcmd -S '.\SQLEXPRESS' -E -d master -h-1 -W -l 5 -Q "SET NOCOUNT ON; SELECT CAST(name AS varchar(60)) + '|' + CAST(value AS varchar(20)) + '|' + CAST(value_in_use AS varchar(20)) + '|' + CAST(minimum AS varchar(20)) + '|' + CAST(maximum AS varchar(20)) 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) — sys.configurations needs auth"
|
||||
}
|
||||
|
||||
Section 'DONE'
|
||||
"Completed at: $(Get-Date -Format 'yyyy-MM-dd HH:mm:ss zzz')"
|
||||
Reference in New Issue
Block a user