public/Watch-LimitFileSize.ps1

function Watch-LimitFileSize {
    <#
    .SYNOPSIS
        Creates or updates a scheduled task to monitor the size of one or more files.

    .DESCRIPTION
        This script creates a Windows scheduled task named "WatchLimitFileSize" that runs the Set-LimitFileSize cmdlet on one or more specified paths.

    .PARAMETER Path
        Array of strings containing one or more file or folder paths to monitor. Examples: 'C:\logs\app.log', 'D:\data\config.txt'.

    .PARAMETER MaxSize
        The maximum size the file is allowed to reach before triggering a trimming operation.

        The value must be a number followed optionally by a unit :
            - Use "Ko" for kilooctets (e.g., "100000Ko")
            - Use "Mo" for megaoctets (e.g., "150Mo")
            - If no unit is specified, kilooctets are assumed by default (e.g., "200" means "200Ko").

        Default: "256Ko"

    .PARAMETER Time
        Specifies the time of day when the scheduled task should run. Format must be 'HH:mm' in 24-hour notation (e.g., '07:00', '23:30'). Default: '07:00'.

    .PARAMETER VerboseLevel
        Controls the script's verbosity level :
            - "Disabled": no console output.
            - "Debug": detailed output.

    .EXAMPLE
        Watch-LimitFileSize -Path "C:\test\lorem1.txt" -MaxSize 3Ko -VerboseLevel Debug

        Creates the scheduled task to monitor a single file.

    .EXAMPLE
        Watch-LimitFileSize -Path "C:\test\lorem1.txt", "C:\test\lorem2.txt" -Time 11:11 -VerboseLevel Debug

        Creates the scheduled task to monitor multiple files.

    .NOTES
        Version : 1.0.1
        Author : Frederic PETIT
        Created : 2025-05-22
        Revised : 2025-06-03

        Compatibility: PowerShell 5+
    #>


    [CmdletBinding(SupportsShouldProcess = $true)]
    Param (
        [Parameter(Mandatory=$true)][string[]]$Path,
        [Parameter(Mandatory=$false)][string]$MaxSize = "256Ko",
        [Parameter(Mandatory=$false)][string]$Time = "07:00",
        [Parameter(Mandatory=$false)][ValidateSet("Disabled", "Debug")][string]$VerboseLevel = "Disabled"
    )

    # Convertir les chemins bruts en chemins absolus, pour éviter les erreurs de contexte.
    try {
        $ResolvedPaths = Resolve-Path -LiteralPath $Path | Select-Object -ExpandProperty Path;
    } catch {
        throw "Error resolving paths : $_";
    }

    # Préparer chaque chemin entre quotes pour usage inline dans un tableau PowerShell.
    $joined = ($ResolvedPaths | ForEach-Object { "'$_'" }) -join ',';

    # Créer une commande complète qui appelle Set-LimitFileSize avec les bons chemins.
    $CommandLine = "Import-Module LimitFileSize; Set-LimitFileSize -Path @($joined) -MaxSize $MaxSize";

    # DateTime complet et conforme XML.
    $DateTime = if ($Time) { [DateTime]::ParseExact($Time, 'HH:mm', $null) } else { [DateTime]::Today.AddHours(7) };
    $StartBoundary = $DateTime.ToString("yyyy-MM-ddTHH:mm:ss");

    # Définition de la tâche.
    $TaskName = "WatchLimitFileSize";
    $TaskXml = @"
<?xml version="1.0" encoding="UTF-16"?>
<Task version="1.4" xmlns="http://schemas.microsoft.com/windows/2004/02/mit/task">
    <RegistrationInfo>
        <Date>$(Get-Date -Format 'yyyy-MM-ddTHH:mm:ss')</Date>
        <Author>$env:USERNAME</Author>
        <URI>\$TaskName</URI>
    </RegistrationInfo>
    <Triggers>
        <CalendarTrigger>
            <StartBoundary>$StartBoundary</StartBoundary>
            <ScheduleByDay>
                <DaysInterval>1</DaysInterval>
            </ScheduleByDay>
        </CalendarTrigger>
    </Triggers>
    <Principals>
        <Principal id="Author">
            <UserId>S-1-5-18</UserId>
            <RunLevel>HighestAvailable</RunLevel>
        </Principal>
    </Principals>
    <Settings>
        <MultipleInstancesPolicy>Queue</MultipleInstancesPolicy>
        <DisallowStartIfOnBatteries>false</DisallowStartIfOnBatteries>
        <StopIfGoingOnBatteries>false</StopIfGoingOnBatteries>
        <AllowHardTerminate>true</AllowHardTerminate>
        <StartWhenAvailable>true</StartWhenAvailable>
        <RunOnlyIfNetworkAvailable>false</RunOnlyIfNetworkAvailable>
        <IdleSettings>
            <StopOnIdleEnd>true</StopOnIdleEnd>
            <RestartOnIdle>false</RestartOnIdle>
        </IdleSettings>
        <AllowStartOnDemand>true</AllowStartOnDemand>
        <Enabled>true</Enabled>
        <Hidden>false</Hidden>
        <RunOnlyIfIdle>false</RunOnlyIfIdle>
        <DisallowStartOnRemoteAppSession>false</DisallowStartOnRemoteAppSession>
        <UseUnifiedSchedulingEngine>true</UseUnifiedSchedulingEngine>
        <WakeToRun>true</WakeToRun>
        <ExecutionTimeLimit>PT5M</ExecutionTimeLimit>
        <Priority>7</Priority>
    </Settings>
    <Actions Context="Author">
        <Exec>
            <Command>powershell.exe</Command>
            <Arguments>-ExecutionPolicy Bypass -Command "$CommandLine"</Arguments>
        </Exec>
    </Actions>
</Task>
"@


    # Vérifier si la tâche existait déjà, et la supprimer si oui
    if (Get-ScheduledTask -TaskName $TaskName -ErrorAction SilentlyContinue) {
        Unregister-ScheduledTask -TaskName $TaskName -Confirm:$false;
        if ($VerboseLevel -eq "Debug") {
            Write-Host "Task '$TaskName' already exists and will be replaced." -ForegroundColor Yellow;
        }
    }

    # Enregistrer (avec écrasement) la tâche planifiée.
    try {
        $null = Register-ScheduledTask -TaskName $TaskName -Xml $TaskXml -Force;
    } catch {
        throw "Error registering task : $_";
    }

    # Vérifier que la tâche a bien été enregistrée puis la démarrer immédiatement.
    try {
        if (Get-ScheduledTask -TaskName $TaskName -ErrorAction SilentlyContinue) {
            if ($VerboseLevel -eq "Debug") {
                Write-Host "Task '$TaskName' OK" -ForegroundColor Green;
            }
            Start-ScheduledTask -TaskName $TaskName;
            if ($VerboseLevel -eq "Debug") {
                Write-Host "Task '$TaskName' EXEC." -ForegroundColor Green;
            }
            #Export-ScheduledTask -TaskName 'WatchLimitFileSize' | Out-File "$env:TEMP\Task.xml";
        }
    } catch {
        if ($VerboseLevel -eq "Debug") {
            Write-Warning "Task '$TaskName' error : $_";
        }
    }
}