IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

Scripts/Batch Discussion :

Récupérer un objet Profil Utilisateur (Session) sous XP [PowerShell]


Sujet :

Scripts/Batch

  1. #1
    Candidat au Club
    Homme Profil pro
    Technicien maintenance
    Inscrit en
    Novembre 2013
    Messages
    5
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Puy de Dôme (Auvergne)

    Informations professionnelles :
    Activité : Technicien maintenance
    Secteur : Tourisme - Loisirs

    Informations forums :
    Inscription : Novembre 2013
    Messages : 5
    Points : 3
    Points
    3
    Par défaut Récupérer un objet Profil Utilisateur (Session) sous XP
    Bonjour à tous,

    Je cherche à mettre en place des opérations de nettoyage/maintenance sur les profils utilisateurs.

    J'ai trouvé la manière de récupérer un objet Session, mais celui-ci ne fonctionne que sous les OS à partir de Vista :
    (je vous épargne l'ensemble du code, qui forme quelques pages assez imbuvables)
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    $session = Get-WmiObject -Class Win32_UserProfile -ComputerName LocalHost | Where-Object {$_.LocalPath -eq("C:\Users\$user")}
    Ce qui permet, par exemple, de faire plus loin un joli :
    qui fait un travail très propre (ne se contente pas de supprimer uniquement le dossier du profil)


    Et pour cause (selon ce que j'en ai compris) : les classes WMI ne semblent pas implémentée sous XP !
    En effet, j'ai droit à une erreur :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    Get-WmiObject : Classe non valide


    Je précise deux choses :

    - tout d'abord, le chemin d'accès au dossier du profil n'est pas en question : ça ne prend pas le WmiObject, même si je mets "Documents and Settings" en lieu et place de "Users";

    - Ensuite, sachant que je travaille en local sur la machine (et non via AD) je cherche bien à récupérer le PROFIL Utilisateur, pas l'Utilisateur, que je récupère autrement, via :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    $hostname = (Get-Item Env:\COMPUTERNAME).value
    $computer = [adsi] "WinNT://$hostname"
    $objLocalAccount = $computer.Create("User", $user)
    # etc.
    $objLocalAccount.SetInfo()
    
    # puis plus loin, par exemple
    $computer.Delete("User",$user)


    Donc, pour en revenir à la récupération de ce profil Utilisateur, ça fonctionne très bien sous SeVen & affiliés, mais je n'ai toujours pas réussi à trouver un équivalent qui fonctionnerait sous XP.

    Je peux bien sûr accéder au dossier du profil, le modifier voire le supprimer, mais ce que je veux est bien la SESSION, afin d'avoir la main sur les (éventuelles) propriétés de l'objet, la suppression du dossier de profil ne suffisant pas à supprimer proprement toutes les traces du profil par exemple.

    D'où ma question principale : quelqu'un connaitrait-il un équivalent qui permettrait (via objet adsi ou autre classe ou objet que je ne connais pas, je ne sais pas) la manipulation d'une session d'utilisateur


    Voilà, j'espère avoir été clair; si quelqu'un a une idée là-dessus, j'avoue avoir passé de longues heures de recherches, mais je n'ai rien trouvé qui réponde à ma question pour un usage sous XP...

    Merci

  2. #2
    Rédacteur


    Profil pro
    Inscrit en
    Janvier 2003
    Messages
    7 171
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Janvier 2003
    Messages : 7 171
    Points : 15 060
    Points
    15 060
    Billets dans le blog
    1
    Par défaut
    Salut,
    consulte ces API.

  3. #3
    Candidat au Club
    Homme Profil pro
    Technicien maintenance
    Inscrit en
    Novembre 2013
    Messages
    5
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Puy de Dôme (Auvergne)

    Informations professionnelles :
    Activité : Technicien maintenance
    Secteur : Tourisme - Loisirs

    Informations forums :
    Inscription : Novembre 2013
    Messages : 5
    Points : 3
    Points
    3
    Par défaut
    Bonjour Laurent, et merci pour cette réponse.

    J'avoue avoir pris un peu peur en tombant là-dessus, n'étant pas habitué aux API Windows et encore moins à comment les appeler via PowerShell.

    Néanmoins, j'ai essayé de coder quelque chose pour faire appel à ça, mais dans un premier temps, l'appel à la fonction me renvoie toujours 'false'...

    Voilà à quoi ça ressemble :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    
    # Signature C# de la fonction à appeler
    $signature = @"
    [DllImport("userenv.dll", SetLastError=true)]
    public static extern bool DeleteProfile(
    	string lpSidString,
    	string lpProfilePath,
    	string lpComputerName
    );
    "@
    
    # Ajout de la fonction à la session PowerShell
    $callWinAPI = Add-Type -MemberDefinition $signature -name "DeleteSession" -namespace Win32Functions -passthru
    
    # SID du profil recherché - obligatoire
    [string]$userSID = $null
    # Chemin d'accès au profil recherché - facultatif, obtenu au besoin depuis le registre
    [string]$userProfilePath = $null
    # Nom du poste sur lequel effacer le profil recherché - facultatif, nom du poste local utilisé par défaut
    [string]$computerName = $null
    
    
    # Définition du Profil à traiter
    $user = "UnProfil"
    ""
    "Profil à traiter :  $user"
    ""
    
    # Définition du Profil à effacer et de l'hôte
    $userProfilePath = "C:\Documents and Settings\$user"
    $computerName = (Get-Item Env:\COMPUTERNAME).value
    
    
    # Vérification de la fonction créée & des paramètres
    ""
    ""
    "Type de la fonction générée : "
    $callWinAPI.getType()
    ""
    "Profil à traiter : '$user'"
    ""
    "SID du Profil : '$userSID'"
    ""
    "Chemin d'accès au Profil : '$userProfilePath'"
    ""
    "Nom de l'hôte : '$computerName'"
    ""
    ""
    
    # Appel de la fonction 'DeleteProfile' ainsi créée
    "Appel à la fonction 'DeleteProfile' en cours..."
    $callWinAPI::DeleteProfile($userSID, $userProfilePath, $computerName)
    (et oui, j'aime bien les nombreux affichages, qui me permettent de débugguer directement dans la console, pour voir à quel niveau ça plante...)

    Donc l'essentiel a l'air de fonctionner, mais l'exécution de la fonction me renvoie toujours 'false'...

    Je me suis dit qu'en toute logique cela venait du fait que je n'avais pas le SID entré en paramètre.


    J'ai donc cherché une manière de le récupérer, et là ça se corse, vu qu'encore un fois ça existe et c'est très simple sous SeVen & affiliés, mais ça a l'air un chouille plus complexe sous XP vu que les classes WMI ne sont pas implémentées.

    J'ai tout de même trouvé quelque chose, même si ça tient franchement de l'usine à gaz; à suivre dans le prochain post...

  4. #4
    Candidat au Club
    Homme Profil pro
    Technicien maintenance
    Inscrit en
    Novembre 2013
    Messages
    5
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Puy de Dôme (Auvergne)

    Informations professionnelles :
    Activité : Technicien maintenance
    Secteur : Tourisme - Loisirs

    Informations forums :
    Inscription : Novembre 2013
    Messages : 5
    Points : 3
    Points
    3
    Par défaut
    Donc, suite à cette tentative, j'ai trouvé comment récupérer des infos sur les profils via la base de registre.

    Voilà à quoi ça ressemble au premier jet :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    # Récupération de la liste des Profils inscrits
    $profileList = "HKLM:\SOFTWARE\Microsoft\Windows NT\CurrentVersion\ProfileList"
    
    # Récupération des chemins d'accès & SIDs des profils
    $list_ProfileAndSid = get-ChildItem $profileList | foreach {Get-ItemProperty $_.psPath} | Select profileImagePath, sid
    
    # Récupération du profil recherché
    $list_ProfileAndSid | foreach {
    
        # Récupération du nom du Profil
        $profileName = $_.ProfileImagePath.split("\")[-1]
        "Profil traité : $profileName"
    
        # Pour le profil recherché, récupération du chemin d'accès et du SID
        if ($profileName -eq $user) {
            $userSID = $_.sid
            $userProfilePath = $_.profileImagePath
    
            # Affichage des infos
            ""
            "`t'$profileName' : Profil à traiter !"
            "`tSID : $userSID"
            "`tProfile Path : $userProfilePath"
            ""
        }
    }

    Tout ceci, rajouté dans le code d'origine, me permet bien de récupérer les infos dont j'ai besoin sur mon utilisateur, encore que j'ai l'impression d'essayer de tuer un moustique à coups de bombe atomique...

    Mais même avec les bonnes infos (SID, Path, etc.), l'exécution de la fonction me renvoie toujours 'false', quoi que je fasse.


    Après de longs moments de tests et de recherche, j'avoue que je sèche un peu.

    Par la même occasion, si quelqu'un a une idée sur un moyen plus simple de récupérer le SID d'un profil, je me dis que mon accès à la base de registre et mes boucles/conditions imbriquées ne sont pas ce qu'il y a de plus léger...

    Merci !

  5. #5
    Candidat au Club
    Homme Profil pro
    Technicien maintenance
    Inscrit en
    Novembre 2013
    Messages
    5
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Puy de Dôme (Auvergne)

    Informations professionnelles :
    Activité : Technicien maintenance
    Secteur : Tourisme - Loisirs

    Informations forums :
    Inscription : Novembre 2013
    Messages : 5
    Points : 3
    Points
    3
    Par défaut
    Eureka !

    J'ai réussi à trouver un appel autrement plus simple pour retrouve le SID.

    Et le mieux, c'est que du coup la fonction s'exécute correctement !

    Voilà le morceau de code pour retrouver le SID :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    # Définition du Profil à traiter
    $user = "MonProfil"
    
    # Depuis le nom d'Utilisateur, retrouver le SID d'un compte local
    $objUser = New-Object System.Security.Principal.NTAccount($user)
    $strSID = $objUser.Translate([System.Security.Principal.SecurityIdentifier])
    $userSID = $strSID.Value
    $userProfilePath = "C:\Documents And Settings\$user"

    Au cas où, voici comment trouver le SID d'un compte sur un domaine Active Directory, ou comment retrouver l'Utilisateur depuis son SID :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    # Depuis le nom d'Utilisateur, retrouver le SID d'un compte Active Directory
    $domainName = "MonDomaine"
    $objUser = New-Object System.Security.Principal.NTAccount($domainName, $user)
    $strSID = $objUser.Translate([System.Security.Principal.SecurityIdentifier])
    $strSID.Value
    
    
    # Retrouver l'Utilisateur depuis le SID
    $objSID = New-Object System.Security.Principal.SecurityIdentifier($strSID)
    $objUser = $objSID.Translate( [System.Security.Principal.NTAccount])
    
    $objUser.Value
    # Cette commande retournera : "DOMAINE\USER"
    
    # Pour retrouver juste le Compte Utilisateur, on utilisera par exemple :
    $userAccount = $objUser.Value.split("\")[-1]


    Voilà, c'était aussi "simple" que ça !

    Du coup, l'exécution se passe à merveille et le Profil est bien supprimé proprement, ce qu'on retrouve dans "Propriétés Système" -> "Profils Utilisateurs".

    La seule chose qui me chagrine, c'est de ne pas savoir en quoi le SID récupéré de cette manière est différent de celui récupéré via la méthode précédente...


    Code complet fourni dans le post suivant...

  6. #6
    Candidat au Club
    Homme Profil pro
    Technicien maintenance
    Inscrit en
    Novembre 2013
    Messages
    5
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Puy de Dôme (Auvergne)

    Informations professionnelles :
    Activité : Technicien maintenance
    Secteur : Tourisme - Loisirs

    Informations forums :
    Inscription : Novembre 2013
    Messages : 5
    Points : 3
    Points
    3
    Par défaut
    Et voici le code "complet" concernant la suppression d'un profil :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    # Signature C# de la fonction à appeler
    $signature = @"
    [DllImport("userenv.dll", SetLastError=true)]
    public static extern bool DeleteProfile(
    	string lpSidString,
    	string lpProfilePath,
    	string lpComputerName
    );
    "@
    
    # Ajout de la fonction à la session PowerShell
    $callWinAPI = Add-Type -MemberDefinition $signature -name "DeleteSession" -namespace Win32Functions -passthru
    
    # SID du profil recherché - obligatoire
    [string]$userSID = $null
    # Chemin d'accès au profil recherché - facultatif, obtenu au besoin depuis le registre
    [string]$userProfilePath = $null
    # Nom du poste sur lequel effacer le profil recherché - facultatif, nom du poste local utilisé par défaut
    [string]$computerName = $null
    
    
    # Définition du Profil à traiter
    $user = "UnProfil"
    ""
    "Profil à traiter :  $user"
    ""
    
    
    # Depuis le nom d'Utilisateur, retrouver le SID d'un compte local
    $objUser = New-Object System.Security.Principal.NTAccount($user)
    $strSID = $objUser.Translate([System.Security.Principal.SecurityIdentifier])
    $userSID = $strSID.Value
    
    # Affichagedu Profil à effacer et de l'hôte
    $userProfilePath = "C:\Documents and Settings\$user"
    $computerName = (Get-Item Env:\COMPUTERNAME).value
    
    
    # Vérification de la fonction créée & des paramètres
    ""
    ""
    "Type de la fonction générée : "
    $callWinAPI.getType()
    ""
    "Profil à traiter : '$user'"
    ""
    "SID du Profil : '$userSID'"
    ""
    "Chemin d'accès au Profil : '$userProfilePath'"
    ""
    "Nom de l'hôte : '$computerName'"
    ""
    ""
    
    # Appel de la fonction 'DeleteProfile' ainsi créée
    "Appel à la fonction 'DeleteProfile' en cours..."
    $callWinAPI::DeleteProfile($userSID, $userProfilePath, $computerName)

    Sachant que ceci fait partie d'un projet plus vaste, je me limiterai ici à considérer cette partie résolue.

    Encore merci Laurent pour cette piste, ça n'a pas été simple, mais ça valait le coup !

    J'espère que mes déboires pourront servir à ceux qui se poseraient la même question pour gérer les profils sous XP.

  7. #7
    Rédacteur


    Profil pro
    Inscrit en
    Janvier 2003
    Messages
    7 171
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Janvier 2003
    Messages : 7 171
    Points : 15 060
    Points
    15 060
    Billets dans le blog
    1
    Par défaut
    Citation Envoyé par Thierry Dumontel Voir le message
    ...j'ai l'impression d'essayer de tuer un moustique à coups de bombe atomique...
    Il y a de nombreux cas où on doit en passer par là.
    C'est sûr que l'on aimerait bien juste dire afin que la machine fasse, mais pour l'instant le futur a encore besoin de nous.

    Citation Envoyé par Thierry Dumontel Voir le message
    Encore merci Laurent pour cette piste, ça n'a pas été simple, mais ça valait le coup !
    C'est comme tout le reste , les débuts sont tjr difficile

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. Comment récupérer un objet d'une session ?
    Par Invité dans le forum Langage
    Réponses: 3
    Dernier message: 06/05/2008, 15h39
  2. Réponses: 2
    Dernier message: 13/08/2007, 08h46
  3. Récupérer la durée d'une session utilisateur
    Par gazza dans le forum Langage
    Réponses: 3
    Dernier message: 20/09/2006, 10h22
  4. [DOS] Récupérer les infos du profil utilisateur
    Par Amélie Ladoque dans le forum Windows
    Réponses: 2
    Dernier message: 13/01/2006, 17h41
  5. Réponses: 4
    Dernier message: 14/09/2005, 21h39

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo