Depuis quelque jours je me suis mis en tête de fabriquer un petit script qui permettrai de lancer l’assistance à distance Microsoft dans le style graphique de ce script mais en ayant la possibilité de naviguer dans les branches de l'Active Directory du poste de travail.
L’application démarre sur la racine AD du poste et alimente une combobox avec toutes les branches AD, un sous menu est alimenté également avec tous les nœuds de niveaux 1 de l'AD, il est possible, a l'aide de ce sous menu de sélectionner un nœud et de mettre le focus dessus.
lorsqu'on sélectionne une branche de l'AD, le click sur le bouton valider lance la fonction de recherche des ordinateurs dans la branche et alimente une autre combobox qui recense tous les comptes ordinateurs de la branche.
Il suffit de sélectionner un ordinateur dans la combobox et de cliquer sur "Assistance à distance" pour lancer MSRA /offerRa vers le poste sélectionné.
Voilà le code :
#include <AD.au3>
#include <GUIConstantsEx.au3>
#include <GuiButton.au3>
#include <GUIConstants.au3>
#include <GuiComboBox.au3>
#include <GuiMenu.au3>
;FileInstall("c:\devau3\rma.jpg", @DocumentsCommonDir & "\"); si on veux mettre un splashscreen d'attente, installation de l'image
;SplashImageOn("",@DocumentsCommonDir & "\rma.jpg"); affichage du splashscreen
Global $sSep = "\" ; variable qui permet de segmenter les OU pour trouver les noeuds
Global $FQDN = GetRootDSE() ; Fonction qui permet de trouver la racine du domaine AD
if $FQDN="KO" then ; si aucun dimaine
Msgbox(64,"Remote Asiistant", "Erreur, A.D. non trouvé" & @CRLF & "Ce programme fonctionne avec Active Directory")
Exit ; Adios
EndIf
$baseOU = "" ; permet d'ouvrir AD la la racine du domaine
; génération des tableaux
Dim $arraycomputers, $menu_OU_item
Dim $nodes_ad[2]
$nodes_ad[0] = ubound($nodes_ad,1)
Dim $menu_OU_item[1]
$arrayou = _getous($baseOU) ; tableau contenant la base AD récupérée
Global $aNodes[$arrayou[0][0] + 1] = [$arrayou[0][0]] ; tableau permettant de récuperer les noeuds de niveau 1
For $i = 1 To $arrayou[0][0] ; boucle de pré-traitement pour la péparation du tableau $aNodes (noeuds de niveau 1)
$aTemp = StringSplit($arrayou[$i][0], $sSep)
$aNodes[$i] = StringFormat("%" & $aTemp[0] - 1 & "s", "") & "#" & $aTemp[$aTemp[0]]
Next
Nodes_AD($aNodes) ; fonction de traitement des noeuds AD niveau 1
$hwnd=GUICreate("Remote assistant : " & $baseOU & $FQDN,700,200) ; creation de la GUI
$menu = GUICtrlCreateMenu("menu"); création du menu
$menu_OU = GUICtrlCreateMenu("Unité Organisationelles")
for $i = 0 to ubound($nodes_ad) ; création du sous menu "Unité Organisationelles" qui se générera automatiquement selon les noeuds de niveau 1 de l'AD dont le poste dépend.
if $i = ubound($nodes_ad)-1 then ; pour éviter de sortir du tableau et générer une erreur
ExitLoop
Else
$menu_OU_item[$i] = GUICtrlCreateMenuItem($nodes_ad[$i+1],$menu_ou); création des sous menus
;consoleWrite($menu_OU_item[$i] & " " & $nodes_ad[$i+1] & @CRLF) ; débug
redim $menu_OU_item[ubound($menu_OU_item)+1] ; redimentionnement du tableau
EndIf
Next
;_arraydisplay($menu_OU_item)
$item_openComputer = GUICtrlCreateMenuItem("Asistance Directe",$menu)
$item_quitter = GUICtrlCreateMenuItem("Quitter",$menu)
$combocomputers=GUICtrlCreateCombo("Selectionnez un ordinateur",10,60,600)
$buttonselectOU = GUICtrlCreateButton("Valider",620,10)
$comboOU = GUICtrlCreateCombo("Selectionnez la branche Active directory" ,10,10,600)
$buttonRA = GUICtrlCreateButton('Assistance à distance', 0, 100, 700, 100, BitAND($BS_CENTER, $BS_VCENTER));
GUISetBkColor(0x00EEEEEE);
GUICtrlSetFont(-1, 25, 400, 0, "Verdana");
_alim_comboOU() ; alimentation du combo des OU
;SplashOff() ; fin d'affichage du splashscreen
GUISetState(@SW_SHOW) ; affichage de la GUI
While 1
$msg=GUIGetMsg()
Switch $msg
Case $GUI_EVENT_CLOSE , $item_quitter
Exit
Case $buttonselectOU ; click sur le combo de choix de l'OU
_GUICtrlComboBox_ResetContent($combocomputers) ; reset du combo en cas de nouvelle selection
GUICtrlSetData($combocomputers, "Selectionnez un ordinateur","Selectionnez un ordinateur")
$readOU=GUICtrlRead($comboOU) ; lecture de la ligne du combo
$arraycomputers = _NameFromAD(retransformeforAD($readOU)) ; permet de transformer la lecture "\" en "OU=" pour lire la base AD
if IsArray($arraycomputers) Then ; si des ordis sont trouvés
msgbox(64,"Remote Assiatant", "trouvé " & $arraycomputers[0] & " ordinateur(s)",1)
For $i=1 To Ubound($arraycomputers)-1 ; alors on alimente le combo des ordis
GUICtrlSetData($combocomputers,$arraycomputers[$i]); alimentation du combo
Next
Else
msgbox(48,"Remote assistant","Aucun Ordinateur dans la branche sélectionnée", 2); si pas d'ordis
EndIf
Case $buttonRA
$readComputer=GUICtrlRead($combocomputers) ; lecture de la ligne du combo ordis
if $readComputer ="" or $readComputer = "Selectionnez un ordinateur" then ; pour les petits malins !
msgbox(48,"Remote Assistant","Veuillez selectionner un ordinateur !", 2)
Else
launchRA($readComputer) ;permet de lancer le remote assist de microsoft (cf fonction)
EndIf
Case $item_openComputer ; on connait le nom de l'ordinateur a assister
$imput = InputBox("Remote Assistant", "Entrez le nom de la machine à contrôller")
if $imput <> "" Then
launchRA($imput)
EndIf
Case $menu_OU_item[0] to ubound($menu_OU_item)+2 ; le plus difficile, la selection du sous menu auto généré
$baseOU = "OU="& GUICtrlRead($menu_OU_item[$msg-$menu_OU_item[0]],1) &"," ; lecture de l'item du sous menu et transformation pour la base AD
ControlSetText($hwnd,$baseOU,$hwnd, "Remote assistant : " & $baseOU & $FQDN); changement du titre de la fenêtre principale
$arrayou = "" ; remise a zero du tableau
$arrayou = _getous($baseOU & $FQDN) ; et alimentation
GUICtrlSetData($comboOU,'') ; remise a zero du combo
GUICtrlSetData($comboOU,"Selectionnez la branche Active directory","Selectionnez la branche Active directory"); et alimentation
_alim_comboOU()
EndSwitch
WEnd
Func _alim_comboOU() ; alimentation du combo des OU
For $j=1 To Ubound($arrayou)-1
GUICtrlSetData($comboOU,$arrayou[$j][0]) ; chaque ligne du tableau crée une ligne dans la combobox
Next
EndFunc
func launchRA($computer);
ShellExecute("msra.exe","/offerRA " & $computer ) ; executable présent depuis windows 7 /offerRa permet de lancer l'assitance a distance sur le poste du client.
EndFunc
func _NameFromAD($sOU); fonction qui permet de retrouver le nom des ordinateurs de la branche AD selectionnée
_AD_Open(); ouverture de l'AD par défaut
Global $aComputers
$aComputers=_AD_GetObjectsInOU($sOU,"(objectclass=computer)",2,"name")
return $aComputers
_AD_Close()
EndFunc
Func GetRootDSE() ; fonction qui permet de connaitre la racine du domaine sur lequel est connecté le poste client
$RootDSE = ObjGet("LDAP://RootDSE")
If IsObj($RootDSE) Then
Return $RootDSE.get( "DefaultNamingContext" )
Else ; si il n'y a pas de domaine !
return "KO"
EndIf
EndFunc
func _getous($baseOU) ; lis la base AD - fonctionne avec l'UDF AD.au3
_AD_Open()
If @error Then Exit MsgBox(16, "Remote assistant", "Erreur. @error = " & @error & ", @extended = " & @extended)
Global $aOUs = _AD_GetAllOUs($baseOU, $sSep)
If @error > 0 Then
MsgBox(64, "Erreur", "Aucune OU ne peut être trouvée " & @error)
Else
;_arraydisplay($aOUs) ; debug
return $aOUs
EndIf
_AD_Close()
EndFunc
Func retransformeforAD($directory) ; fonction de transformation des "\" en "OU="
$OUcomplet = ""
$aOU = ""
local $transit1 = "OU=" & $directory
local $transit2 = StringReplace($transit1, "\", ",OU=")
local $transit3 = StringSplit($transit2, ",")
$i = $transit3[0]
While ($i >= 1)
$aOU &= $transit3[$i] & ","
$i = $i - 1
WEnd
$OUcomplet = $aOU & $FQDN
return $OUcomplet
EndFunc ;==>retransfo
Func Nodes_AD($aTree); fonction de découpage des noeuds de l'AD dans le but de créer le sous menu "Unités Organisationnelles"
For $i = 1 To $aTree[0]
$line = StringSplit(StringStripCR($aTree[$i]), @TAB) ; découpage de chaque ligne du tableau pour en determiner le niveau
$level = StringInStr($line[1], "#")
If $level = 0 Then
ExitLoop
EndIf
If $level = 1 Then ; si niveau 1 alors on envoi vers le tableau pour le sous menu
$nodes_ad[ubound($nodes_ad)-1] = StringMid($line[1], $level + 1)
redim $nodes_ad[ubound($nodes_ad) +1] ; redimentionnement
EndIf
Next
$nodes_ad[0] = ubound($nodes_ad,1); comptage du nombre de lignes du tableau.
EndFunc
#include <GUIConstantsEx.au3>
#include <GuiButton.au3>
#include <GUIConstants.au3>
#include <GuiComboBox.au3>
#include <GuiMenu.au3>
;FileInstall("c:\devau3\rma.jpg", @DocumentsCommonDir & "\"); si on veux mettre un splashscreen d'attente, installation de l'image
;SplashImageOn("",@DocumentsCommonDir & "\rma.jpg"); affichage du splashscreen
Global $sSep = "\" ; variable qui permet de segmenter les OU pour trouver les noeuds
Global $FQDN = GetRootDSE() ; Fonction qui permet de trouver la racine du domaine AD
if $FQDN="KO" then ; si aucun dimaine
Msgbox(64,"Remote Asiistant", "Erreur, A.D. non trouvé" & @CRLF & "Ce programme fonctionne avec Active Directory")
Exit ; Adios
EndIf
$baseOU = "" ; permet d'ouvrir AD la la racine du domaine
; génération des tableaux
Dim $arraycomputers, $menu_OU_item
Dim $nodes_ad[2]
$nodes_ad[0] = ubound($nodes_ad,1)
Dim $menu_OU_item[1]
$arrayou = _getous($baseOU) ; tableau contenant la base AD récupérée
Global $aNodes[$arrayou[0][0] + 1] = [$arrayou[0][0]] ; tableau permettant de récuperer les noeuds de niveau 1
For $i = 1 To $arrayou[0][0] ; boucle de pré-traitement pour la péparation du tableau $aNodes (noeuds de niveau 1)
$aTemp = StringSplit($arrayou[$i][0], $sSep)
$aNodes[$i] = StringFormat("%" & $aTemp[0] - 1 & "s", "") & "#" & $aTemp[$aTemp[0]]
Next
Nodes_AD($aNodes) ; fonction de traitement des noeuds AD niveau 1
$hwnd=GUICreate("Remote assistant : " & $baseOU & $FQDN,700,200) ; creation de la GUI
$menu = GUICtrlCreateMenu("menu"); création du menu
$menu_OU = GUICtrlCreateMenu("Unité Organisationelles")
for $i = 0 to ubound($nodes_ad) ; création du sous menu "Unité Organisationelles" qui se générera automatiquement selon les noeuds de niveau 1 de l'AD dont le poste dépend.
if $i = ubound($nodes_ad)-1 then ; pour éviter de sortir du tableau et générer une erreur
ExitLoop
Else
$menu_OU_item[$i] = GUICtrlCreateMenuItem($nodes_ad[$i+1],$menu_ou); création des sous menus
;consoleWrite($menu_OU_item[$i] & " " & $nodes_ad[$i+1] & @CRLF) ; débug
redim $menu_OU_item[ubound($menu_OU_item)+1] ; redimentionnement du tableau
EndIf
Next
;_arraydisplay($menu_OU_item)
$item_openComputer = GUICtrlCreateMenuItem("Asistance Directe",$menu)
$item_quitter = GUICtrlCreateMenuItem("Quitter",$menu)
$combocomputers=GUICtrlCreateCombo("Selectionnez un ordinateur",10,60,600)
$buttonselectOU = GUICtrlCreateButton("Valider",620,10)
$comboOU = GUICtrlCreateCombo("Selectionnez la branche Active directory" ,10,10,600)
$buttonRA = GUICtrlCreateButton('Assistance à distance', 0, 100, 700, 100, BitAND($BS_CENTER, $BS_VCENTER));
GUISetBkColor(0x00EEEEEE);
GUICtrlSetFont(-1, 25, 400, 0, "Verdana");
_alim_comboOU() ; alimentation du combo des OU
;SplashOff() ; fin d'affichage du splashscreen
GUISetState(@SW_SHOW) ; affichage de la GUI
While 1
$msg=GUIGetMsg()
Switch $msg
Case $GUI_EVENT_CLOSE , $item_quitter
Exit
Case $buttonselectOU ; click sur le combo de choix de l'OU
_GUICtrlComboBox_ResetContent($combocomputers) ; reset du combo en cas de nouvelle selection
GUICtrlSetData($combocomputers, "Selectionnez un ordinateur","Selectionnez un ordinateur")
$readOU=GUICtrlRead($comboOU) ; lecture de la ligne du combo
$arraycomputers = _NameFromAD(retransformeforAD($readOU)) ; permet de transformer la lecture "\" en "OU=" pour lire la base AD
if IsArray($arraycomputers) Then ; si des ordis sont trouvés
msgbox(64,"Remote Assiatant", "trouvé " & $arraycomputers[0] & " ordinateur(s)",1)
For $i=1 To Ubound($arraycomputers)-1 ; alors on alimente le combo des ordis
GUICtrlSetData($combocomputers,$arraycomputers[$i]); alimentation du combo
Next
Else
msgbox(48,"Remote assistant","Aucun Ordinateur dans la branche sélectionnée", 2); si pas d'ordis
EndIf
Case $buttonRA
$readComputer=GUICtrlRead($combocomputers) ; lecture de la ligne du combo ordis
if $readComputer ="" or $readComputer = "Selectionnez un ordinateur" then ; pour les petits malins !
msgbox(48,"Remote Assistant","Veuillez selectionner un ordinateur !", 2)
Else
launchRA($readComputer) ;permet de lancer le remote assist de microsoft (cf fonction)
EndIf
Case $item_openComputer ; on connait le nom de l'ordinateur a assister
$imput = InputBox("Remote Assistant", "Entrez le nom de la machine à contrôller")
if $imput <> "" Then
launchRA($imput)
EndIf
Case $menu_OU_item[0] to ubound($menu_OU_item)+2 ; le plus difficile, la selection du sous menu auto généré
$baseOU = "OU="& GUICtrlRead($menu_OU_item[$msg-$menu_OU_item[0]],1) &"," ; lecture de l'item du sous menu et transformation pour la base AD
ControlSetText($hwnd,$baseOU,$hwnd, "Remote assistant : " & $baseOU & $FQDN); changement du titre de la fenêtre principale
$arrayou = "" ; remise a zero du tableau
$arrayou = _getous($baseOU & $FQDN) ; et alimentation
GUICtrlSetData($comboOU,'') ; remise a zero du combo
GUICtrlSetData($comboOU,"Selectionnez la branche Active directory","Selectionnez la branche Active directory"); et alimentation
_alim_comboOU()
EndSwitch
WEnd
Func _alim_comboOU() ; alimentation du combo des OU
For $j=1 To Ubound($arrayou)-1
GUICtrlSetData($comboOU,$arrayou[$j][0]) ; chaque ligne du tableau crée une ligne dans la combobox
Next
EndFunc
func launchRA($computer);
ShellExecute("msra.exe","/offerRA " & $computer ) ; executable présent depuis windows 7 /offerRa permet de lancer l'assitance a distance sur le poste du client.
EndFunc
func _NameFromAD($sOU); fonction qui permet de retrouver le nom des ordinateurs de la branche AD selectionnée
_AD_Open(); ouverture de l'AD par défaut
Global $aComputers
$aComputers=_AD_GetObjectsInOU($sOU,"(objectclass=computer)",2,"name")
return $aComputers
_AD_Close()
EndFunc
Func GetRootDSE() ; fonction qui permet de connaitre la racine du domaine sur lequel est connecté le poste client
$RootDSE = ObjGet("LDAP://RootDSE")
If IsObj($RootDSE) Then
Return $RootDSE.get( "DefaultNamingContext" )
Else ; si il n'y a pas de domaine !
return "KO"
EndIf
EndFunc
func _getous($baseOU) ; lis la base AD - fonctionne avec l'UDF AD.au3
_AD_Open()
If @error Then Exit MsgBox(16, "Remote assistant", "Erreur. @error = " & @error & ", @extended = " & @extended)
Global $aOUs = _AD_GetAllOUs($baseOU, $sSep)
If @error > 0 Then
MsgBox(64, "Erreur", "Aucune OU ne peut être trouvée " & @error)
Else
;_arraydisplay($aOUs) ; debug
return $aOUs
EndIf
_AD_Close()
EndFunc
Func retransformeforAD($directory) ; fonction de transformation des "\" en "OU="
$OUcomplet = ""
$aOU = ""
local $transit1 = "OU=" & $directory
local $transit2 = StringReplace($transit1, "\", ",OU=")
local $transit3 = StringSplit($transit2, ",")
$i = $transit3[0]
While ($i >= 1)
$aOU &= $transit3[$i] & ","
$i = $i - 1
WEnd
$OUcomplet = $aOU & $FQDN
return $OUcomplet
EndFunc ;==>retransfo
Func Nodes_AD($aTree); fonction de découpage des noeuds de l'AD dans le but de créer le sous menu "Unités Organisationnelles"
For $i = 1 To $aTree[0]
$line = StringSplit(StringStripCR($aTree[$i]), @TAB) ; découpage de chaque ligne du tableau pour en determiner le niveau
$level = StringInStr($line[1], "#")
If $level = 0 Then
ExitLoop
EndIf
If $level = 1 Then ; si niveau 1 alors on envoi vers le tableau pour le sous menu
$nodes_ad[ubound($nodes_ad)-1] = StringMid($line[1], $level + 1)
redim $nodes_ad[ubound($nodes_ad) +1] ; redimentionnement
EndIf
Next
$nodes_ad[0] = ubound($nodes_ad,1); comptage du nombre de lignes du tableau.
EndFunc