Toujours dans le cadre de la modification d'un mot de passe administrateur sur le domaine, j'ai du rechercher tous les connecteurs ODBC utilisant un compte spécifique (en plus des services et des tâches planifiées ).

Dans cet article, je vais vous expliquer comment faire pour obtenir la liste des connecteurs ODBC utilisant un compte précis. Ce script, comme les précédents en lien, a toute son utilité lorsqu'il est lancé dans une boucle qui balaiera l'intégralité des serveurs d'une UO ou répondant à un filtre précis dans le nom (si votre charte de nommage des serveurs vous permet de les retrouver ainsi).

Comment faire?

Les connecteurs ODBC sont assez simples à localiser, mais ne sont toutefois pas très aisés à interroger.

Ils se trouvent dans le registre, séparées dans deux ruches, une système (HKEY_CURRENT_USER), une utilisateur (HKEY_LOCAL_MACHINE).

Dans chacune de ces ruches, nous trouverons les clés SOFTWARE\ODBC\ODBC.INI qui dans lesquelles nous aurons en clair les informations d'identifiant ET de mot de passe pour le connecteur.

Oui. Le mot de passe en clair. (d'ou l'importance de ne PAS utiliser le compte "administrateur" du domaine)

Tout d'abord, sélectionnons nos UO ou sont situées nos serveurs. Ici, il s'agira de "Serveurs" dans l'UO "SITE 1" et de "Domain Controllers".

$ou = @("OU=Servers,OU=SITE 1,DC=domaine,DC=local","OU=Domain Controllers,DC=domaine,DC=local") 
#définition des UO
$tableauerreurs = New-object System.Collections.ArrayList 
#création d'un tableau contenant les erreurs
$listesrv = New-Object System.Collections.ArrayList 
#création d'un tableau contenant la liste des serveurs
$tableauodbc =New-object System.Collections.ArrayList 
#création d'un tableau contenant la liste des connecteurs trouvés

Nous allons ensuite récuperer l'intégralité des serveurs en nous servant de la commande Get-ADComputer et en récupérant en plus la propriété "OperatingSystem" pour pouvoir ensuite filtrer les serveurs Windows uniquement.

 $ou | % {
 $serveurs = Get-ADComputer -SearchBase $_ -Filter * -Properties "OperatingSystem"
 $listesrv.AddRange($serveurs) 
 #nous ajoutons la liste contenue dans $serveurs au tableau
 }
$listesrv = $listesrv | Where-Object {$_.operatingsystem -like "Windows*"} |Sort-Object -Property name 
#Nous filtrons ce qui comporte "windows" et trions par le nom
$listesrv | Select-Object -Property name

A ce stade nous avons donc une liste de serveurs Windows à analyser.

Nous n'avons qu'à ouvrir la liste des clés contenues dans les ruches précisées au préalable en nous servant de la classe .NET Microsoft.Win32.RegistryKey Pour étant donné que la clé est la même dans chaque ruche (SOFTWARE\ODBC\ODBC.INI) je crée une table contenant CurrentUser et LocalMachine pour ensuite aller dans chaque en me servant de la clé. La procédure est la suivante :

  1. Obtention de la liste des sous-clés avec la méthode getsubkeynames()
  2. Recherche dans chaque sous-clé (avec opensubkey() puis getvaluenames() ) d'une entrée nommée UID (l'identifiant d'un connecteur ODBC)
  3. Enregistrement des valeurs de UID et PWD (avec la méthode getvalue() dans des variables puis injection dans le tableau

A cela est ajoutée une petite vérification au cas ou il soit impossible d'accéder au serveur pour une raison quelconque. Cette petite vérification va récupérer l'erreur affichée et l'envoyer dans le tableau créé à cet effet, et si aucune erreur ne se produit, les informations seront collectées.


Script final

Vous pouvez télécharger ce script depuis mon espace git personnel.

$ou = @("OU=Servers,OU=SITE 1,DC=domaine,DC=local","OU=Domain Controllers,DC=domaine,DC=local") 
#définition des UO
$tableauerreurs = New-object System.Collections.ArrayList 
#création d'un tableau contenant les erreurs
$listesrv = New-Object System.Collections.ArrayList 
#création d'un tableau contenant la liste des serveurs
$tableauodbc =New-object System.Collections.ArrayList 
#création d'un tableau contenant la liste des connecteurs trouvés

$ou | % {
 $serveurs = Get-ADComputer -SearchBase $_ -Filter * -Properties "OperatingSystem"
 $listesrv.AddRange($serveurs) 
 #nous ajoutons la liste contenue dans $serveurs au tableau
 }
$listesrv = $listesrv | Where-Object {$_.operatingsystem -like "Windows*"} |Sort-Object -Property name 
#Nous filtrons ce qui comporte "windows" et trions par le nom
$listesrv | Select-Object -Property name

foreach ($serveur in $listesrv)

{

$key = "SOFTWARE\ODBC\ODBC.INI"
$types = @([Microsoft.Win32.RegistryHive]::CurrentUser,[Microsoft.Win32.RegistryHive]::LocalMachine)

foreach ($type in $types)
{

$regkey = [Microsoft.Win32.RegistryKey]::OpenRemoteBaseKey($type, $($serveur.name)) #nous ouvrons la ruche distante sur l'ordinateur scanné
if (!$?)
    {
    $tableauerreurs.add([PSCUSTOMOBJECT]@{
        "Serveur" = $($serveur.name)   
        "Region" = "ODBC $type clé  $type\$key"
        "Erreur" = $error[0].Exception.Message
        })
    }
else
    {
    $regkey = $regkey.opensubkey($key) #ouverture de la clé contenant les infos d'ODBC

    if ($regkey -ne $null)
        {
        #on récupère l'intégralité des clés enfants, et pour chaque on va voir s'il y'a des informations d'UID
        foreach ($value in $regkey.GetSubKeyNames() ) 
            {
   $subkey = $regkey.OpenSubKey($value) 
            if ($subkey.GetValueNames() -contains "UID")
                {
                $user = $subkey.getValue("UID") #on récupère le nom d'utilisateur
                $pass = $subkey.getValue("PWD") #et également le mot de passe
                $tableauodbc.Add([PSCUSTOMOBJECT]@{
                    "Serveur" = $($serveur.name)
                    "Type ODBC" = "$type"
                    "Chemin ODBC" = "$type\$key\$subkey"
                    "Utilisateur" = $user
                    }) #et on ajoute le tout dans le  tableau
                }

            } #fin foreach valeur dans sous clés registre
        }
    }

}
} #fin foreach
$tableauodbc

Ajouter un commentaire

Article précédent Article suivant