Gérer les connexions aux imprimantes de manière centralisée

Lors de la migration d'un annuaire Novell vers Active Directory chez un client, un problème s'est posé pour recréer la fonctionnalité d'affecter certaines queues d'impression à certains groupes d'utilisateurs. L'objectif principal est d'allouer (ou de désallouer) automatiquement les imprimantes simplement en ajoutant les utilisateurs dans des groupes dédiés à cet usage.

Or, par défaut, les stratégies Microsoft permettent de faire cela, mais s'appliquent principalement à des unités d'organisation et non aux groupes. Ceci limite fortement l'utilisation, les utilisateurs étant rarement regroupés de manière adéquate. L'utilisation de la sécurité sur les stratégies pour appliquer ou une stratégie n'est pas pratique et ne résout pas tous les problèmes.

La solution aura été de créer un script gérant les imprimantes à connecter ou à déconnecter ainsi que l'affectation de l'imprimante par défaut si cela est préférable.

Ce script peut s'exécuter dans une stratégie de lancement de script à l'ouverture de session, ou tout simplement intégré au script de connexion de l'utilisateur. Le script détecte tous les groupes d'impression dont fait partie l'utilisateur, et réalise les actions indiquées dans ce groupe. L'astuce à ce niveau consiste à utiliser la zone "info" (Notes/Remarques) de chaque groupe pour conserver les actions correspondantes. On suppose que les groupes d'imprimantes commencent par "IMP_", mais le script peut être modifié afin de prendre en compte un préfixe différent.

3 actions sont prévues :

DEFAULT\TDSRV2.DEMAN.LOCAL\EPSON810M [ Connecter une imprimante et la définir par défaut
CONNECT\TDSRV12.DEMAN.LOCAL\EPSON [ Connecter l'imprimante (l'ajouter aux imprimantes existantes)
REMOVE\TDSRV2\CANON [ Déconnecter l'imprimante si elle est définie dans l'environnement de l'utilisateur

Bien entendu, un même groupe peut réaliser plusieurs actions sur différentes imprimantes.

Le script étant réalisé en VBS, le lancement sera fait sous la forme de "cscript MAPPRINTER.VBS" afin d'éviter de devoir valider chaque ligne d'affichage.

Voici ce contenu du script:

' ********************************************
' Map des imprimantes selon les groupes AD "IMP_xxx"
'
' ********************************************
'on error resume next
'
' Declaration des variables
dim userName,StrDomainNC,UserGroups,ImpUserGroups,UserDN,GroupDN, ZoneInfo

dim i,j

' Declaration des objets
dim wshNetwork, userobj,oRootDSE,GroupObj,UserGrp,oConnection,oRecordSet

'Ne pas déclarer les tableaux utilisés par SPLIT
' Impr,LigneImpr

' Create a wshNetwork object
set wshNetwork = createObject("wscript.Network")

Set oRootDSE = GetObject("LDAP://RootDSE")
strDomainNC = oRootDSE.Get("defaultNamingContext")
'wscript.echo StrDomainNC

Set oConnection = CreateObject("ADODB.Connection")
oConnection.Provider = "ADsDSOObject"
oConnection.Open "ADs Provider"

Username=WshNetwork.username
UserDN=GiveDN(Username,"user")
Set UserObj = GetObject("LDAP://"&UserDN)

wscript.echo "Bonjour "&username&" connecté sur "&WshNetwork.computername

'UserGroups=""
ImpUserGroups=""

For Each GroupObj In UserObj.Groups
UserGroups=UserGroups & "[" & GroupObj.SamAccountName+"]"
' wscript.echo UserGroups
If Left(GroupObj.name,7)="CN=IMP_" Then ImpUserGroups=ImpUserGroups &"|"& GroupObj.SamAccountName
Next

wscript.echo "Membre de "&replace(ImpUserGroups,"|"," ")
impuserGroups=mid(ImpUserGroups,2)
'wscript.echo ImpUserGroups
impr=split(ImpUserGroups,"|")
for i=lbound(impr) to ubound(impr)
GroupDN=giveDn(impr(i),"group")
set UserGrp = GetObject("LDAP://"&GroupDN)
ZoneInfo=UserGrp.info
ligneImpr=split(ZoneInfo,chr(13)+chr(10))
for j=lbound(LigneImpr) to ubound(LigneImpr)
IF Left(LigneImpr(j),6)="REMOVE" Then
On error resume next
wshNetwork.RemovePrinterConnection Mid(LigneImpr(j),7),true,true
If err.number<>0 Then
err.clear
Else
Wscript.echo "La connexion de l'imprimante: "&LigneImpr(j)&" a été supprimée"
End if
on error goto 0
Else
If (Left(LigneImpr(j),7)="DEFAULT") OR (Left(LigneImpr(j),7)="CONNECT") Then
DefaultPrinter=False
IF Left(LigneImpr(j),7)="DEFAULT" Then
DefaultPrinter=True
End If
LigneImpr(j)=Mid(LigneImpr(j),8)

On error resume next
wshNetwork.addWindowsPrinterConnection (LigneImpr(j))
If err.number <>0 Then
wscript.echo "Erreur de connexion sur l'imprimante: "&LigneImpr(j)
Else
wscript.echo "Connexion de l'imprimante: "&LigneImpr(j)
If DefaultPrinter=True Then wshNetwork.SetDefaultPrinter LigneImpr(j)
End if
on error goto 0
End if
End if
next

next
'
'Function InGroup(strGroup)
' InGroup=False
' If InStr(UserGroups,"[" & strGroup & "]") Then
' InGroup=True
' End If
'End Function
Function GiveDN(SamAccountName,TypeAccount)

Set oRecordset = oConnection.Execute("<GC://"+StrDomainNC+">;(&(objectCategory="&typeAccount&")(samaccountname="+samAccountName+"));distinguishedName;subtree")

If Not oRecordset.EOF Then
While Not oRecordset.EOF
if isnull(oRecordset.Fields("distinguishedName")) Then
GiveDN=""
else
GiveDN=oRecordset.Fields("distinguishedName")
exit function
end if
oRecordset.movenext
Wend
Else
GiveDN=""
End If

end function

Bien sur, pour que les connexions se passent aussi magiquement sur Windows 7 que sur XP, le serveur devra posséder les drivers nécessaires à chaque type de client (32 et 64 bits). Par ailleurs, si les drivers ne sont pas signés, la stratégie (des pilotes signés/non signés) devra autoriser les utilisateurs à installer ce type de drivers.

Sinon, lors de la première installation d'un driver non signé, une approbation sera demandée !

A noter que cette solution particulière pour gérer les imprimantes pourrait être aussi utilisée pour gérer d'autres paramètres qui sont normalement affectés aux membres d'une unité d'organisation, mais que l'on souhaiterait affecter à un groupe d'utilisateurs dispersés dans l'annuaire.

N'hésitez pas à me transmettre les autres cas d'utilisation de cette méthode!