Question Doublons générés lors du traitement import AD

  • witness57
  • Auteur du sujet
  • Visiteur
  • Visiteur
il y a 4 ans 11 mois #31074 par witness57
Réponse de witness57 sur le sujet Doublons générés lors du traitement import AD
Merci
sympa

Connexion ou Créer un compte pour participer à la conversation.

Plus d'informations
il y a 4 ans 11 mois - il y a 4 ans 11 mois #31075 par xyz
Un premier jet, autant battre le fer tant qu'il est chaud :
$Pattern='^(?<Nom>.*?)(?<Nombre>\d*)$'
'AccountName255' -match $Pattern

[int]$Indice=$Matches.Nombre

$Delegate={
param( $Match)
$Indice++
return "$($match.Groups['Nom'].Value)$Indice"
}

[Regex]::Replace('AccountName255', $Pattern, $Delegate)
#AccountName256
Reste peut être un pb de portée pour $Indice...

Tutoriels PowerShell
Dernière édition: il y a 4 ans 11 mois par xyz. Raison: correction résultat

Connexion ou Créer un compte pour participer à la conversation.

Plus d'informations
il y a 4 ans 11 mois - il y a 4 ans 11 mois #31078 par xyz
Une ébauche :
#Account.ps1
Param()
#Décompose un nom de compte AD
$Pattern='^(?<Nom>.*?)(?<Nombre>\d*)$'

#Simule le résultat d'une requête AD
Function Get-AccountName{ @('AccountName100','AccountName1','AccountName21')}

Function New-AccountName{
#Récupère un nom de compte normé du pipeline
#renvoi un objet personnalisé, sa propriété 'Nombre' (de type entier) permettra le tri
param(
[Parameter(ValueFromPipeline)]
[string] $AccountName,

[string] $Pattern
)
process {
if ($AccountName -match $Pattern)
{ [PSCustomObject]@{Nom=$Matches.Nom;Nombre=[int]$Matches.Nombre;Origine=$AccountName} }
else
{ throw "Le nom de compte '$AccountName' n'est pas normé." }
}
}
#Récupère le nom de compte ayant le numéro le plus élevé
$LastAccount=Get-AccountName|New-AccountName -Pattern $Pattern|Sort-Object -Property Nombre -Desc|Select-Object -First 1
Write-Debug "LastAccount='$LastAccount'"

$LastAccountName=$LastAccount.Nom
Write-Debug "LastAccountName='$LastAccountName'"

#Initialise la variable, permet de la récupérer en fin de création de compte
[int]$script:Compteur=-1

$Delegate={
param( $Match)
#Write-Debug "Before $script:Compteur"

#La portée script permet d'adresser la variable déclarée dans l'appelant
If ($script:Compteur -eq -1)
{$script:Compteur=1+$Match.Groups['Nombre'].Value}
Else
{ $Script:Compteur++ }
#Write-Debug "After $script:Compteur"
Return "$($Match.Groups['Nom'].Value)$script:Compteur"
}

#Lors du premier appel on doit connaitre le nombre de duplication de compte afin d'initialiser le compteur.
#On passe en premier paramètre de Replace() le nom de compte ayant le nombre le plus élévé.
[Regex]::Replace($LastAccount.Origine, $Pattern, $Delegate)
Write-host "Premier appel Compteur=$script:Compteur" -ForegroundColor Green

#Le nom de compte passé dans les appels suivants peut être sans numéro, car le compteur existe avec la valeur attendue
[Regex]::Replace('AccountName', $Pattern, $Delegate)
Write-host "Second appel Compteur=$script:Compteur" -ForegroundColor Green

[Regex]::Replace('AccountName', $Pattern, $Delegate)
Write-host "Troisième appel Compteur=$script:Compteur" -ForegroundColor Green
]

Par contre si on utilise ce jeu de test :
Function Get-AccountName{ @('Riri100','Riri1','Riri21','Fifi1','Fifi2','Loulou')}
Les noms de compte qui ne sont pas dupliqués ne matche pas la regex et la variable $compteur devrait être une hashtable (cache des occurences dupliquées).
Il peut y avoir d'autres solutions/approches.

Tutoriels PowerShell
Dernière édition: il y a 4 ans 11 mois par xyz. Raison: coquille

Connexion ou Créer un compte pour participer à la conversation.

  • witness57
  • Auteur du sujet
  • Visiteur
  • Visiteur
il y a 4 ans 11 mois #31079 par witness57
Réponse de witness57 sur le sujet Doublons générés lors du traitement import AD
Merci Laurent,
Je vais regarder tout ça.

Connexion ou Créer un compte pour participer à la conversation.

Plus d'informations
il y a 4 ans 11 mois #31081 par xyz
Une version basée sur l'usage d'un cache simple :
Param()
#Décompose un nom de compte AD
$script:Pattern='^(?<Nom>.*?)(?<Nombre>\d*)$'

Function Update-Cache{
    param(
        [Parameter(Mandatory=$True,position=0)]
    [string] $Nom,
        [Parameter(Mandatory=$True,position=1)]
    [int] $Compteur
 )

 if (-not $script:Cache.ContainsKey($Nom))
 {
    Write-Debug "Cache: Ajoute '$Nom' '$Compteur'"
    $Script:Cache.Add($Nom,$Compteur)
 }
 else
 {
    if($Compteur -gt $Script:Cache.$Nom)
    {
       Write-Debug "Cache: MAJ du compteur '$($Script:Cache.$Nom)' --> '$Compteur'"
       $Script:Cache.$Nom=$Compteur
    }
 }
}

$Script:Cache=@{}
#Simule le résultat d'une requête AD
#todo Function Get-AccountName{ @('','1','22','A','a1','Riri100','Riri1','Riri21','Fifi1','Fifi2','Loulou')}
Function Get-AccountName{ @('Riri100','Riri1','Riri21','Fifi1','Fifi2','Loulou')}

#Liste des nouveaux comptes a ajouter
Function Get-NewName{ @('Riri','Fifi','Loulou','Donald')}
Function Split-AccountName{
    #Récupère un nom de compte normé du pipeline
    #renvoi un objet personnalisé, sa propriété 'Nombre' (de type entier) permettra le tri
  param(
       [Parameter(ValueFromPipeline)]
      [string] $AccountName
    )
 process {
   if ($AccountName -match $script:Pattern)
   {
      if ($Matches.Nombre -ne [string]::Empty)
      { [PSCustomObject]@{Nom=$Matches.Nom;Nombre=[int]$Matches.Nombre;Origine=$AccountName} }
      else
      {
         #Le premier nom de compte inexistant dans l'AD n'est pas postfixé par un nombre
        [PSCustomObject]@{Nom=$Matches.Nom;Nombre=0;Origine=$AccountName}
      }
   }
   else
   { Write-Error "Le nom de compte '$AccountName' n'est pas normé." }
 }
}
#Récupère les noms de compte ayant le numéro le plus élevé en renseignant le cache
#todo regrouper par nom : Get-AccountName|Split-AccountName|Group-Object -Property Nom -AsHashTable -AsString
Get-AccountName|
 Split-AccountName|
 Foreach-Object {
    Write-host "Traite '$_'" -ForegroundColor Green
    Update-Cache $_.Nom $_.Nombre
 }
$Cache # todo remove line

#voir : https://docs.microsoft.com/fr-fr/dotnet/api/system.text.regularexpressions.matchevaluator?view=netframework-4.5
$Delegate={
 param( $Match)
    $Nom=$Match.Groups['Nom'].Value
    [int]$Compteur=$Match.Groups['Nombre'].Value

    Update-Cache $Nom $Compteur
    $Compteur=$script:Cache.$Nom
    Write-Debug "Delegate: Before $Compteur"
    $script:Cache.$Nom=++$Compteur
    Write-Debug "Delegate: After $Compteur"
    Return "$($Match.Groups['Nom'].Value)$Compteur"
}

Get-NewName|
 ForEach-Object {
    Write-host "Recherche de doublon pour le compte '$_'" -ForegroundColor White
    $NewAccountName=[Regex]::Replace($_, $script:Pattern, $Delegate)
    Write-host "Nouveau nom dupliqué '$NewAccountName'" -ForegroundColor Green
}
$Cache
Reste le cas d'un nouveau nom de compte inexistant en base, ici le code l'incrémente.
Je te laisse créer des jeux de test et gérer les possibles cas d'erreur.
Comme je ne connais pas ton infra ni ta norme de nommage AD il y a surement des choses à adapter.
Et si qq à une autre solution on la lira avec plaisir :-)

Tutoriels PowerShell

Connexion ou Créer un compte pour participer à la conversation.

  • witness57
  • Auteur du sujet
  • Visiteur
  • Visiteur
il y a 4 ans 11 mois #31090 par witness57
Réponse de witness57 sur le sujet Doublons générés lors du traitement import AD
Merci, mais je ne m'attendais pas à un bloc de code aussi important 

Connexion ou Créer un compte pour participer à la conversation.

Temps de génération de la page : 0.050 secondes
Propulsé par Kunena