Review 1.5: SQL Scripts describe the reviewed Windows server and check rules

Headers of SQLI-WIN-001/006/007/008/009/010/012/013 and SQLI-SYN-001 follow the rule
changes (not measurable instead of passed, caps and summary findings, hourly 24-hour
counts, per-user and updater tasks, neutral check titles); SQLI-WIN-010's severity
gains Low when the event log cannot be read (also in README.md).

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
This commit is contained in:
Søren Eggert Lundsteen Olsen 2026-10-02 15:44:16 +02:00
parent 7e66dc94c4
commit 53ffc008f0
10 changed files with 40 additions and 19 deletions

View file

@ -229,7 +229,7 @@ testen på de filer, der skal opdateres.
| SQLI-WIN-007 | [SQLI-WIN-007.sql](SQLI-WIN-007.sql) | En tjeneste, der skal starte automatisk, kører ikke | CimWindowsServerSource (Windows, ingen SQL) | Medium. |
| SQLI-WIN-008 | [SQLI-WIN-008.sql](SQLI-WIN-008.sql) | En overvåget tjeneste kører ikke | CimWindowsServerSource (Windows, ingen SQL) | High når tjenesten ikke kører; Medium når den ikke findes (eller ikke kan ses). |
| SQLI-WIN-009 | [SQLI-WIN-009.sql](SQLI-WIN-009.sql) | Fejl i Windows' hændelseslog | CimWindowsServerSource (Windows, ingen SQL) | High: disk/filsystem, ressourcer, niveau Critical, tjeneste stoppet 3+ gange. Medium: tjeneste stoppet, program gik ned, Dynamics AX. Low: almindelige fejl der gentager sig. (Uventet nedlukning: se SQLI-WIN-010.) |
| SQLI-WIN-010 | [SQLI-WIN-010.sql](SQLI-WIN-010.sql) | Serveren er genstartet | CimWindowsServerSource (Windows, ingen SQL) | High ved uventet genstart; Info ved genstart uden tegn på at den var uventet. |
| SQLI-WIN-010 | [SQLI-WIN-010.sql](SQLI-WIN-010.sql) | Serveren er genstartet | CimWindowsServerSource (Windows, ingen SQL) | High ved uventet genstart; Info ved genstart uden tegn på at den var uventet; Low når hændelsesloggen ikke kan læses. |
| SQLI-WIN-011 | [SQLI-WIN-011.sql](SQLI-WIN-011.sql) | Serveren er ikke genstartet i lang tid | CimWindowsServerSource (Windows, ingen SQL) | Low. |
| SQLI-WIN-012 | [SQLI-WIN-012.sql](SQLI-WIN-012.sql) | En planlagt opgave fejlede sidste gang, den kørte | CimWindowsServerSource (Windows, ingen SQL) | Medium. |
| SQLI-WIN-013 | [SQLI-WIN-013.sql](SQLI-WIN-013.sql) | En planlagt opgave kørte ikke, da den skulle | CimWindowsServerSource (Windows, ingen SQL) | Medium. |

View file

