import depuis ancien GitHub

This commit is contained in:
David Wuibaille
2025-10-31 08:38:13 +01:00
parent 6f3aeedc93
commit 6a2f2de58e
745 changed files with 178444 additions and 0 deletions

View File

@@ -0,0 +1,396 @@
Add-Type -AssemblyName System.Windows.Forms
Add-Type -AssemblyName System.Drawing
[System.Windows.Forms.Application]::EnableVisualStyles()
# ==== Config SQL IVANTI ====
$script:IvantiSqlInstance = "serveurIVANTI.domain.lan"
$script:IvantiSqlDatabase = "LDMS123"
# -----------------------------
# Form setup (compact & pro)
# -----------------------------
$form = New-Object System.Windows.Forms.Form
$form.Text = 'Ops Maintenance Console'
$form.Size = New-Object System.Drawing.Size(465,580)
$form.StartPosition= 'CenterScreen'
$form.FormBorderStyle = 'FixedDialog'
$form.MaximizeBox = $false
$form.MinimizeBox = $false
$form.Font = New-Object System.Drawing.Font('Segoe UI', 9)
# Status strip (status text + progress)
$statusStrip = New-Object System.Windows.Forms.StatusStrip
$statusLabel = New-Object System.Windows.Forms.ToolStripStatusLabel
$prog = New-Object System.Windows.Forms.ToolStripProgressBar
$statusLabel.Spring = $true
$prog.Minimum = 0; $prog.Maximum = 1; $prog.Step = 1; $prog.Value = 0
[void]$statusStrip.Items.Add($statusLabel)
[void]$statusStrip.Items.Add($prog)
$form.Controls.Add($statusStrip)
function Set-Status([string]$text){ $statusLabel.Text = $text }
# -----------------------------
# GroupBox: Task
# -----------------------------
$gbTask = New-Object System.Windows.Forms.GroupBox
$gbTask.Text = 'Task'
$gbTask.Location = New-Object System.Drawing.Point(10,8)
$gbTask.Size = New-Object System.Drawing.Size(445,80)
$form.Controls.Add($gbTask)
$lblSelect = New-Object System.Windows.Forms.Label
$lblSelect.Text = 'Select:'
$lblSelect.Location = New-Object System.Drawing.Point(12,30)
$lblSelect.AutoSize = $true
$gbTask.Controls.Add($lblSelect)
$comboBox = New-Object System.Windows.Forms.ComboBox
$comboBox.Location = New-Object System.Drawing.Point(65,27)
$comboBox.Size = New-Object System.Drawing.Size(230,24)
$comboBox.DropDownStyle = 'DropDownList'
$comboBox.Items.Add('IVANTI Core') | Out-Null
$comboBox.Items.Add('IVANTI Console') | Out-Null
$comboBox.Items.Add('WSUS') | Out-Null
$gbTask.Controls.Add($comboBox)
$btnRun = New-Object System.Windows.Forms.Button
$btnRun.Text = 'Run'
$btnRun.Location = New-Object System.Drawing.Point(310,26)
$btnRun.Size = New-Object System.Drawing.Size(110,26)
$gbTask.Controls.Add($btnRun)
$form.AcceptButton = $btnRun
# -----------------------------
# GroupBox: Credentials
# -----------------------------
$gbCreds = New-Object System.Windows.Forms.GroupBox
$gbCreds.Text = 'Credentials (IVANTI Core)'
$gbCreds.Location = New-Object System.Drawing.Point(10,95)
$gbCreds.Size = New-Object System.Drawing.Size(445,90)
$form.Controls.Add($gbCreds)
$labelUser = New-Object System.Windows.Forms.Label
$labelUser.Text = 'Username:'
$labelUser.Location = New-Object System.Drawing.Point(12,27)
$labelUser.AutoSize = $true
$gbCreds.Controls.Add($labelUser)
$textBoxNom = New-Object System.Windows.Forms.TextBox
$textBoxNom.Location = New-Object System.Drawing.Point(90,24)
$textBoxNom.Size = New-Object System.Drawing.Size(150,24)
$textBoxNom.Enabled = $false
$gbCreds.Controls.Add($textBoxNom)
$labelPwd = New-Object System.Windows.Forms.Label
$labelPwd.Text = 'Password:'
$labelPwd.Location = New-Object System.Drawing.Point(12,57)
$labelPwd.AutoSize = $true
$gbCreds.Controls.Add($labelPwd)
$textBoxPassword = New-Object System.Windows.Forms.TextBox
$textBoxPassword.Location = New-Object System.Drawing.Point(90,54)
$textBoxPassword.Size = New-Object System.Drawing.Size(150,24)
$textBoxPassword.UseSystemPasswordChar = $true
$textBoxPassword.Enabled = $false
$gbCreds.Controls.Add($textBoxPassword)
# -----------------------------
# GroupBox: Output
# -----------------------------
$gbOut = New-Object System.Windows.Forms.GroupBox
$gbOut.Text = 'Output'
$gbOut.Location = New-Object System.Drawing.Point(10,190)
$gbOut.Size = New-Object System.Drawing.Size(445,330)
$form.Controls.Add($gbOut)
$outputBox = New-Object System.Windows.Forms.RichTextBox
$outputBox.Location = New-Object System.Drawing.Point(12,22)
$outputBox.Size = New-Object System.Drawing.Size(420,270)
$outputBox.Font = New-Object System.Drawing.Font('Consolas', 9)
$outputBox.ReadOnly = $true
$outputBox.WordWrap = $false
$gbOut.Controls.Add($outputBox)
$btnClear = New-Object System.Windows.Forms.Button
$btnClear.Text= 'Clear'
$btnClear.Location = New-Object System.Drawing.Point(322,295)
$btnClear.Size = New-Object System.Drawing.Size(110,26)
$gbOut.Controls.Add($btnClear)
# Helper: unified output
function Append-Output([string]$text){
foreach($line in ($text -split "(`r`n|`n|`r)")){
if ([string]::IsNullOrWhiteSpace($line)) { continue }
$color = [System.Drawing.Color]::Black
if ($line -match '\bOK\b') { $color = [System.Drawing.Color]::ForestGreen }
elseif ($line -match '\bKO\b') { $color = [System.Drawing.Color]::Crimson }
$outputBox.SelectionStart = $outputBox.TextLength
$outputBox.SelectionLength = 0
$outputBox.SelectionColor = $color
$outputBox.AppendText($line + [Environment]::NewLine)
$outputBox.SelectionColor = $outputBox.ForeColor
}
$outputBox.ScrollToCaret()
}
# -----------------------------
# Logging helper
# -----------------------------
function Write-Log {
[CmdletBinding()]
param(
[Parameter(Mandatory=$True)][string]$Message,
[Parameter(Mandatory=$False)]
[string]$Path = $(if ($MyInvocation.MyCommand.Path) {
$MyInvocation.MyCommand.Path -replace '\.ps1$', '.log'
} else { "C:\Windows\Temp\exploitbox.log" })
)
$timestamp = Get-Date -Format "yyyy-MM-dd HH:mm:ss"
"$timestamp : $script:SelectedOption : $Message" | Out-File -FilePath $Path -Append
}
# -----------------------------
# Functions (business)
# -----------------------------
function Start-WSUS-Maintenance {
Write-Host "[STEP] Start-WSUS-Maintenance"
Set-Status "WSUS maintenance..."
$Aff = ""
$FileSQL = Join-Path $PSScriptRoot "WSUSMaintenance.sql"
Write-Log -Message "----- Start-WSUS-Maintenance"
$Instance = "\\.\pipe\MICROSOFT##WID\tsql\query"
$Bdd = "SUSDB"
try {
Import-Module SqlServer -ErrorAction Stop
Invoke-Sqlcmd -ServerInstance $Instance -Database $Bdd -InputFile $FileSQL -ErrorAction Stop -Verbose
$Aff = "Maintenance OK"
Write-Log -Message "WSUS maintenance OK"
Write-Host "[DONE] WSUS maintenance OK"
} catch {
$Aff = "KO : $($_.Exception.Message)"
Write-Log -Message "WSUS maintenance KO ($($_.Exception.Message))"
Write-Host "[FAIL] WSUS maintenance KO $($_.Exception.Message)"
}
return ($Aff + "`r`n")
}
function Start-IVANTI-Maintenance {
Write-Host "[STEP] Start-IVANTI-Maintenance"
Set-Status "IVANTI SQL maintenance..."
$Aff = ""
$FileSQL = Join-Path $PSScriptRoot "SQLMaintenance2022.sql"
Write-Log -Message "----- Start-IVANTI-Maintenance"
$username = $textBoxNom.Text
$password = $textBoxPassword.Text
try {
Import-Module SqlServer -ErrorAction Stop
Invoke-Sqlcmd -ServerInstance $script:IvantiSqlInstance `
-Database $script:IvantiSqlDatabase `
-Username $username `
-Password $password `
-InputFile $FileSQL `
-ErrorAction Stop -Verbose
$Aff = "Maintenance OK"
Write-Log -Message "IVANTI SQL maintenance OK"
Write-Host "[DONE] IVANTI SQL maintenance OK"
} catch {
$Aff = "KO : $($_.Exception.Message)"
Write-Log -Message "IVANTI SQL maintenance KO ($($_.Exception.Message))"
Write-Host "[FAIL] IVANTI SQL maintenance KO $($_.Exception.Message)"
}
return ($Aff + "`r`n")
}
function Get-RebootStatus {
Write-Host "[STEP] Get-RebootStatus"
Set-Status "Checking reboot status..."
$Aff = ""
Write-Log -Message "----- Get-RebootStatus"
$rebootRequired = $false
$rebootPaths = @(
'HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Component Based Servicing\RebootPending',
'HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\WindowsUpdate\Auto Update\RebootRequired'
)
foreach ($p in $rebootPaths) { if (Test-Path $p) { $rebootRequired = $true; break } }
if ($rebootRequired) {
$Aff = "Reboot Needed (KO)"; Write-Log -Message $Aff; Write-Host "[INFO] Reboot Needed"
} else {
$Aff = "No Reboot Needed (OK)"; Write-Log -Message $Aff; Write-Host "[INFO] No Reboot Needed"
}
return ($Aff + "`r`n")
}
function Cleanup-IIS {
Write-Host "[STEP] Cleanup-IIS"
Set-Status "Cleaning IIS logs..."
$Aff = ""; Write-Log -Message "----- Cleanup-IIS"
$LogPath = "C:\inetpub\logs\LogFiles\W3SVC1"
if (-not (Test-Path $LogPath)) {
$Aff = "PurgeIIS : OK (no log folder)`r`n"
Write-Log -Message "PurgeIIS : OK (no log folder)"
Write-Host "[DONE] Cleanup-IIS OK (no folder)"
return $Aff
}
$maxDaystoKeep = -30
$old = Get-ChildItem -Path $LogPath -File -Filter *.log | Where-Object LastWriteTime -lt ((Get-Date).AddDays($maxDaystoKeep))
if ($old.Count -gt 0){ foreach ($i in $old){ Remove-Item $i.FullName -Force -Verbose } }
$old = Get-ChildItem -Path $LogPath -File -Filter *.log | Where-Object LastWriteTime -lt ((Get-Date).AddDays($maxDaystoKeep))
if ($old.Count -gt 0){ $Aff = "PurgeIIS : KO"; Write-Log -Message $Aff; Write-Host "[FAIL] Cleanup-IIS KO" }
else { $Aff = "PurgeIIS : OK"; Write-Log -Message $Aff; Write-Host "[DONE] Cleanup-IIS OK" }
return ($Aff + "`r`n")
}
function Check-ldscan {
Write-Host "[STEP] Check-ldscan"
Set-Status "Checking ldscan folder..."
$Aff = ""; Write-Log -Message "----- Check-ldscan"
$path = "C:\Program Files\LANDesk\ManagementSuite\ldscan"
$count = Get-ChildItem $path -File | Measure-Object | ForEach-Object { $_.Count }
if ($count -gt 200) {
$Aff = "Countldscan : KO"; Write-Log -Message $Aff; Write-Host "[FAIL] ldscan KO ($count files)"
} else {
$count = Get-ChildItem $path -Recurse -File | Measure-Object | ForEach-Object { $_.Count }
if ($count -gt 200) { $Aff = "Countldscan : WARNING"; Write-Log -Message $Aff; Write-Host "[WARN] ldscan WARNING ($count files)" }
else { $Aff = "Countldscan : OK"; Write-Log -Message $Aff; Write-Host "[DONE] ldscan OK ($count files)" }
}
return ($Aff + "`r`n")
}
# PSWindowsUpdate
function Install-WindowsUpdate {
Write-Host "[STEP] Install-WindowsUpdate (PSWindowsUpdate)"
Set-Status "Installing Windows Updates..."
$Aff = ""; Write-Log -Message "----- Install-WindowsUpdate (PSWindowsUpdate)"
try {
if (-not (Get-Module -ListAvailable -Name PSWindowsUpdate)) { throw "Module PSWindowsUpdate not found on this system." }
Import-Module PSWindowsUpdate -ErrorAction Stop
# Remove -WindowsUpdate to honor WSUS policy
$updates = PSWindowsUpdate\Install-WindowsUpdate -WindowsUpdate -AcceptAll -IgnoreReboot -ErrorAction Stop
if ($updates) {
$Aff += ($updates | Select-Object KB, Title, Result | Format-Table -AutoSize | Out-String)
$updates | ForEach-Object { Write-Log -Message ("{0} {1} -> {2}" -f $_.KB, $_.Title, $_.Result) } | Out-Null
Write-Host "[DONE] Windows Update processed (OK)"
} else {
$Aff += "No applicable updates (OK).`r`n"; Write-Log -Message "No applicable updates."; Write-Host "[INFO] No applicable updates"
}
} catch {
$Aff += "PSWindowsUpdate failed (KO): $($_.Exception.Message)`r`n"
Write-Log -Message "PSWindowsUpdate failed (KO): $($_.Exception.Message)"
Write-Host "[FAIL] Windows Update failed (KO): $($_.Exception.Message)"
}
return $Aff
}
function Get-WSUS-PatchInGroups {
Write-Host "[STEP] Get-WSUS-PatchInGroups"
Set-Status "Building WSUS report..."
$Aff = ""; Write-Log -Message "----- Get-WSUS-PatchInGroups"
$MaxDaysReport = 35; $ListeKB=@()
[reflection.assembly]::LoadWithPartialName("Microsoft.UpdateServices.Administration") | Out-Null
$wsusServer = [Microsoft.UpdateServices.Administration.AdminProxy]::GetUpdateServer()
$updates = $wsusServer.GetUpdates()
$targetGroups = $wsusServer.GetComputerTargetGroups()
foreach ($u in $updates){
$approvals = $u.GetUpdateApprovals()
foreach ($ap in $approvals){
foreach ($tg in $targetGroups){
if ($tg.Id -eq $ap.ComputerTargetGroupId) {
$days = (New-TimeSpan -Start $ap.goLiveTime -End (Get-Date)).Days
$title = $u.Title; $group = $tg.Name
if ($days -lt $MaxDaysReport) {
$match = 0
if (($title -match "Windows 10") -and ($title -match "1809") -and ($title -match " x64")) { $match = 1 }
if ($match -eq 1) {
$ListeKB += [PSCustomObject]@{ KBTitre=$title; KBGroup=$group; KBChang=$days }
}
}
}
}
}
}
$ListeKB = $ListeKB | Sort-Object KBTitre, KBChang
$maxTitle=120; $maxGroup=25; $maxDays=5; $prev="####"
foreach ($KB in $ListeKB) {
if ($KB.KBTitre -ne $prev) { $Aff += "`r`n"; $prev = $KB.KBTitre }
$line = "{0,-$maxTitle} | {1,-$maxGroup} | {2,-$maxDays}" -f $KB.KBTitre, $KB.KBGroup, $KB.KBChang
$Aff += "`r`n$line"; Write-Log -Message $line
}
Write-Host "[DONE] WSUS patch listing generated"
return ($Aff + "`r`n")
}
# -----------------------------
# Admin check
# -----------------------------
if (-NOT ([Security.Principal.WindowsPrincipal][Security.Principal.WindowsIdentity]::GetCurrent()
).IsInRole([Security.Principal.WindowsBuiltInRole] "Administrator")) {
Start-Process PowerShell -ArgumentList "-File `"$($MyInvocation.MyCommand.Path)`"" -Verb RunAs
exit
}
# -----------------------------
# UI events
# -----------------------------
$comboBox.Add_SelectedIndexChanged({
$script:SelectedOption = $comboBox.SelectedItem
if ($comboBox.SelectedItem -eq 'IVANTI Core') {
$textBoxNom.Enabled = $true; $textBoxPassword.Enabled = $true; $textBoxNom.Text = "admindb"
$gbCreds.Enabled = $true
} else {
$textBoxNom.Enabled = $false; $textBoxPassword.Enabled = $false; $gbCreds.Enabled = $false
}
})
$btnClear.Add_Click({ $outputBox.Clear(); Set-Status "Output cleared." })
$btnRun.Add_Click({
$selectedOption = $comboBox.SelectedItem
$script:SelectedOption = $selectedOption
if (-not $selectedOption) { [System.Windows.Forms.MessageBox]::Show("Please select a task.", "Info", 'OK', 'Information') | Out-Null; return }
# progress config
switch ($selectedOption) {
'IVANTI Core' { $prog.Maximum = 6 }
'IVANTI Console' { $prog.Maximum = 2 }
'WSUS' { $prog.Maximum = 4 }
}
$prog.Value = 0
if ($selectedOption -eq "IVANTI Core") {
Set-Status "IVANTI Core running..."
Append-Output "----- Check ldscan"; Append-Output (Check-ldscan); $prog.PerformStep()
Append-Output "----- Clean IIS Log"; Append-Output (Cleanup-IIS); $prog.PerformStep()
Append-Output "----- Windows Update"; Append-Output (Install-WindowsUpdate); $prog.PerformStep()
Append-Output "----- SQL maintenance"; Append-Output (Start-IVANTI-Maintenance);$prog.PerformStep()
Append-Output "----- Get Reboot"; Append-Output (Get-RebootStatus); $prog.PerformStep()
Set-Status "IVANTI Core: done."
}
if ($selectedOption -eq "IVANTI Console") {
Set-Status "IVANTI Console running..."
Append-Output "----- Windows Update"; Append-Output (Install-WindowsUpdate); $prog.PerformStep()
Append-Output "----- Get Reboot"; Append-Output (Get-RebootStatus); $prog.PerformStep()
Set-Status "IVANTI Console: done."
}
if ($selectedOption -eq "WSUS") {
Set-Status "WSUS tasks running..."
Append-Output "----- Windows Update"; Append-Output (Install-WindowsUpdate); $prog.PerformStep()
Append-Output "----- Get Reboot"; Append-Output (Get-RebootStatus); $prog.PerformStep()
Append-Output "----- SQL Maintenance"; Append-Output (Start-WSUS-Maintenance); $prog.PerformStep()
Append-Output "----- Deploy"; Append-Output (Get-WSUS-PatchInGroups); $prog.PerformStep()
Set-Status "WSUS: done."
}
})
# -----------------------------
# Run UI
# -----------------------------
$form.ShowDialog() | Out-Null

View File

@@ -0,0 +1,202 @@
-- Delete from patch history only needs to be run once if the proper thresholds have been set up in the product (Security Activity Tool - Gear icon)
DECLARE @DaysToKeepPatchHistory INTEGER;
DECLARE @DaysToKeepAuditing INTEGER;
DECLARE @DaysToKeepSecurityAction INTEGER;
DECLARE @BatchSize INTEGER;
DECLARE @Producthistory INTEGER;
DECLARE @ChangedateHistory INTEGER;
DECLARE @Loopsize INTEGER;
DECLARE @RowThreshold INTEGER;
SET @DaysToKeepPatchHistory = 90; --Change 90 to how many days of patching history you want
SET @DaysToKeepAuditing = 90; --Change 90 to how many days of auditing history you want
SET @DaysToKeepSecurityAction = 90; --Change 90 to how many days of security actions from EPS you want
SET @BatchSize = 100000; -- Change to number of records per delete you can make this larger or smaller depending on how much room you have for the transaction logs.
SET @Producthistory = 180; -- This will clear out older entries from the ProductComputer table which houses MSI entries.
SET @ChangedateHistory = 90; -- Clears out DBO.history these are the history values for an machine. On older databases the number of entries can cause the clean up statement to lock up.
SET @RowThreshold = 500 --- This value handles the threshold for the delete statement, At 500 it will run the loop until the table has less than 500 records.
WHILE EXISTS
(
SELECT *
FROM [dbo].[PatchHistory]
WHERE [ActionDate] < (GETDATE() - @DaysToKeepPatchHistory) HAVING count(*) > @RowThreshold
)
BEGIN
DELETE TOP (@BatchSize)
FROM [dbo].[PatchHistory]
WHERE [ActionDate] < (GETDATE() - @DaysToKeepPatchHistory)
END;
WHILE EXISTS
(
SELECT *
FROM [dbo].[AuditInstance]
WHERE [ModifiedDate] < (GETDATE() - @DaysToKeepAuditing) HAVING count(*) > @RowThreshold
)
BEGIN
DELETE TOP (@BatchSize)
FROM [dbo].[AuditInstance]
WHERE [ModifiedDate] < (GETDATE() - @DaysToKeepAuditing)
END;
WHILE EXISTS
(
SELECT *
FROM [dbo].[History]
WHERE [ChangeDate] < (GETDATE() - @ChangedateHistory) HAVING count(*) > @RowThreshold
)
BEGIN
DELETE TOP (@BatchSize)
FROM [dbo].[history]
WHERE [ChangeDate] < (GETDATE() - @ChangedateHistory)
END;
WHILE EXISTS
(
SELECT *
FROM [dbo].[SecurityAction]
WHERE [ActionDate] < (GETDATE() - @DaysToKeepSecurityAction) HAVING count(*) > @RowThreshold
)
BEGIN
DELETE TOP (@BatchSize)
FROM [dbo].[SecurityAction]
WHERE [ActionDate] < (GETDATE() - @DaysToKeepSecurityAction)
END;
WHILE EXISTS
(
SELECT *
FROM [dbo].[ProductComputer]
WHERE [Entrydate] < (GETDATE() - @Producthistory) HAVING count(*) > @RowThreshold
)
BEGIN
DELETE TOP (@BatchSize)
FROM [dbo].[ProductComputer]
WHERE [Entrydate] < (GETDATE() - @Producthistory);
END;
--Removes FileInfoInstance Entries greater than 180 days. ONLY USE IN EMERGENCY SITUATIONS. Contact Ivanti support before utilizing this line.
-- WHILE EXISTS
-- (
--SELECT *
--FROM [dbo].[FileInfoInstance]
-- WHERE [FileDate] < (GETDATE() - 180) HAVING count(*) > @RowThreshold
--)
--BEGIN
--DELETE TOP (@BatchSize)
--FROM [dbo].[FileInfoInstance]
--WHERE [FileDate] < (GETDATE() - 180); --Removes FileInfoInstance Entries greater than 180 days. ONLY USE IN EMERGENCY SITUATIONS. Contact Ivanti support before utilizing this line.
--END;
-- Drop Temporary Tables Created by DA during Vendor Imports
DECLARE @cmd VARCHAR(4000);
DECLARE [cmds] CURSOR FOR
SELECT 'drop table [' + [TABLE_NAME] + ']'
FROM [INFORMATION_SCHEMA].[TABLES]
WHERE [TABLE_NAME] LIKE 'tmp_%';
OPEN [cmds];
WHILE 1 = 1
BEGIN
FETCH [cmds]
INTO @cmd;
IF @@fetch_status != 0
BREAK;
EXEC (@cmd);
END;
CLOSE [cmds];
DEALLOCATE [cmds];
-- Remove orphaned entries from FileInfo
WHILE EXISTS
(
SELECT *
FROM [FileInfo]
WHERE [FileSize] <> 1
AND [Version] <> 'X'
AND [Discovered] = 1
AND [FileInfo_Idn] IN
(
SELECT [a].[FileInfo_Idn]
FROM [FileInfo] [a]
LEFT OUTER JOIN [FileInfoInstance] [b] ON [a].[FileInfo_Idn] = [b].[FileInfo_Idn]
LEFT OUTER JOIN [ProductFile] [c] ON [a].[FileInfo_Idn] = [c].[FileInfo_Idn]
LEFT OUTER JOIN [FileConnections] [d] ON [a].[FileInfo_Idn] = [d].[FileInfo_Idn]
LEFT OUTER JOIN [TrustedFileInfo] [e] ON [a].[FileInfo_Idn] = [e].[FileInfo_Idn]
LEFT OUTER JOIN [SLM_ProductUsageFile] [f] ON [a].[FileInfo_Idn] = [f].[FileInfo_Idn]
WHERE [b].[FileInfo_Idn] IS NULL
AND [c].[FileInfo_Idn] IS NULL
AND [d].[FileInfo_Idn] IS NULL
AND [e].[FileInfo_Idn] IS NULL
AND [f].[FileInfo_Idn] IS NULL
) HAVING count(*) > @RowThreshold
)
BEGIN
DELETE TOP (@BatchSize)
FROM [FileInfo]
WHERE [FileSize] <> 1
AND [Version] <> 'X'
AND [Discovered] = 1
AND [FileInfo_Idn] IN
(
SELECT [a].[FileInfo_Idn]
FROM [FileInfo] [a]
LEFT OUTER JOIN [FileInfoInstance] [b] ON [a].[FileInfo_Idn] = [b].[FileInfo_Idn]
LEFT OUTER JOIN [ProductFile] [c] ON [a].[FileInfo_Idn] = [c].[FileInfo_Idn]
LEFT OUTER JOIN [FileConnections] [d] ON [a].[FileInfo_Idn] = [d].[FileInfo_Idn]
LEFT OUTER JOIN [TrustedFileInfo] [e] ON [a].[FileInfo_Idn] = [e].[FileInfo_Idn]
LEFT OUTER JOIN [SLM_ProductUsageFile] [f] ON [a].[FileInfo_Idn] = [f].[FileInfo_Idn]
WHERE [b].[FileInfo_Idn] IS NULL
AND [c].[FileInfo_Idn] IS NULL
AND [d].[FileInfo_Idn] IS NULL
AND [e].[FileInfo_Idn] IS NULL
AND [f].[FileInfo_Idn] IS NULL
);
END;
--- Clears Unkown items list
TRUNCATE TABLE [METABLOCKED];
--- Changes null device id's to unassigned
UPDATE [Computer]
SET [DeviceId] = 'Unassigned'
WHERE [DeviceId] IS NULL;
-- Rebuild fragmented indexes
DECLARE @TableName VARCHAR(255);
DECLARE @sql NVARCHAR(500);
DECLARE @fillfactor INT;
SET @fillfactor = 80;
DECLARE [TableCursor] CURSOR FOR
SELECT OBJECT_SCHEMA_NAME([object_id]) + '.' + [name] AS [TableName]
FROM [sys].[tables];
OPEN [TableCursor];
FETCH NEXT FROM [TableCursor]
INTO @TableName;
WHILE @@FETCH_STATUS = 0
BEGIN
SET @sql
= N'ALTER INDEX ALL ON ' + @TableName + N' REBUILD WITH (FILLFACTOR = ' + CONVERT(VARCHAR(3), @fillfactor)
+ N')';
EXEC (@sql);
FETCH NEXT FROM [TableCursor]
INTO @TableName;
END;
CLOSE [TableCursor];
DEALLOCATE [TableCursor];
GO
--Check for consistency errors
DBCC CHECKDB;
--Run checkpoint to allow logs to be freed
CHECKPOINT;

View File

@@ -0,0 +1,118 @@
USE SUSDB;
GO
SET NOCOUNT ON;
-- Rebuild or reorganize indexes based on their fragmentation levels
DECLARE @work_to_do TABLE (
objectid int
, indexid int
, pagedensity float
, fragmentation float
, numrows int
)
DECLARE @objectid int;
DECLARE @indexid int;
DECLARE @schemaname nvarchar(130);
DECLARE @objectname nvarchar(130);
DECLARE @indexname nvarchar(130);
DECLARE @numrows int
DECLARE @density float;
DECLARE @fragmentation float;
DECLARE @command nvarchar(4000);
DECLARE @fillfactorset bit
DECLARE @numpages int
-- Select indexes that need to be defragmented based on the following
-- * Page density is low
-- * External fragmentation is high in relation to index size
PRINT 'Estimating fragmentation: Begin. ' + convert(nvarchar, getdate(), 121)
INSERT @work_to_do
SELECT
f.object_id
, index_id
, avg_page_space_used_in_percent
, avg_fragmentation_in_percent
, record_count
FROM
sys.dm_db_index_physical_stats (DB_ID(), NULL, NULL , NULL, 'SAMPLED') AS f
WHERE
(f.avg_page_space_used_in_percent < 85.0 and f.avg_page_space_used_in_percent/100.0 * page_count < page_count - 1)
or (f.page_count > 50 and f.avg_fragmentation_in_percent > 15.0)
or (f.page_count > 10 and f.avg_fragmentation_in_percent > 80.0)
PRINT 'Number of indexes to rebuild: ' + cast(@@ROWCOUNT as nvarchar(20))
PRINT 'Estimating fragmentation: End. ' + convert(nvarchar, getdate(), 121)
SELECT @numpages = sum(ps.used_page_count)
FROM
@work_to_do AS fi
INNER JOIN sys.indexes AS i ON fi.objectid = i.object_id and fi.indexid = i.index_id
INNER JOIN sys.dm_db_partition_stats AS ps on i.object_id = ps.object_id and i.index_id = ps.index_id
-- Declare the cursor for the list of indexes to be processed.
DECLARE curIndexes CURSOR FOR SELECT * FROM @work_to_do
-- Open the cursor.
OPEN curIndexes
-- Loop through the indexes
WHILE (1=1)
BEGIN
FETCH NEXT FROM curIndexes
INTO @objectid, @indexid, @density, @fragmentation, @numrows;
IF @@FETCH_STATUS < 0 BREAK;
SELECT
@objectname = QUOTENAME(o.name)
, @schemaname = QUOTENAME(s.name)
FROM
sys.objects AS o
INNER JOIN sys.schemas as s ON s.schema_id = o.schema_id
WHERE
o.object_id = @objectid;
SELECT
@indexname = QUOTENAME(name)
, @fillfactorset = CASE fill_factor WHEN 0 THEN 0 ELSE 1 END
FROM
sys.indexes
WHERE
object_id = @objectid AND index_id = @indexid;
IF ((@density BETWEEN 75.0 AND 85.0) AND @fillfactorset = 1) OR (@fragmentation < 30.0)
SET @command = N'ALTER INDEX ' + @indexname + N' ON ' + @schemaname + N'.' + @objectname + N' REORGANIZE';
ELSE IF @numrows >= 5000 AND @fillfactorset = 0
SET @command = N'ALTER INDEX ' + @indexname + N' ON ' + @schemaname + N'.' + @objectname + N' REBUILD WITH (FILLFACTOR = 90)';
ELSE
SET @command = N'ALTER INDEX ' + @indexname + N' ON ' + @schemaname + N'.' + @objectname + N' REBUILD';
PRINT convert(nvarchar, getdate(), 121) + N' Executing: ' + @command;
EXEC (@command);
PRINT convert(nvarchar, getdate(), 121) + N' Done.';
END
-- Close and deallocate the cursor.
CLOSE curIndexes;
DEALLOCATE curIndexes;
IF EXISTS (SELECT * FROM @work_to_do)
BEGIN
PRINT 'Estimated number of pages in fragmented indexes: ' + cast(@numpages as nvarchar(20))
SELECT @numpages = @numpages - sum(ps.used_page_count)
FROM
@work_to_do AS fi
INNER JOIN sys.indexes AS i ON fi.objectid = i.object_id and fi.indexid = i.index_id
INNER JOIN sys.dm_db_partition_stats AS ps on i.object_id = ps.object_id and i.index_id = ps.index_id
PRINT 'Estimated number of pages freed: ' + cast(@numpages as nvarchar(20))
END
GO
--Update all statistics
PRINT 'Updating all statistics.' + convert(nvarchar, getdate(), 121)
EXEC sp_updatestats
PRINT 'Done updating statistics.' + convert(nvarchar, getdate(), 121)
GO

View File

@@ -0,0 +1 @@
powershell -file "C:\Scripts\Exploitation\ExploitBox.ps1"

View File

@@ -0,0 +1,57 @@
# ExploitBox
## PowerShell GUI for Maintenance Tasks (Ivanti / WSUS)
This project provides a PowerShell-based GUI tool to assist with routine maintenance operations, specifically targeting Ivanti and WSUS environments.
---
## 🔧 Configuration
Edit the following variables at the top of the `ExploitBox.ps1` script:
```powershell
# ==== Global Config ====
$script:IvantiSqlInstance = "serveurIVANTI.domain.lan"
$script:IvantiSqlDatabase = "LDMS123"
```
---
## 📦 Installation
Before running the script, install the required PowerShell modules:
```powershell
Install-Module SqlServer -Scope CurrentUser -Force
Install-Module PSWindowsUpdate -Scope CurrentUser -Force -AllowClobber
```
---
## ▶️ Execution
Unblock the script and execute it using PowerShell:
```powershell
Unblock-File .\ExploitBox.ps1
powershell.exe -NoProfile -ExecutionPolicy Bypass -File .\ExploitBox.ps1
```
---
## 💡 Features
- GUI interface for easier operations
- Connects to Ivanti SQL database
- Uses `PSWindowsUpdate` for patch management
- Modular and easily configurable
---
## 📸 Screenshots
![ExploitBox Screenshot](readme.png)
---

Binary file not shown.

After

Width:  |  Height:  |  Size: 17 KiB