Deadlines
- Event log over RPC (MS-EVEN6): the whole read has a deadline (OperationTimeout per log);
the token cancels the EventLogSession's operations and is checked before each
FormatDescription, and the agent stops waiting even if the native call ignores it.
Reported as ServerAccessProblem.Timeout ("svarede ikke i tide over hændelsesloggens
protokol (RPC) inden for N sekunder").
- Every CIM call runs on the thread pool and is awaited with the caller's token; a call
that ignores cancellation is abandoned and the CIM session is closed once it returns.
- Each server cycle has a deadline (new SQLInsight:Servers:CycleTimeout, default 5 min,
1-30 min, at least 2 x OperationTimeout): the areas not read by then are "ikke målbar"
("Serveren svarede ikke inden for N minutter, så indsamlingen blev afbrudt; …"),
logged once, and the slot is freed.
- Scheduled tasks: run information is read within a time budget (CycleTimeout / 3); the
rest keep their state without the last run, and the coverage note says so.
- "Test server" has an overall deadline (WindowsServerTester, default 2 min); areas not
done in time are reported as not answered, so the result is always stored.
Backoff and memory
- A server that does not answer (Unreachable/Timeout, or a timed-out cycle) is backed
off 1, 2, 5, 10, then 15 minutes, reset when it answers.
- Protocol Auto: the protocol that worked (e.g. DCOM after WS-Man was refused, also for
access denied) is tried first for an hour, then WS-Man is tried again; a server whose
event log RPC failed is read over CIM for an hour.
- Over WS-Man with read-only WinRM rights Task Scheduler's GetInfoByName is denied: with
Auto the tasks are read over DCOM instead (remembered for the server); with WSMan forced
the reason says to choose Auto or DCOM. The advice "winrm configSDDL default" (broader
WinRM rights) is gone; texts follow the grant script (-WinRM read right,
-EnableFirewall -AgentAddress), not Remote Management Users.
Events
- Each log continues from its own mark (ServerEventSnapshot.LogReadUntil, a small additive
field in Core): a truncated System log no longer loses the events between its last
read event and the newest Application event.
- CIM fallback: Win32_NTLogEvent is streamed and only the oldest max per log are kept
(memory bounded, deterministic order), consistent with the RPC read and the coverage
text, which now names the logs that had more.
Other
- CimInstances (and method results) are mapped to SQLInsight's types and disposed at once.
- Options are clamped when bound (ServerOptions/SyntheticCheckOptions.Normalize):
OperationTimeout 5 s-5 min, MaxEventsPerCollection 10-10000, MaxWatched 1-200,
MaxParallelServers/Checks 1-32, retention days >= 1, ForecastHistoryDays 1-365,
FailuresBeforeFinding/SlowRunsBeforeFinding 1-99.
- Shutdown: the timer's cancellation is caught, running cycles are awaited before the
throttle is disposed; a cycle's time is taken when it gets its slot; a TaskCanceledException
that is not shutdown no longer ends the service.
- Retention maintenance also runs (hourly) when SQLInsight:Servers:Enabled is false but
synthetic checks are on.
- LocalCimTests run alone (collection without parallelization), share one warmed-up
session, use the same 2 min operation timeout and a 5 min deadline per test, a smaller
workload, and report timings in assertion messages.
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
- An HTTP answer that breaks off while it is read (HttpIOException/IOException) is a
failed check ("Svaret blev afbrudt, mens det blev læst: …"), not an exception that
made the check rerun every tick. Other unforeseen network errors (IOException,
SocketException, HttpRequestException, AuthenticationException) become
"Forbindelsen fejlede: …"; one that hits the check's deadline is "Intet svar inden
for N sekunder". DNS: an invalid name (ArgumentException) is a failed lookup.
- The HTTP "Adresse" detail (a URL may carry query secrets) and the AX "Object server"
detail are Sensitive, so the API redacts them.
- SyntheticCheckRun's compiler-generated ToString no longer prints the SQL password.
- ProcessRunner (AX Business Connector logon): the PowerShell process tree is killed in
a finally whenever it has not exited, also when the agent stops (before: only on the
check's timeout, leaving an orphaned process and AX session). Output and errors are
capped at 64 K characters each; the rest is read and dropped so the process never
blocks on a full pipe.
- Tests: broken body, password redaction, bounded output, killed on agent stop.
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
The grant script changes SCM and WMI security on customer servers. Before, a re-run
replaced every ACE of the account on a WMI namespace (also a customer's Deny), -Remove
took the account out of groups and ACEs it had before, only the SCM SDDL was backed up
(and never used), Remote Management Users also opened PowerShell Remoting, and
-EnableFirewall narrowed Windows' built-in rules for every other tool and was never undone.
- Checks everything before changing anything: elevation, the account resolves (broad
groups refused), Deny ACEs stop the script, -EnableFirewall needs -AgentAddress.
- Backs up the original SDDLs (SCM, WMI namespaces, WinRM), group memberships and
firewall rules before the first change; records what it added in a state file in an
administrators-only folder; -Remove removes only that.
- SDDL handled with RawSecurityDescriptor (GetSD/SetSD, sc sdshow/sdset): exactly one
ACE added in canonical order, verified before writing and after; aliases (NS) work.
- No Remote Management Users: -WinRM adds GENERIC_READ (no Execute) to WinRM's RootSDDL;
DCOM is the default.
- Firewall: its own "SQLInsight Agent: ..." rules only from the agent's address,
removed again with -Remove; Windows' rules untouched.
- -WhatIf, groups by SID, Danish messages, PowerShell 2.0 syntax.
- ServerGrantScript.For does not fill in an account that could end the PowerShell
string (typographic quotes, control characters); tests run the SDDL logic in
Windows PowerShell against real default SDDLs.
- docs/windows-servere.md: rights, safety net, firewall.
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
After the rebase onto 1.4 the 16 SQLI-WIN/SQLI-SYN scripts had their own /* */ format,
so SqlScriptTests (rule ids, review header, -- Kilde: blocks) failed.
- The scripts have main's header (Regel-id, Titel, Alvor, Versioner, Vurdering,
Grænseværdier, Rettigheder, Data kommer fra, Regelkode, Read-only); the Windows
WQL/XPath stays word for word in comments.
- The synthetic SQL check's SQL is registered (SyntheticCheckRunner.UseDatabaseSql,
BeginTransactionSql, RollbackSql, SyntheticCheckSettings.DefaultQuery) and shown
as -- Kilde: blocks in SQLI-SYN-001/002 and _collectors/SyntheticCheckRunner.sql.
- SqlScriptTests know ServerRuleCatalog; only those rules may be without SQL blocks.
- ServerScriptTests: every CimQueries query/filter is in a SQLI-WIN script word for word.
- The SQL check cancels the rest of a large answer instead of draining it on close.
- Rule counts: README (108 built-in: 92 SQL Server + 13 Windows + 3 synthetic),
SQL Scripts/README (rule table, 124 rules, Windows/synthetic section), RuleCatalogTests,
CONTRIBUTING (how to add a server rule).
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
- ServerMonitoringService keeps the SQL Server hosts in step with the monitored
instances (SQLInsight:Servers:IncludeSqlHosts), picks up servers added, paused or
changed in SQLInsight Web within a minute, and runs each server's due areas with
a limit on parallelism. Default intervals: 1 min CPU/memory, 15 min disks and
tasks, 5 min services and events (SQLInsight:Servers:Intervals).
- ServerMonitor: one CIM session per cycle; per-minute samples, disk samples and
the "fuld om ca. N dage" forecast from the stored history, grouped events (read
from where the last read stopped), services and tasks. A missing right makes
only that area "ikke målbar" with the exact reason, logged once per change; a
server that does not answer is notified once, and again when it answers.
Survives an agent restart (samples, boot time, event position).
- SyntheticCheckService runs checks on their interval, opens a SQL login password
sealed for the agent (AgentCredentialKey.OpenContext), looks up the linked
Windows service when a check fails, stores results and findings, notifies with
links to /servere/fund/{id}.
- AgentRequestService hands ServerTest and SyntheticCheckRun to ServerRequestHandler.
- appsettings.json: SQLInsight:Servers and SQLInsight:SyntheticChecks with every
threshold, interval and retention.
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
New project SQLInsight.Servers:
- CimWindowsServerSource (Microsoft.Management.Infrastructure, the API behind
Get-CimInstance): WS-Man first, DCOM if that fails, a local session for the
agent's own computer, as the agent's identity. Only SELECT queries (CimQueries)
and Task Scheduler's read-only GetInfo. CPU and paging from raw counters, disks
(Win32_Volume, Win32_LogicalDisk fallback), services, scheduled tasks, and the
System/Application logs through the Event Log service (MS-EVEN6, XPath filter on
the server) with Win32_NTLogEvent as fallback.
- ServerErrors: access denied, missing namespace, RPC/WinRM unreachable and
timeouts become "ikke målbar" reasons that name the missing right and the grant
script; never local administrator.
- WindowsServerTester: tries every area once for the web UI's test.
- SyntheticCheckRunner: TCP, HTTP(S) with expected status/text and TLS certificate
expiry (also for refused certificates), SQL login + read-only query (re-validated,
in a transaction that is always rolled back), DNS, and the Dynamics AX logon:
AOS port, then a logon through the .NET Business Connector in a separate Windows
PowerShell process with a timeout when it is installed; otherwise the result
says clearly that only the port was tested.
Tests: error mapping, queries, AX command/parsing, runners against local TCP and
HTTP(S) servers with a self-signed certificate, the CIM source against this
computer, and the SQL check against the test instance.
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>