How to create a regex allowing me to cath a value following a specific sentence

Hello everyone,

I am trying to create a Powershell script allowing me to automate Bitlocker disk encryption on C: drive, the problem is i want to create some custom notifications to let the user be aware of the encryption percentage at 25, 50 and 75 percent. Notifications are working fine, same for everything except the percentage detection and i really have no idea why because the lines are cathed correctly. I think the problem is in my “regex”. Here is my script :

function Send-Notification {
    Param(
        [Parameter(Mandatory)]
        [string]$NotificationTitle,
        [Parameter(Mandatory)]
        [string]$NotificationMessage,
        [string]$NotificationMessage2 = '',  # Deuxième message optionnel
        [string]$AppID = '{1AC14E77-02E7-4E5D-B744-2EB1AE5198B7}\WindowsPowerShell\v1.0\powershell.exe',
        [string]$NotificationImage = '',  # Si vous souhaitez définir une image par défaut, vous pouvez la spécifier ici
        [ValidateSet('alarm', 'reminder', 'incomingcall', 'default')]
        [string]$NotificationType = 'default'  # Type de notification par défaut
    )

    $null = [Windows.UI.Notifications.ToastNotificationManager, Windows.UI.Notifications, ContentType = WindowsRuntime]
    $null = [Windows.Data.Xml.Dom.XmlDocument, Windows.Data.Xml.Dom.XmlDocument, ContentType = WindowsRuntime]
    $NotificationTemplate = [xml]@"
<toast scenario="$NotificationType">
    <visual>
        <binding template="ToastGeneric">
            <text>$NotificationTitle</text>
            <text>$NotificationMessage</text>
            <text>$NotificationMessage2</text>
            <image placement="appLogoOverride" src="$NotificationImage"/>
        </binding>
    </visual>
</toast>
"@
    $NotificationXML = [Windows.Data.XML.DOM.XMLDocument]::New()
    $NotificationXML.LoadXml($NotificationTemplate.OuterXml)
    $Toast = [Windows.UI.Notifications.ToastNotification]::new($NotificationXML)
    $ToastNotifier = [Windows.UI.Notifications.ToastNotificationManager]::CreateToastNotifier($AppID)
    $ToastNotifier.Show($Toast)
}

# Function to get the encryption percentage
function Get-EncryptionPercentage {
    $statusOutput = manage-bde -status C: | Out-String
    Write-Output "Sortie complète de manage-bde :"
    Write-Output $statusOutput

    # Split the output into lines
    $statusLines = $statusOutput -split "`r?`n"

    # Initialize the percentage variable
    $percentage = 0
    $found = $false

    # Loop through each line to find the percentage
    foreach ($line in $statusLines) {
        # Nettoyer la ligne de tout espace ou caractère non imprimable
        $cleanLine = $line.Trim()
        Write-Output "Processing line: $cleanLine"

        # Rechercher la ligne contenant "Pourcentage chiffré"
        if ($cleanLine -like '*Pourcentage chiffré*') {
            Write-Output "Ligne trouvée : $cleanLine"
            # Utilisation d'une regex pour capturer le pourcentage
            $percentageMatch = [regex]::Match($cleanLine, 'Pourcentage chiffré\s*:\s*(\d+[.,]?\d*)')
            if ($percentageMatch.Success) {
                $percentage = $percentageMatch.Groups[1].Value -replace ',', '.'
                $percentage = [int][math]::Floor([double]$percentage)
                $found = $true
                break
            }
        }
    }

    if ($found) {
        # Vérification que le pourcentage est entre 0 et 100
        if ($percentage -ge 0 -and $percentage -le 100) {
            Write-Output "Pourcentage extrait : $percentage%"
            return $percentage
        } else {
            Write-Error "Erreur: Pourcentage extrait ($percentage%) est hors de l'intervalle valide (0-100)."
            return 0
        }
    } else {
        Write-Error "Erreur: Ligne de pourcentage non trouvée."
        return 0
    }
}

# Testez la fonction indépendamment pour voir si elle fonctionne correctement
$percentageComplete = Get-EncryptionPercentage
Write-Output "Pourcentage d'encryption actuel: $percentageComplete%"




manage-bde -on C: -skiphardwaretest

