Résolu Optimisation du temps de traitement

Plus d'informations
il y a 2 ans 8 mois - il y a 2 ans 8 mois #31208 par Bruce
Bonjour,

Mon script sert à avoir une liste unique des chemins AD (distinguishedname) d'un ordinateur d'un AD mais sans le nom du PC.
exemple : 
"CN=USER_X_PO,CN=Computers,DC=societe,DC=local" -> "CN=Computers,DC=societe,DC=local"
"CN=USER_Y_PO,OU=PC_FILIALE1,OU=FILIALE1,DC=societe,DC=local" -> "OU=PC_FILIALE1,OU=FILIALE1,DC=societe,DC=local"

Ceci dans le but de déplacer certains PC dans les mauvaises OU, mais sur cette liste je dois éliminer les doublons.
Mon script fonctionne mais le temps de traitement est trop long je trouve, je pense qu'il doit y avoir un moyen de l'optimiser, c'est surtout la partie de recherche des doublons qui prends du temps, 1minute et 44sec pour 714 PC dans 27 emplacements.... merci.
Voici mon code:
cls
$starttime=Get-Date
$Alldn = Get-ADComputer -Filter * | Select-Object -Property DistinguishedName |sort -Property DistinguishedName
$totDN = $Alldn.Count
$dnList = @{}
$id = 0
Write-Host "Nombre de PC: $totDN"
foreach ($item in $Alldn)
{
    # Extraction des OU ou CN de chaque ordinateur
    $pos = $item.DistinguishedName.IndexOf("OU=")
    if ($pos -ge 0) 
    {
        $dn = $item.DistinguishedName.Substring($pos)
        #Write-Host $dn
        #$dnList[$id] = $dn
    }else #si pas de OU dans DistinguishedName alors l'ordinateur se trouve dans un CN
    {
        $dn = $item.DistinguishedName      # recuperation du DistinguishedName entier
        $lg = $dn.Length                   # longueur de la chaine DistinguishedName
        $dn = $dn.Substring(3,$lg-3)       # Suppression du premier "CN=" au début de la chaine        
        $pos = $dn.indexof("CN=")          # index du "CN=" dans la nouvelle chaine 
        $lg = $dn.Length                   # longueur de la chaine $cn
        $dn = $dn.Substring($pos,$lg-$pos) # recuperation du DistinguishedName sans le nom de l'ordinateur
        #Write-Host -BackgroundColor DarkCyan -ForegroundColor White $dn
    }
    # Recherche de doublons
    $exist = $false
    if ($id -eq 0) # Si 1er OU ou CN on l'ajoute au tableau
    {
        $dnList[$id] = $dn
        $exist = $true
    }else          # Sinon on parcours la liste des OU pour vérifier si celui en cours existe déjà
    {
        for ($j=0; $j -lt $id; $j++)
        {
            if ($dnList[$j] -match $dn) 
            { 
                $exist = $true # indique l presence
                break          # sortie de la boucle
            }            
        }
    }
    # Si le chemin n'est pas present dans la liste on l'ajoute
    if ($exist -eq $false) 
    { 
        $dnList[$id] = $dn 
    }
    # increment de l'index $id du tableau
    $id++
}
$dncount = $dnList.Count
$dnList | Out-GridView -Title "Emplacement des ordinateurs" -OutputMode None 
$endtime=Get-Date
$totaltime=($endtime-$starttime).TotalSeconds
$minutes="{0:N0}" -f ($totaltime/60)
$seconds="{0:N0}" -f ($totaltime%60)
Write-Host  -BackgroundColor DarkCyan -ForegroundColor White "Recherche et tri des $dncount emplacements uniques effectué en $minutes minutes $seconds secondes."

 
Dernière édition: il y a 2 ans 8 mois par Bruce. Raison: Mettre le code dans le format code

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

Plus d'informations
il y a 2 ans 8 mois #31215 par Arnaud Petitjean
Bonjour Bruce,