@ -15,7 +15,9 @@
--
-- Vurdering (sker i C# ud fra de indsamlede data, ikke på den overvågede server):
-- Har de seneste FailuresBeforeFinding kørsler alle fejlet, er det et fund. Titlen siger, om den tilknyttede tjeneste
-- kører, er stoppet, eller om tjekket blot fejler, med fejlteksten som måling (følsom).
-- kører, er stoppet (eller i en anden tilstand) eller ikke findes, eller at tjekket fejler N gange i træk. Fejlteksten
-- står aldrig i titlen (den sendes uredigeret til API og notifikationer), kun som måling (følsom). Er alle de
-- resultater, agenten har givet reglen, fejl, siges "mindst N" gange, og "Fejler siden" er "… eller tidligere".
--
-- Grænseværdier (agentens appsettings.json og tjekkets indstillinger):
-- SQLInsight:SyntheticChecks:FailuresBeforeFinding standard 2 (fejl i træk før et fund: ét tabt svar er ingen alarm)

View file

@ -14,7 +14,8 @@
-- Hvert minut læses tælleren Processor(_Total)\% Processor Time som rå værdi. CPU for minuttet er
-- 100 × (1 − Δ tomgangstid / Δ tid) mellem to læsninger (PERF_100NSEC_TIMER_INV), altså gennemsnittet over hele
-- minuttet, ikke et øjebliksbillede. Er gennemsnittet af minutterne i de seneste SustainedMinutes minutter mindst
-- HighPercent, er det et fund. Uden to læsninger endnu: "ikke målbar".
-- HighPercent, er det et fund. Uden to læsninger endnu: "ikke målbar". Er den forrige læsning mere end tre intervaller
-- gammel (serveren kunne ikke nås et stykke tid), giver minuttet ingen CPU-værdi frem for et gennemsnit af hele hullet.
--
-- Grænseværdier (agentens appsettings.json):
-- SQLInsight:Servers:Cpu:HighPercent standard 90 (gennemsnitlig CPU i procent)

View file

@ -14,8 +14,10 @@
-- Ledig plads pr. drev hver 15. minut gemmes i repositoriet. Prognosen tager timegennemsnit af de seneste
-- ForecastHistoryDays dage – kun siden drevet sidst skiftede størrelse (et udvidet drev starter en ny tendens) – og
-- lægger en ret linje (mindste kvadraters metode) gennem den ledige plads. Hælder linjen nedad, passer den rimeligt
-- (R²), og er der nok historik, er "fuld om ca. N dage" = ledig plads nu / forbrug pr. dag. Svinger pladsen op og ned
-- (backup skrevet og slettet), er der ingen prognose frem for et skræmmende gæt.
-- (R²), og er der nok historik, er "fuld om ca. N dage" = ledig plads ved seneste måling / forbrug pr. dag, talt fra nu
-- (er seneste timegennemsnit mere end en time gammelt, trækkes resten fra). Svinger pladsen op og ned (backup skrevet og
-- slettet), er der ingen prognose frem for et skræmmende gæt. Har intet drev nok historik endnu (en ny server de første
-- par dage), er reglen "ikke målbar" med grunden – ikke "bestået".
--
-- Grænseværdier (agentens appsettings.json):
-- SQLInsight:Servers:Disks:ForecastDays standard 30 (fund når drevet forventes fuldt inden for så mange dage)

View file

@ -12,13 +12,16 @@
--
-- Vurdering (sker i C# ud fra de indsamlede data, ikke på den overvågede server):
-- Et fund pr. tjeneste med StartMode = 'Auto' og State <> 'Running', som hverken står på den indbyggede liste, i
-- Ignore, i serverens ignoreringsliste eller i serverens liste over overvågede tjenester. Ingen fund inden for
-- StartupGraceMinutes efter LastBootUpTime. Viser serveren slet ingen tjenester, er området "ikke målbar"
-- (manglende læseret på Service Control Manager).
-- Ignore, i serverens ignoreringsliste eller i serverens liste over overvågede tjenester. Listerne matcher tjenestens
-- navn eller visningsnavn, præcist eller med præfiks* – på samme måde som SQLI-WIN-008. Højst MaxFindings fund (efter
-- tjenestenavn); resten nævnes i ét samlet fund. Inden for StartupGraceMinutes efter LastBootUpTime er reglen
-- "ikke målbar" (åbne fund forbliver åbne i stedet for at blive løst og genåbnet ved hver genstart). Viser serveren
-- slet ingen tjenester, er området "ikke målbar" (manglende læseret på Service Control Manager).
--
-- Grænseværdier (agentens appsettings.json og serverens indstillinger i SQLInsight Web):
-- SQLInsight:Servers:Services:Ignore ekstra tjenester, der må være stoppet (navn eller præfiks*)
-- SQLInsight:Servers:Services:StartupGraceMinutes standard 15 (ingen fund de første minutter efter en genstart)
-- SQLInsight:Servers:Services:Ignore ekstra tjenester, der må være stoppet (navn, visningsnavn eller præfiks*)
-- SQLInsight:Servers:Services:StartupGraceMinutes standard 15 (ikke målbar de første minutter efter en genstart)
-- SQLInsight:Servers:Services:MaxFindings standard 15 (1–100; fund pr. tjeneste, resten i ét samlet fund)
-- Indbygget liste over automatiske tjenester, der stopper af sig selv (StoppedAutomaticServiceRule.StopByDesign),
-- fx sppsvc, gupdate, edgeupdate, MapsBroker, RemoteRegistry, clr_optimization_*, CDPUserSvc_*.
-- Pr. server: "Tjenester der ignoreres" (insight.WindowsServers.IgnoredServices). Overvågede tjenester (SQLI-WIN-008)

View file

@ -11,12 +11,13 @@
-- skal køre uanset starttype. Når de ikke gør, er det, de leverer, ikke tilgængeligt. SQLInsight starter aldrig selv tjenester.
--
-- Vurdering (sker i C# ud fra de indsamlede data, ikke på den overvågede server):
-- For hvert navn på listen findes tjenesten på navn eller visningsnavn. Findes den ikke: fund (Middel). Er State ikke
-- 'Running': fund (Høj). Uden liste: "ikke relevant".
-- For hvert navn på listen findes tjenesterne på navn eller visningsnavn, præcist eller med præfiks* (samme matchning
-- som SQLI-WIN-007). Findes ingen: fund (Middel). Er State ikke 'Running': fund (Høj) pr. tjeneste. Uden liste:
-- "ikke relevant". Inden for StartupGraceMinutes efter en genstart: "ikke målbar" (åbne fund forbliver åbne).
--
-- Grænseværdier (fast i koden):
-- Listen pr. server: "Overvågede tjenester" (insight.WindowsServers.WatchedServices), sat i SQLInsight Web eller API v1.
-- SQLInsight:Servers:Services:StartupGraceMinutes standard 15 (ingen fund de første minutter efter en genstart)
-- SQLInsight:Servers:Services:StartupGraceMinutes standard 15 (ikke målbar de første minutter efter en genstart)
--
-- Rettigheder på den overvågede server (db/permissions/grant-windows-server.ps1, aldrig lokal administrator):
-- WMI Enable Account/Remote Enable på root\cimv2 + læseret (CC LC RP RC) på Service Control Manager

View file

@ -14,13 +14,17 @@
-- Vurdering (sker i C# ud fra de indsamlede data, ikke på den overvågede server):
-- Hændelser med niveau 1 (kritisk) og 2 (fejl) siden sidste indsamling læses fra System og Application. Støj tælles,
-- men grupperes ikke. Resten grupperes pr. log, kilde og hændelses-id med antal, første og seneste tidspunkt og den
-- nyeste tekst som eksempel (følsom: vises kun lokalt, [udeladt] i API'et). Grupperne fra de seneste 24 timer lægges
-- sammen. Vigtige kategorier giver fund med det samme, almindelige fejl først ved RepeatThreshold gentagelser.
-- nyeste tekst som eksempel (følsom: vises kun lokalt, [udeladt] i API'et). Antallet holdes pr. klokketime, og kun de
-- timer, der har hændelser inden for de seneste 24 timer, lægges sammen – en fejl, der kommer hver 10. time, tæller
-- altså aldrig mere end de 2–3 gange, den faktisk er set på et døgn. Vigtige kategorier giver fund med det samme,
-- almindelige fejl først ved RepeatThreshold gentagelser. Højst MaxFindings fund i en fast rækkefølge (kategori, så den
-- ældste først, så nøglen), så de samme hændelser beholder deres fund; resten nævnes i ét samlet fund med den højeste
-- alvor blandt dem.
--
-- Grænseværdier (agentens appsettings.json):
-- SQLInsight:Servers:EventLog:RepeatThreshold standard 5 (en almindelig fejl skal ses så mange gange på 24 timer)
-- SQLInsight:Servers:EventLog:Ignore ekstra støj: "Kilde:id", "Kilde" eller "Kilde*"
-- SQLInsight:Servers:EventLog:MaxFindings standard 15 (højst så mange fund pr. server, vigtigste først)
-- SQLInsight:Servers:EventLog:MaxFindings standard 15 (1–100; fund pr. hændelse, vigtigste først, resten i ét samlet fund)
-- SQLInsight:Servers:EventLog:MaxEventsPerCollection standard 2000 (hændelser pr. log pr. indsamling)
-- Indbygget støjliste (ServerEventAnalysis.DefaultIgnore): DCOM 10016/10010, Schannel 36874/36887/36888, TPM-WMI 1796/1801,
-- WMI 10, Security-SPP 8198, og SQL Server's egne kilder (MSSQLSERVER, MSSQL$*, SQLSERVERAGENT, SQLAgent$*,

View file

@ -3,7 +3,7 @@
-- ===================================================================================================================
-- Regel-id: SQLI-WIN-010
-- Titel: Serveren er genstartet
-- Alvor: High ved uventet genstart; Info ved genstart uden tegn på at den var uventet.
-- Alvor: High ved uventet genstart; Info ved genstart uden tegn på at den var uventet; Low når hændelsesloggen ikke kan læses.
-- Versioner: Windows Server 2008 R2 og nyere.
--
-- Hvad tjekkes, og hvorfor:
@ -13,7 +13,9 @@
-- Vurdering (sker i C# ud fra de indsamlede data, ikke på den overvågede server):
-- Er LastBootUpTime inden for 24 timer, er serveren genstartet. Er der i hændelsesloggen (seneste 24 timer) en hændelse i
-- kategorien "uventet nedlukning" – Microsoft-Windows-Kernel-Power 41, EventLog 6008, BugCheck/WER-SystemErrorReporting 1001 –
-- senest set tidligst en time før starttidspunktet, er genstarten uventet (Høj), ellers Info.
-- senest set tidligst en time før starttidspunktet, er genstarten uventet (Høj), ellers Info. "Planlagt" siges kun, når
-- hændelsesloggen er læst efter starttidspunktet: er den læst sidst før genstarten, er reglen "ikke målbar", indtil den
-- er indsamlet igen; kan den slet ikke læses, er fundet Low og siger, at årsagen ikke kan ses.
--
-- Grænseværdier (fast i koden):
-- Fast: 24 timer efter LastBootUpTime (ServerEventAnalysis.RecentWindow), derefter forsvinder fundet af sig selv.

View file

@ -11,10 +11,14 @@
-- integrationer eller filbackup: når de fejler, opdager ingen det, før noget mangler.
--
-- Vurdering (sker i C# ud fra de indsamlede data, ikke på den overvågede server):
-- Et fund pr. aktiveret, overvåget opgave, hvis LastTaskResult er en fejl.
-- Et fund pr. aktiveret, overvåget opgave, hvis LastTaskResult er en fejl. Indeholder opgavens navn en brugers SID
-- (S-1-5-21-…), står den i titlen som "bruger-" og en kort hash; det fulde navn kun som følsom måling.
--
-- Grænseværdier (agentens appsettings.json):
-- SQLInsight:Servers:Tasks:IncludeMicrosoftTasks standard false (Microsofts egne opgaver under \Microsoft\ overvåges ikke)
-- SQLInsight:Servers:Tasks:IgnoreUserAndUpdaterTasks standard true (opgaver pr. bruger – en SID i navnet – og programmers
-- egne opdateringsopgaver: OneDrive, MicrosoftEdgeUpdate, GoogleUpdate,
-- User_Feed_Synchronization; TaskResults.DefaultIgnoredNames)
-- SQLInsight:Servers:Tasks:Ignore opgaver der aldrig overvåges (sti\navn eller præfiks*)
-- SQLInsight:Servers:Tasks:MaxWatched standard 50 (højst så mange opgaver pr. server)
-- Resultater, der ikke er fejl: 0x0, 0x41300 (klar), 0x41301 (kører), 0x41302 (deaktiveret), 0x41303 (har ikke kørt),

View file

@ -17,7 +17,9 @@
-- Grænseværdier (agentens appsettings.json):
-- SQLInsight:Servers:Tasks:LateMinutes standard 60 (næste kørsel mere end så mange minutter i fortiden)
-- SQLInsight:Servers:Tasks:IncludeMicrosoftTasks standard false
-- SQLInsight:Servers:Tasks:IgnoreUserAndUpdaterTasks standard true (opgaver pr. bruger og opdateringsopgaver, se SQLI-WIN-012)
-- SQLInsight:Servers:Tasks:Ignore opgaver der aldrig overvåges
-- En brugers SID i opgavens navn står aldrig i titlen ("bruger-" og en kort hash), kun i den følsomme måling.
--
-- Rettigheder på den overvågede server (db/permissions/grant-windows-server.ps1, aldrig lokal administrator):
-- WMI Enable Account/Remote Enable på root\Microsoft\Windows\TaskScheduler (se SQLI-WIN-012 om GetInfo over WinRM).