# Notify encryption's beginning
Send-Notification -NotificationTitle "Chiffrement du disque" -NotificationMessage "Début du chiffrement du disque. Des pertes de performances sont à prévoir." -NotificationMessage2 "Temps restant estimé : 20 minutes."

# Loop to monitor encryption progress
$percentageComplete = Get-EncryptionPercentage
while ($percentageComplete -lt 100) {
    # Print the current encryption percentage
    Write-Output "Pourcentage d'encryption actuel: $percentageComplete%"

    if ($percentageComplete -ge 25 -and $percentageComplete -lt 50) {
        Send-Notification -NotificationTitle "Chiffrement du disque" -NotificationMessage "Chiffrement du disque : 25%." -NotificationMessage2 "Temps restant estimé : 15 minutes."
    } elseif ($percentageComplete -ge 50 -and $percentageComplete -lt 75) {
        Send-Notification -NotificationTitle "Chiffrement du disque" -NotificationMessage "Chiffrement du disque : 50%." -NotificationMessage2 "Temps restant estimé : 10 minutes."
    } elseif ($percentageComplete -ge 75 -and $percentageComplete -lt 100) {
        Send-Notification -NotificationTitle "Chiffrement du disque" -NotificationMessage "Chiffrement du disque : 75%." -NotificationMessage2 "Temps restant estimé : 5 minutes."
    }

    # Wait for a short period before checking again
    Start-Sleep -Seconds 5

    # Update the percentage
    $percentageComplete = Get-EncryptionPercentage
}

# Print final percentage (should be 100)
Write-Output "Pourcentage d'encryption final: $percentageComplete%"

# Once encryption is complete
Send-Notification -NotificationTitle "Chiffrement terminé" -NotificationMessage "Chiffrement terminé." -NotificationMessage2 "Vous pouvez à nouveau utiliser normalement le PC."

# Deleting the task after disk encryption
Unregister-ScheduledTask -TaskName "BitlockerActivation" -Confirm:$false

And here is my output (errors with Bitlocker encryptions are logic knowing my disk is already encrypted) :

PS C:\Windows\system32> powershell.exe D:\Notif.ps1
Get-EncryptionPercentage : Erreur: Ligne de pourcentage non trouvée.
Au caractère D:\Notif.ps1:83 : 23
+ $percentageComplete = Get-EncryptionPercentage
+                       ~~~~~~~~~~~~~~~~~~~~~~~~
    + CategoryInfo          : NotSpecified: (:) [Write-Error], WriteErrorException
    + FullyQualifiedErrorId : Microsoft.PowerShell.Commands.WriteErrorException,Get-EncryptionPercentage

Pourcentage d'encryption actuel: Sortie complète de manage-bde : Chiffrement de lecteur BitLocker : outil de configuration version 10.0.19041
Copyright (C) 2013 Microsoft Corporation. Tous droits réservés.

Volume C: [Windows]
[Volume du système d?exploitation]

    Taille :                     475,69 Go
    Version de BitLocker :       2.0
    État de la conversion :      Chiffrement en cours
    Pourcentage chiffré :        84,7%
    Méthode de chiffrement :     XTS-AES 128
    État de la protection :      Protection désactivée
    État du verrouillage :       Déverrouillé
    Champ d?identification :     Inconnu
    Protecteurs de clés :
        TPM

 Processing line: Chiffrement de lecteur BitLocker : outil de configuration version 10.0.19041 Processing line: Copyright (C) 2013 Microsoft Corporation. Tous droits réservés. Processing line:  Processing line: Volume C: [Windows] Processing line: [Volume du système d?exploitation] Processing line:  Processing line:     Taille :                     475,69 Go Processing line:     Version de BitLocker :       2.0 Processing line:     État de la conversion :      Chiffrement en cours Processing line:     Pourcentage chiffré :        84,7% Processing line:     Méthode de chiffrement :     XTS-AES 128 Processing line:     État de la protection :      Protection désactivée Processing line:     État du verrouillage :       Déverrouillé Processing line:     Champ d?identification :     Inconnu Processing line:     Protecteurs de clés : Processing line:         TPM Processing line:  Processing line:  0%
Chiffrement de lecteur BitLocker : outil de configuration version 10.0.19041
Copyright (C) 2013 Microsoft Corporation. Tous droits réservés.

