Skip to content

Commit 4fec196

Browse files
Uwe Jankeclaude
andcommitted
feat: DiskFreeSpaceThreshold konfigurierbar + OutputPath aus Config
- Neuer Config-Key DiskFreeSpaceThresholdPct (Default 10%) via Set-sqmConfig - Get-sqmDiskInfoByDriveLetter: ThresholdPct + ExtendNeededGB im Result-Objekt - Get-sqmServerHardwareReport: Spalte Erweiterung in HTML/TXT; OutputPath aus Config - Export-sqmServerConfiguration, Test-sqmSSISPackageCompatibility: OutputPath aus Config - Invoke-sqmSplunkConfiguration, New-sqmOla*: LogPath-Fallback korrigiert (Single-Quote-Bug) Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
1 parent 7ad8295 commit 4fec196

10 files changed

Lines changed: 92 additions & 36 deletions

Public/Export-sqmServerConfiguration.ps1

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -108,7 +108,9 @@ function Export-sqmServerConfiguration
108108
# Default OutputPath
109109
if (-not $OutputPath)
110110
{
111-
$OutputPath = "$env:ProgramData\sqmSQLTool\Snapshots"
111+
$configOutput = Get-sqmConfig -Key 'OutputPath'
112+
$OutputPath = if ($configOutput) { Join-Path $configOutput 'Snapshots' }
113+
else { Join-Path $env:ProgramData 'sqmSQLTool\Snapshots' }
112114
}
113115

114116
# Ensure output directory exists

Public/Get-sqmDiskInfoByDriveLetter.ps1

Lines changed: 22 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -94,6 +94,14 @@ function Get-sqmDiskInfoByDriveLetter
9494
[math]::Round(($logicalDisk.FreeSpace / $logicalDisk.Size) * 100, 2)
9595
} else { 0 }
9696

