1 votes

Regex dans powershell

J'essaie d'utiliser powershell pour faire correspondre le nom d'utilisateur et le statut de l'utilisateur dans l'exemple ci-dessous :

Internal user ID:        1     Login name: ADMINISTRATOR    
Last login:
Last update user ID:     2     Date and time created: Tue Oct-25-2016 10:59:31
User status:             ENABLED       Reason for last status change:          0

Avec mon constructeur de regex que j'ai fait fonctionner :

Login name:\s+(\w+)\n.*\n.*\nUser status:\s+(ENABLED|DISABLED)

mais lorsque je l'utilise dans select-string, il ne renvoie rien. Y a-t-il quelque chose d'évident que je fais mal ?

powershell :

$as = select-string "c:\users\ssfors\desktop\audit\user.rep" -pattern "Login name:\s+(\w+)\n.*\n.*\nUser status:\s+(ENABLED|DISABLED)"
foreach ($a in $as) {
echo $a.matches.groups[1].Value
}

0voto

Seth Points 8547

Si vous regardez la question suivante, vous verrez une façon d'obtenir PowerShell/ Select-String pour utiliser le mode ligne unique : Regex multiligne pour correspondre au bloc de configuration

Le problème auquel vous êtes confronté est que, par défaut, une RegEx est généralement appliquée par ligne d'entrée. Ainsi, votre RegEx ne fonctionne que sur la première ligne qui contient Internal user ID et Login name .

Ce que vous devez faire, c'est supprimer les sauts de ligne de votre entrée ou dire à Select-String pour utiliser le mode ligne unique. Dans les deux cas, vous devriez ajuster votre RegEx pour ne pas utiliser \n car elle ne sera pas nécessaire. Vous pourriez le faire comme ceci :

Login name:\s+(\w+)\s+.*?User status:\s+(ENABLED|DISABLED)

Après cela, vous devez soit ajuster votre entrée en exécutant par exemple -replace '`n' (remarquez également que vous devriez utiliser `n dans PowerShell) ou vous pouvez utiliser un modificateur sur l'entrée comme indiqué dans la question ci-dessus. Dans ce cas, votre RegEx serait modifié en :

(?s)Login name:\s+(\w+)\s+.*?User status:\s+(ENABLED|DISABLED)

Même après tout ça, vous n'allez pas en avoir fini, Select-String retourne en fait la ligne par ligne d'une entrée si vous fournissez -Path Il est donc préférable de lire tout le fichier en une seule fois.

Un exemple pourrait être le suivant :

$fileContent = (Get-Content c:\users\ssfors\desktop\audit\user.rep) -join ''
$results = $fileContent | Select-String -pattern "Login name:\s+(\w+)\s+.*?User status:\s+(ENABLED|DISABLED)" -AllMatches
foreach($match in $results.Matches){
    foreach($group in $match.Groups){
        echo $group.Value
    }
}

if($results.Matches.Count -eq 1 -and $results.Matches[0].Groups.Count -eq 3){
    echo "User Name:", $results.Matches[0].Groups[1].Value;
    echo "Status:",  $results.Matches[0].Groups[2].Value;
}

Notez que l'exemple n'utilise pas le modificateur de ligne unique car il n'est pas nécessaire. Il lit le fichier et concatène les lignes en n'utilisant rien comme délimiteur.

SistemesEz.com

SystemesEZ est une communauté de sysadmins où vous pouvez résoudre vos problèmes et vos doutes. Vous pouvez consulter les questions des autres sysadmins, poser vos propres questions ou résoudre celles des autres.

Powered by:

X