Volume C: [Windows]
[Volume du système d’exploitation]
REMARQUE : cette commande n’a pas créé de nouveaux protecteurs de clés. Tapez
« manage-bde -protectors -add -? » pour plus d’informations sur l’ajout de
protecteurs de clés supplémentaires.
REMARQUE : le chiffrement est déjà en cours.
Tapez « manage-bde -status -? » pour plus d’informations sur l’état du
chiffrement.

La protection BitLocker sera active une fois le chiffrement terminé.
Get-EncryptionPercentage : Erreur: Ligne de pourcentage non trouvée.
Au caractère D:\Notif.ps1:94 : 23
+ $percentageComplete = Get-EncryptionPercentage
+                       ~~~~~~~~~~~~~~~~~~~~~~~~
    + CategoryInfo          : NotSpecified: (:) [Write-Error], WriteErrorException
    + FullyQualifiedErrorId : Microsoft.PowerShell.Commands.WriteErrorException,Get-EncryptionPercentage

Pourcentage d'encryption final: Sortie complète de manage-bde : Chiffrement de lecteur BitLocker : outil de configuration version 10.0.19041
Copyright (C) 2013 Microsoft Corporation. Tous droits réservés.

Volume C: [Windows]
[Volume du système d?exploitation]

    Taille :                     475,69 Go
    Version de BitLocker :       2.0
    État de la conversion :      Chiffrement en cours
    Pourcentage chiffré :        84,8%
    Méthode de chiffrement :     XTS-AES 128
    État de la protection :      Protection désactivée
    État du verrouillage :       Déverrouillé
    Champ d?identification :     Inconnu
    Protecteurs de clés :
        TPM

 Processing line: Chiffrement de lecteur BitLocker : outil de configuration version 10.0.19041 Processing line: Copyright (C) 2013 Microsoft Corporation. Tous droits réservés. Processing line:  Processing line: Volume C: [Windows] Processing line: [Volume du système d?exploitation] Processing line:  Processing line:     Taille :                     475,69 Go Processing line:     Version de BitLocker :       2.0 Processing line:     État de la conversion :      Chiffrement en cours Processing line:     Pourcentage chiffré :        84,8% Processing line:     Méthode de chiffrement :     XTS-AES 128 Processing line:     État de la protection :      Protection désactivée Processing line:     État du verrouillage :       Déverrouillé Processing line:     Champ d?identification :     Inconnu Processing line:     Protecteurs de clés : Processing line:         TPM Processing line:  Processing line:  0%
Unregister-ScheduledTask : Aucun objet MSFT_ScheduledTask avec la propriété « TaskName » égale à « BitlockerActivation » n’a été trouvé. Vérifiez la valeur de la propriété et réessayez.
Au caractère D:\Notif.ps1:121 : 1
+ Unregister-ScheduledTask -TaskName "BitlockerActivation" -Confirm:$fa ...
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    + CategoryInfo          : ObjectNotFound: (BitlockerActivation:String) [Unregister-ScheduledTask], CimJobException
    + FullyQualifiedErrorId : CmdletizationQuery_NotFound_TaskName,Unregister-ScheduledTask

Thank you very much for your help and your time

FiirOz,
Welcome to the forum. :wave:t3:

That’s a lot of code. And the comments in french do not help very much. :man_shrugging:t3: It seems like you already know what your issue is. How about creating a minimal reproducable example where you omit all unnecessary code not needed to understand your issue? What’s the input string? What pattern are you looking for? And what is not working as expected?

I’m on mobile so forgive me for not going through all that code, but whenever I’m working with Regex I like to use Regex101 to test different lines of text against my proposed pattern

Just use Get-BitlockerVolume it returns the percentage encrypted. No need for regex

Hey !

I figure out my issue, the first problem was my regex that was not correct, I used regex101 and find out the good one : (?<=Pourcentage chiffré[ \t]*:[ \t]*)(\d+(?:[.,]?\d+)?)
Then i had another problem, I only received 0% everytime, but i figured out i was using UTF8 as file encoding bu Windows Powershell makes bad assumptions so I had to use UTF8 with BOM.

Thank you to everyone for your help !

Just want to make sure you saw neemo’s response here… I didn’t look at your code but Get-BitlockerVolume is the play, don’t reinvent the wheel when there’s already ways to pull the data. EncryptionPercentage is a property on the returned object. It greatly simplifies your code and uses already built-in process for this.

Oh thanks i didn’t see neemo’s response, I am going to look into that !