97+
# Berechnung: Wie viel GB muss das Laufwerk erweitert werden, damit >= Schwellwert% frei sind?
98+
# Formel: (Free+X)/(Total+X) = t => X = (t*Total - Free) / (1-t)
99+
$threshold = [int](Get-sqmConfig -Key 'DiskFreeSpaceThresholdPct')
100+
$thresholdRatio = $threshold / 100.0
101+
$extendNeededGB = if ($freePercent -lt $threshold -and $logicalDisk.Size -gt 0) {
102+
[math]::Ceiling(($thresholdRatio * $totalGB - $freeGB) / (1 - $thresholdRatio))
103+
} else { 0 }
104+
97105
$serialNumber = if ([string]::IsNullOrWhiteSpace($disk.SerialNumber)) {
98106
'N/A'
99107
} else {
@@ -128,20 +136,23 @@ function Get-sqmDiskInfoByDriveLetter
128136
$machine = Get-sqmMachineType
129137

130138
$result = [PSCustomObject]@{
131-
DriveLetter = "${Letter}:"
132-
DiskNumber = $diskNumber
133-
TotalGB = $totalGB
134-
FreeGB = $freeGB
135-
FreePercent = $freePercent
136-
SerialNumber = $serialNumber
137-
IsVM = $machine.IsVM
138-
MachineType = $machine.MachineType
139-
IsPartitionedDisk = $isPartitioned
140-
SharedWith = $sharedWith
139+
DriveLetter = "${Letter}:"
140+
DiskNumber = $diskNumber
141+
TotalGB = $totalGB
142+
FreeGB = $freeGB
143+
FreePercent = $freePercent
144+
ThresholdPct = $threshold
145+
ExtendNeededGB = $extendNeededGB
146+
SerialNumber = $serialNumber
147+
IsVM = $machine.IsVM
148+
MachineType = $machine.MachineType
149+
IsPartitionedDisk = $isPartitioned
150+
SharedWith = $sharedWith
141151
}
142152

153+
$extMsg = if ($extendNeededGB -gt 0) { " ERWEITERUNG NOETIG: +${extendNeededGB} GB" } else { '' }
143154
$partMsg = if ($isPartitioned) { " GETEILT mit: $sharedWith" } else { '' }
144-
Invoke-sqmLogging -Message "[$Letter`:] DiskNr=$diskNumber Total=${totalGB} GB Free=${freeGB} GB (${freePercent}%) SN=$serialNumber Typ=$($machine.MachineType)$partMsg" -FunctionName $functionName -Level "INFO"
155+
Invoke-sqmLogging -Message "[$Letter`:] DiskNr=$diskNumber Total=${totalGB} GB Free=${freeGB} GB (${freePercent}%) SN=$serialNumber Typ=$($machine.MachineType)$partMsg$extMsg" -FunctionName $functionName -Level "INFO"
145156

146157
$results.Add($result)
147158
$result

Public/Get-sqmServerHardwareReport.ps1

Lines changed: 44 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -107,7 +107,9 @@ function Get-sqmServerHardwareReport
107107

108108
if (-not $PSBoundParameters.ContainsKey('ReportPath') -or [string]::IsNullOrWhiteSpace($ReportPath))
109109
{
110-
$ReportPath = Join-Path $env:ProgramData 'sqmSQLTool\HardwareReports'
110+
$configOutput = Get-sqmConfig -Key 'OutputPath'
111+
$ReportPath = if ($configOutput) { Join-Path $configOutput 'HardwareReports' }
112+
else { Join-Path $env:ProgramData 'sqmSQLTool\HardwareReports' }
111113
}
112114

113115
if (-not (Test-Path $ReportPath))
@@ -538,31 +540,47 @@ function _Build-sqmHardwareReportHtml
538540
# -------------------------------------------------------------------------
539541
# ABSCHNITT: Logische Laufwerke
540542
# -------------------------------------------------------------------------
543+
$diskThreshold = [int](Get-sqmConfig -Key 'DiskFreeSpaceThresholdPct')
544+
$diskThresholdRatio = $diskThreshold / 100.0
545+
541546
$logHtml = "<table class='itbl'><thead><tr>" +
542547
"<th>Laufwerk</th><th>Label</th><th>Dateisystem</th>" +
543-
"<th>Gesamt</th><th>Belegt</th><th>Frei</th><th>Auslastung</th>" +
548+
"<th>Gesamt</th><th>Belegt</th><th>Frei</th><th>Auslastung</th><th>Erweiterung</th>" +
544549
"</tr></thead><tbody>"
545550

546551
foreach ($ld in ($d.LogicalDisks | Sort-Object DeviceID))
547552
{
548-
$ldTotal = if ($ld.Size) { _Size ([double]$ld.Size) } else { 'n/a' }
549-
$ldFree = if ($ld.FreeSpace) { _Size ([double]$ld.FreeSpace) } else { 'n/a' }
550-
$ldUsed = if ($ld.Size -and $ld.FreeSpace) { _Size ([double]($ld.Size - $ld.FreeSpace)) } else { 'n/a' }
551-
$pctUsed = if ($ld.Size -gt 0) { [int](([double]($ld.Size - $ld.FreeSpace) / [double]$ld.Size) * 100) } else { 0 }
553+
$ldTotalBytes = if ($ld.Size) { [double]$ld.Size } else { 0 }
554+
$ldFreeBytes = if ($ld.FreeSpace) { [double]$ld.FreeSpace } else { 0 }
555+
$ldTotal = if ($ldTotalBytes -gt 0) { _Size $ldTotalBytes } else { 'n/a' }
556+
$ldFree = if ($ldFreeBytes -gt 0) { _Size $ldFreeBytes } else { 'n/a' }
557+
$ldUsed = if ($ldTotalBytes -gt 0) { _Size ($ldTotalBytes - $ldFreeBytes) } else { 'n/a' }
558+
$pctUsed = if ($ldTotalBytes -gt 0) { [int](($ldTotalBytes - $ldFreeBytes) / $ldTotalBytes * 100) } else { 0 }
552559
$pctFree = 100 - $pctUsed
553-
$barColor = if ($pctFree -lt 10) { '#e74c3c' } elseif ($pctUsed -ge 90) { '#e74c3c' } elseif ($pctUsed -ge 75) { '#f39c12' } else { '#27ae60' }
560+
$isCritical = $pctFree -lt $diskThreshold
561+
$barColor = if ($isCritical) { '#e74c3c' } elseif ($pctUsed -ge 90) { '#e74c3c' } elseif ($pctUsed -ge 75) { '#f39c12' } else { '#27ae60' }
554562
$bar = "<div class='dbar'><div class='dfill' style='width:{0}%;background:{1}'></div></div><span class='dpct'>{0}%</span>" -f $pctUsed, $barColor
555563
$drive = if ($ld.DeviceID) { "$($ld.DeviceID)\" } else { 'n/a' }
556564
$fs = if ($ld.FileSystem) { [string]$ld.FileSystem } else { 'n/a' }
557565
$volName = if ($ld.VolumeName) { [string]$ld.VolumeName } else { '' }
558-
$warningFlag = if ($pctFree -lt 10) { " ⚠️ KRITISCH" } else { '' }
566+
$warningFlag = if ($isCritical) { " &#9888; KRITISCH" } else { '' }
567+
568+
# Erweiterungsberechnung: (t*Total - Free) / (1-t) auf naechstes GB aufrunden
569+
$extendCell = if ($isCritical -and $ldTotalBytes -gt 0) {
570+
$totalGB = $ldTotalBytes / 1GB
571+
$freeGB = $ldFreeBytes / 1GB
572+
$extGB = [math]::Ceiling(($diskThresholdRatio * $totalGB - $freeGB) / (1 - $diskThresholdRatio))
573+
"<span style='color:#e74c3c;font-weight:700'>+${extGB} GB</span>"
574+
} else {
575+
"<span style='color:#27ae60'>&#10003; OK</span>"
576+
}
559577

560578
$logHtml += "<tr><td><strong>$(_H $drive)</strong></td><td>$(_H $volName)</td><td>$(_H $fs)</td>" +
561-
"<td>$(_H $ldTotal)</td><td>$(_H $ldUsed)</td><td>$(_H $ldFree)</td><td>$bar$warningFlag</td></tr>"
579+
"<td>$(_H $ldTotal)</td><td>$(_H $ldUsed)</td><td>$(_H $ldFree)</td><td>$bar$warningFlag</td><td>$extendCell</td></tr>"
562580
}
563581
if ($d.LogicalDisks.Count -eq 0)
564582
{
565-
$logHtml += '<tr><td colspan="7" class="norow">Keine lokalen Laufwerke gefunden</td></tr>'
583+
$logHtml += '<tr><td colspan="8" class="norow">Keine lokalen Laufwerke gefunden</td></tr>'
566584
}
567585
$logHtml += '</tbody></table>'
568586

@@ -940,19 +958,28 @@ function _Build-sqmHardwareReportTxt
940958
}
941959
}
942960

943-
# Detaillierte Logical Disk-Infos mit < 10% Warnung
961+
# Detaillierte Logical Disk-Infos mit Schwellwert-Warnung und Erweiterungsberechnung
962+
$txtThreshold = [int](Get-sqmConfig -Key 'DiskFreeSpaceThresholdPct')
963+
$txtThresholdRatio = $txtThreshold / 100.0
944964
if ($Data.LogicalDisks.Count -gt 0)
945965
{
946966
$lines += ""
947-
$lines += " [LOGISCHE LAUFWERKE]"
967+
$lines += " [LOGISCHE LAUFWERKE] (Schwellwert: $txtThreshold% frei)"
948968
foreach ($ld in ($Data.LogicalDisks | Sort-Object DeviceID))
949969
{
950970
$drive = if ($ld.DeviceID) { "$($ld.DeviceID)\" } else { 'n/a' }
951-
$total = if ($ld.Size) { '{0:N0}' -f ([double]$ld.Size / 1GB) + ' GB' } else { 'n/a' }
952-
$free = if ($ld.FreeSpace) { '{0:N0}' -f ([double]$ld.FreeSpace / 1GB) + ' GB' } else { 'n/a' }
953-
$pctFree = if ($ld.Size -gt 0) { [int](([double]$ld.FreeSpace / [double]$ld.Size) * 100) } else { 0 }
954-
$warning = if ($pctFree -lt 10) { " [!!! KRITISCH !!!]" } else { '' }
955-
$lines += " $drive $total Gesamt, $free Frei ($pctFree% frei)$warning"
971+
$totalGB = if ($ld.Size) { [double]$ld.Size / 1GB } else { 0 }
972+
$freeGB = if ($ld.FreeSpace) { [double]$ld.FreeSpace / 1GB } else { 0 }
973+
$total = '{0:N0}' -f $totalGB + ' GB'
974+
$free = '{0:N0}' -f $freeGB + ' GB'
975+
$pctFree = if ($ld.Size -gt 0) { [int](($freeGB / $totalGB) * 100) } else { 0 }
976+
$extMsg = ''
977+
if ($pctFree -lt $txtThreshold -and $totalGB -gt 0)
978+
{
979+
$extGB = [math]::Ceiling(($txtThresholdRatio * $totalGB - $freeGB) / (1 - $txtThresholdRatio))
980+
$extMsg = " [!!! KRITISCH !!! Erweiterung um +$extGB GB noetig]"
981+
}
982+
$lines += " $drive $total Gesamt, $free Frei ($pctFree% frei)$extMsg"
956983
}
957984
}
958985

Public/Invoke-sqmSplunkConfiguration.ps1

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -377,7 +377,7 @@ function Invoke-sqmSplunkConfiguration {
377377

378378
if (-not $LogPath) {
379379
$LogPath = Get-sqmConfig -Key 'LogPath'
380-
if (-not $LogPath) { $LogPath = '$env:ProgramData\sqmSQLTool\Logs' }
380+
if (-not $LogPath) { $LogPath = Join-Path $env:ProgramData 'sqmSQLTool\Logs' }
381381
}
382382

383383
$result = [PSCustomObject]@{

Public/New-sqmOlaMaintenanceJobs.ps1

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -235,10 +235,10 @@ function New-sqmOlaMaintenanceJobs
235235
if ($SqlCredential) { $connParams['SqlCredential'] = $SqlCredential }
236236

237237
$logDir = $cfg['LogPath']
238-
if (-not $logDir) { $logDir = '$env:ProgramData\sqmSQLTool\Logs' }
238+
if (-not $logDir) { $logDir = Join-Path $env:ProgramData 'sqmSQLTool\Logs' }
239239
$maintenanceLogDir = Join-Path $logDir 'MaintenanceLog'
240240
$centralLogDir = $cfg['CentralPath']
241-
241+
242242
$dayNames = @{ 1 = 'Sonntag'; 2 = 'Montag'; 4 = 'Dienstag'; 8 = 'Mittwoch'; 16 = 'Donnerstag'; 32 = 'Freitag'; 64 = 'Samstag' }
243243
$schedDayName = if ($dayNames.ContainsKey($ScheduleDay)) { $dayNames[$ScheduleDay] }
244244
else { "Tag $ScheduleDay" }

Public/New-sqmOlaSysDbBackupJob.ps1

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -147,7 +147,7 @@ function New-sqmOlaSysDbBackupJob
147147
if ($SqlCredential) { $connParams['SqlCredential'] = $SqlCredential }
148148

149149
$logDir = $cfg['LogPath']
150-
if (-not $logDir) { $logDir = '$env:ProgramData\sqmSQLTool\Logs' }
150+
if (-not $logDir) { $logDir = Join-Path $env:ProgramData 'sqmSQLTool\Logs' }
151151
$maintenanceLogDir = Join-Path $logDir 'MaintenanceLog'
152152
$centralLogDir = $cfg['CentralPath']
153153
}

Public/New-sqmOlaUsrDbBackupJob.ps1

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -362,7 +362,7 @@ function New-sqmOlaUsrDbBackupJob
362362
}
363363

364364
$logDir = $cfg['LogPath']
365-
if (-not $logDir) { $logDir = '$env:ProgramData\sqmSQLTool\Logs' }
365+
if (-not $logDir) { $logDir = Join-Path $env:ProgramData 'sqmSQLTool\Logs' }
366366
$maintenanceLogDir = Join-Path $logDir 'MaintenanceLog'
367367
$centralLogDir = $cfg['CentralPath']
368368

Public/Set-sqmConfig.ps1

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -86,6 +86,12 @@
8686
Empfohlene NTFS-Blockgroesse in Bytes fuer Get-sqmDiskBlockSize.
8787
Standard: 65536 (64 KB)
8888
89+
.PARAMETER DiskFreeSpaceThresholdPct
90+
Schwellwert (in Prozent) fuer den freien Speicherplatz auf Laufwerken.
91+
Laufwerke unterhalb dieses Schwellwerts werden als kritisch markiert und
92+
die benoetigte Erweiterung wird automatisch berechnet.
93+
Standard: 10 (10 %)
94+
8995
.PARAMETER Language
9096
Output language of the module. Allowed values: de-DE, en-US.
9197
Default: de-DE.
@@ -163,6 +169,9 @@ function Set-sqmConfig
163169
[ValidateSet(4096, 8192, 16384, 32768, 65536, 131072)]
164170
[int]$CheckDiskBlockSize,
165171
[Parameter(Mandatory = $false)]
172+
[ValidateRange(1, 50)]
173+
[int]$DiskFreeSpaceThresholdPct,
174+
[Parameter(Mandatory = $false)]
166175
[ValidateSet('de-DE', 'en-US')]
167176
[string]$Language,
168177
[Parameter(Mandatory = $false)]
@@ -433,6 +442,11 @@ function Set-sqmConfig
433442
$globalConfig['CheckDiskBlockSize'] = $CheckDiskBlockSize
434443
$updated = $true
435444
}
445+
if ($PSBoundParameters.ContainsKey('DiskFreeSpaceThresholdPct'))
446+
{
447+
$globalConfig['DiskFreeSpaceThresholdPct'] = $DiskFreeSpaceThresholdPct
448+
$updated = $true
449+
}
436450

437451
# Ausgabe-Sprache
438452
if ($PSBoundParameters.ContainsKey('Language'))

Public/Test-sqmSSISPackageCompatibility.ps1

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -118,8 +118,9 @@ function Test-sqmSSISPackageCompatibility
118118
# Set default OutputPath
119119
if (-not $OutputPath)
120120
{
121-
$OutputPath = Get-sqmConfig -Key 'OutputPath'
122-
if (-not $OutputPath) { $OutputPath = "$env:ProgramData\sqmSQLTool\SSISReports" }
121+
$configOutput = Get-sqmConfig -Key 'OutputPath'
122+
$OutputPath = if ($configOutput) { Join-Path $configOutput 'SSISReports' }
123+
else { Join-Path $env:ProgramData 'sqmSQLTool\SSISReports' }
123124
}
124125

125126
# Version mapping: SQL Server version -> version major

sqmSQLTool.psm1

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -122,6 +122,7 @@ if ($script:sqmIsFitsEnvironment)
122122
$script:sqmModuleConfig['CheckCostThresholdMin'] = 50
123123
$script:sqmModuleConfig['CheckTempDbMaxFiles'] = 8
124124
$script:sqmModuleConfig['CheckDiskBlockSize'] = 65536
125+
$script:sqmModuleConfig['DiskFreeSpaceThresholdPct'] = 10
125126
}
126127

127128
# =============================================================================

0 commit comments

Comments
 (0)