Question intéressante pour ton premier post ;-)

Alors, le plus simple pour toi sera de créer un tableau afin d'y stocker tous les chemins AD de tes ordinateurs sans distinction. Puis une fois que cela sera fait, tu dédoublonnes ta liste.

Pour se faire, rien de plus simple grâce aux commandes :
  • Get-Unique
  • Sort-Object -Unique
  • Select-Object -Unique
Tu n'as que l'embarras du choix et tu verras que tu gagneras en temps de traitement.

Petit exemple pour la forme avec Get-Unique :
'toto', 'toto', 'titi', 'tutu', 'tutu' | Get-Unique

toto
titi
tutu

MVP PowerShell et créateur de ce magnifique forum :-)
Auteur de 6 livres PowerShell aux éditions ENI
Fondateur de la société Start-Scripting
Besoin d'une formation PowerShell ?

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

Plus d'informations
il y a 2 ans 8 mois #31217 par Bruce
Réponse de Bruce sur le sujet Optimisation du temps de traitement
Merci je vais regarder ça, je savais que Powershell était puissant et que j'essayais de réinventer la roue mais quand on ne connait pas toutes les primitives on repasse par les bases...

Merci encore je mettrais le code final une fois validé

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

Plus d'informations
il y a 2 ans 8 mois #31218 par Bruce
Réponse de Bruce sur le sujet Optimisation du temps de traitement
Voici le code corrigé et optimisé, je passe de 1min 44sec à 2sec c'est parfait, merci pour les infos !
cls
$starttime=Get-Date
$Alldn = Get-ADComputer -Filter * | Select-Object -Property DistinguishedName |sort -Property DistinguishedName
$totDN = $Alldn.Count
$dnList = @{}
$id = 0
Write-Host "Nombre de PC: $totDN"
foreach ($item in $Alldn)
{
    # Extraction des OU ou CN de chaque ordinateur
    $pos = $item.DistinguishedName.IndexOf("OU=")
    if ($pos -ge 0) 
    {
        $dn = $item.DistinguishedName.Substring($pos)
    }else #si pas de OU dans DistinguishedName alors l'ordinateur se trouve dans un CN
    {
        $dn = $item.DistinguishedName          # recuperation du DistinguishedName entier
        $lg = $dn.Length                                  # longueur de la chaine DistinguishedName
        $dn = $dn.Substring(3,$lg-3)               # Suppression du premier "CN=" au début de la chaine        
        $pos = $dn.indexof("CN=")                  # index du "CN=" dans la nouvelle chaine 
        $lg = $dn.Length                                  # longueur de la chaine $cn
        $dn = $dn.Substring($pos,$lg-$pos)   # recuperation du DistinguishedName sans le nom de l'ordinateur xpl: CN=Computers,DC=Societe,DC=local
    }
    # Ajout dans le tableau
    $dnList[$id] = $dn
    $id++    
}
$dncount = $dnList.Count
$SelectedOU = $dnList.Values | Select-Object -Unique| Sort-Object -Descending |Out-GridView -Title "Selection de l'OU de destination" -OutputMode Single
$endtime=Get-Date
$totaltime=($endtime-$starttime).TotalSeconds
$minutes="{0:N0}" -f ($totaltime/60)
$seconds="{0:N0}" -f ($totaltime%60)
Write-Host  -BackgroundColor DarkCyan -ForegroundColor White "Recherche et tri des $dncount emplacements uniques effectué en $minutes minutes $seconds secondes."
Write-Host  -BackgroundColor DarkCyan -ForegroundColor White "OU selectionnée: $SelectedOU"

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

Plus d'informations
il y a 2 ans 8 mois #31219 par Arnaud Petitjean
Super ! 

MVP PowerShell et créateur de ce magnifique forum :-)
Auteur de 6 livres PowerShell aux éditions ENI
Fondateur de la société Start-Scripting
Besoin d'une formation PowerShell ?

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

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