Gestire Active Directory
con script ADSI
(parte 1)
Script originalmente sviluppati da
Dr. Holger Schwichtenberg
Agenda
Le basi di ADSI
Introduzione all’architettura di ADSI
Tool ADSI
Operazioni tipiche con script ADSI
Esempi commentati di uso di ADSI
Creazione di user, group, organizational unit
Modifica delle impostazioni utente
Aggiunta di un utente ad un gruppo
Query ADSI
Le basi di ADSI
Cos‘è ADSI?
Componente COM per l‘accesso a diversi servizi di
directory
LDAP
WinNT
NDS
Utilizzabile in script e programmi (COM e .NET)
Versione attuale 2.5
Incluso in tutte le attuali versioni di Windows
È un add-on per Windows NT 4 e Win9x
ADSI SDK fornisce esempi e documentazione
Dove si utilizza ADSI?
Con Windows Script Host (WSH)
Con VBA (Word, Excel, Powerpoint ...)
VB 6
Tutti i linguaggi che possono usare COM
(C++, C)
Tutti i linguaggi .NET
Architettura ADSI
Client
Script COM
System.DirectoryService
Active Directory Service Interface
ADSI Provider
LDAP://
ADSI Provider
WinNT://
ADSI Provider
altro
Rete
AD
Exchange
NT4
NT5.x
Altro
Provider ADSI
NT Lanmanager
Windows NT 4.0 locale/domain
Windows 2000 locale
Windows XP locale
Windows Server 2003 locale
(Active Directory 2000/2003)
Novell Netware/Directory Services
Internet Information Server Metabase
LDAP (Active Directory, ADAM, Microsoft
Exchange, Lotus Notes, ecc.)
Operazioni tipiche con script ADSI
Basic ADSI Operations
Accesso ai container e oggetti di AD
Lettura di dati
Modifica di dati
Enumerazione di oggetti
Spostamento di oggetti
Creazione e cancellazione di oggetti
Accesso e lettura di attributi degli oggetti
Determinazione del percorso LDAP
LDAP://server01/CN=giorgio
malusardi,OU=it,DC=firbolg,DC=com
Acquisire l‘oggetto nello script
set obj = GetObject("LDAP://server01/CN=Giorgio
Malusardi,OU=it,DC=firbolg,DC=com")
L‘oggetto ha:
Attributi (Proprietà):
Dati che possono essere letti e scritti (es.:
Displayname, TelephoneNumber)
Metodi:
Operazioni che si possono effettuare (es.:
cancellare un oggetto)
Accesso e lettura di attributi degli oggetti
Determinazione del percorso LDAP
LDAP://server01/CN=giorgio
malusardi,OU=it,DC=firbolg,DC=com
Il nome del protocollo
è case sentive
Acquisire l‘oggetto nello script
set obj = GetObject("LDAP://server01/CN=Giorgio
Malusardi,OU=it,DC=firbolg,DC=com")
L‘oggetto ha:
Attributi (Proprietà):
Dati che possono essere letti e scritti (es.:
Displayname, TelephoneNumber)
Metodi:
Operazioni che si possono effettuare (es.:
cancellare un oggetto)
demo
ADSI Edit
Accesso e lettura di attributi degli oggetti
User
PATH="LDAP://server01/CN=giorgio
malusardi,OU=it,DC=firbolg,DC=com"
Set u = GetObject(PATH)
' --- ADSI meta data
WScript.echo "Name: " & u.name
WScript.echo "Class: " & u.Class
' --- General property page
WScript.echo "DisplayName: " & u.Fullname
WScript.echo "Description: " & u.Description
WScript.echo "TelephoneNumber: " & u.TelephoneNumber
' --- Account property page
WScript.echo "NT4-Account Name: " & u.samAccountName
Oggetti ADSI vs oggetti ADS
Organizational
Unit
ou
DisplayName
ManagedBy
Name
Class
Filter
Count
LocalityName
create()
Binding (Percorso LDAP)
Organizational
Unit
ou
DisplayName
ManagedBy
Rappresentazione
Organizational utnit it
delete()
user
cn
displayName
Name
Class
sAMAccountName
FullName
FirstName
SetPassword()
Binding (Percorso LDAP)
user
ADSI
cn
displayName
sAMAccountName
Rappresentazione
Active Directory
User xxxx
Risorse
Come trovare il corretto nome delle proprietà
Mappatura tra User Object e User Interface
http://msdn.microsoft.com/library/default.asp?url=/l
ibrary/en-us/ad/ad/
user_object_user_interface_mapping.asp
Inserire un valore nella proprietà in MMC
trovare la proprietà in ADSI Edit
city l
office physicalDeliveryOfficeName
Problemi con i Data type
Problemi con i Data type
Proprietà multivalore
Problemi con i Data type
Function ADSIGet(obj, attribut)
ADSIGet = ""
On Error Resume Next
ADSIGet = obj.Get(attribut)
If IsArray(ADSIGet) Then ADSIGet = Join(obj.Get(attribut), ";")
End Function
Proprietà multivalore
Wscript.echo ADSIGet(u,"OtherTelephone")
Wscript.echo ADSIGet(u,"Url")
Problemi con i Data type
Function ADSIGet(obj, attribut)
ADSIGet = ""
On Error Resume Next
ADSIGet = obj.Get(attribut)
If IsArray(ADSIGet) Then ADSIGet = Join(obj.Get(attribut), ";")
End Function
Proprietà multivalore
Wscript.echo ADSIGet(u,"OtherTelephone")
Wscript.echo ADSIGet(u,"Url")
Problemi con i Data type
Function ADSIGet(obj, attribut)
ADSIGet = ""
On Error Resume Next
ADSIGet = obj.Get(attribut)
If IsArray(ADSIGet) Then ADSIGet = Join(obj.Get(attribut), ";")
End Function
Proprietà multivalore
Wscript.echo ADSIGet(u,"OtherTelephone")
Wscript.echo ADSIGet(u,"Url")
INTEGER8 (Integer a 64-Bit). Intervallo a 100 nano
secondi da 1.1.1601
Problemi con i Data type
Function ADSIGet(obj, attribut)
ADSIGet = ""
On Error Resume Next
ADSIGet = obj.Get(attribut)
If IsArray(ADSIGet) Then ADSIGet = Join(obj.Get(attribut), ";")
End Function
Proprietà multivalore
Wscript.echo ADSIGet(u,"OtherTelephone")
Wscript.echo ADSIGet(u,"Url")
INTEGER8
(Integer a 64-Bit). Intervallo a 100
Int8ToDate(u.Get("AccountExpires"))
Int8ToDate(u.Get("lastLogon"))
nanosececondi
da 1.1.1601
Int8ToDate(u.Get("lastLogoff"))
Int8ToDate(u.Get("badPasswordTime"))
Int8ToDate(u.Get("pwdLastSet"))
Un errore tipico
Creare un oggetto con RDN
Errato:
objCON.Create("organizationalunit", "DEV")
Corretto:
objCON.Create("organizationalunit", "ou=DEV")
demo
Leggere i dati di xxx
Modificare le proprietà
User
u.DisplayName = "giorgio malusardi"
u.put "Description", "Evangelist"
u.TelephoneNumber = "++39 2 70392020"
u.EmailAddress = "[email protected]"
Dim tel(1)
tel(0) = "++39 2 70392020"
tel(1) = "++39 2 70397000"
u.PutEx 2, "otherTelephone", tel
u.SetInfo
Modificare le proprietà
User
u.DisplayName = "giorgio malusardi"
u.put "Description", "Evangelist"
u.TelephoneNumber = "++39 2 70392020"
u.EmailAddress = "[email protected]"
Dim tel(1)
tel(0) = "++39 2 70392020"
tel(1) = "++39 2 70397000"
u.PutEx 2, "otherTelephone", tel
u.SetInfo
1 = Rimuove i valori
2 = Rimpiazza i valori
3 = Aggiunge i valori
4 = Cancella i valori
Enumerazione di oggetti
Users
Tutti gli user in un container
Const PATH = "LDAP://server01/
OU=it,DC=firbolg,DC=com"
Set c = GetObject(PATH)
Wscript.Echo "# of Objects: " & c.Count
For Each u In c
WScript.echo u.ADsPath & " : " &
u.Get("SAMAccountname")
Next
Enumerazione di oggetti
Users
Tutti gli user in un container
Const PATH = "LDAP://server01/
OU=it,DC=firbolg,DC=com"
Set c = GetObject(PATH)
c.Filter = Array("User", "Group")
Wscript.Echo "# of Objects: " & c.Count
For Each u In c
WScript.echo u.ADsPath & " : " & _
u.Get("SAMAccountname")
Next
Creazione di un oggettto
OU
Const CONTAINER = "LDAP://server01/DC=firbolg,DC=com"
Const MANAGER = "CN=giorgio
malusardi,OU=it,DC=firbolg,DC=com"
Const DESC = "Firbolg - IT Managers"
Const LOCALITY = "Milano"
Const OU = "Managers"
' --- Get container
Set objCON = GetObject(CONTAINER)
' --- Create new OU
Set objOU = objCON.Create("organizationalunit", "ou=" &
OU)
' --- Set properties
objOU.LocalityName = LOCALITY
objOU.Description = DESC
objOU.Put "ManagedBy", MANAGER
objOU.SetInfo
Creazione di un oggettto
OU
Const CONTAINER = "LDAP://server01/DC=firbolg,DC=com"
Const MANAGER = "CN=giorgio malusardi,OU=it,DC=firbolg,DC=com"
Const DESC = "Firbolg - IT Managers"
Const LOCALITY = "Milano"
RDN completo,
Const OU = "Managers"
non solo il nome
' --- Get container
Set objCON = GetObject(CONTAINER)
' --- Create new OU
Set objOU = objCON.Create("organizationalunit", "ou=" & OU)
' --- Set properties
objOU.LocalityName = LOCALITY
objOU.Description = DESC
objOU.Put "ManagedBy", MANAGER
objOU.SetInfo
Creazione di un oggetto
User
Function ADSIADS_CreateUser(CONTAINER, USER, PASSWORD)
Dim c, u
' --- Bind to container
Set c = GetObject(CONTAINER)
' --- Create user
Set u = c.Create("user", "cn=" & USER)
' --- Set required properties
u.Put "samAccountName", CStr(USER)
u.SetInfo
' --- Set password
WScript.echo "User has been created: " & u.ADsPath
u.SetPassword PASSWORD
WScript.echo "Password has been set!"
' --- Enable Account
u.AccountDisabled = False
u.SetInfo
' --- Return new user object
Set ADSIADS_CreateUser = u
End Function
Attributi utente
' --- Account Property Page
' UPN
u.userPrincipalName = "giorgio malusardi"
' User must change password at next login
u.pwdLastSet = 0
' SmartCard required
Const ADS_UF_SMARTCARD_REQUIRED = 262144
u.userAccountControl = u.userAccountControl OR
ADS_UF_SMARTCARD_REQUIRED
' Account expires
u.AccountExpirationDate = "01/01/2005"
' User cannot change password
' difficult!!! see demo
' --- Organization Property Page
' Manager: AD attribute "Manager", type "DN"
u.manager = "cn=paolo rossi,OU=it,dc=firbolg,dc=com"
Muovere oggetti
Muovere un oggetto in una diversa OU
Const TARGETCONTAINER =
"LDAP://server01/ou=Managers,DC=firbolg,DC=com"
Const SOURCEOBJEKT = "LDAP://server01/cn=giorgio
malusardi,OU=it,DC=firbolg,DC=com"
Const TARGETRDN = "cn=giorgio malusardi"
Dim objContainer ' As IADsContainer
Set objContainer = GetObject(TARGETCONTAINER)
objContainer.MoveHere SOURCEOBJEKT, TARGETRDN
WScript.Echo "User Moved"
Muovere oggetti
Muovere un oggetto in una diversa OU
Const TARGETCONTAINER =
"LDAP://server01/ou=Managers,DC=firbolg,DC=com"
Const SOURCEOBJEKT = "LDAP://server01/cn=giorgio
Si puo‘ usare per
malusardi,OU=it,DC=firbolg,DC=com"
RINOMINARE oggetti
Const TARGETRDN = "cn=giorgio malusardi"
Dim objContainer ' As IADsContainer
Set objContainer = GetObject(TARGETCONTAINER)
objContainer.MoveHere SOURCEOBJEKT, TARGETRDN
WScript.Echo "User Moved"
demo
Creare utenti da un database
Architettura ADSI
Read only
ActiveX Data Object (ADO)
Script COM
OLE DB
OLE DB Provider
per ADSI
Read/Write
OLE DB Provider
SQL
OLE DB Provider
Altro
Rete
Active Directory Service Interface
ADSI Provider
LDAP://
ADSI Provider
WinNT://
ADSI Provider
NDS://
Rete
AD
NT4
Exchange
NT5.x
Altro
SQL Server
Altro DB
Sintassi delle query ADSI
ADO su ADSI usa un OLE DB-Provider
Solo per LDAP Provider
Read-only
Sintassi LDAP (LDAP Search Filter, RFC 2254)
<LDAP://server01/dc=firbolg,dc=com>;(&(obje
ctCategory=person)(objectClass=user)(name=f
*));name,adspath"
Sintassi SQL
"Select adspath,SamAccountname from
'LDAP://server01/dc=firbolg,dc=com' where
objectclass='user' and
objectCategory='person' and name = 'f*'"
Sintassi delle query LDAP
Operatori:
AND: e commerciale (&)
OR: barra verticale (|)
NOT: punto esclamativo (!)
Esiste il valore: (!(MyCorpSpecial=*)
Comparazione:
=, <=, >=
> e < non sono consentiti
(&(Attribute>=Value)(!(Attribute=Value)))
Sintassi delle query LDAP
Operatori:
AND: e commerciale (&)
OR: barra verticale (|)
Generare
query
conesclamativo
"Saved Queries"
nella console
NOT:
punto
(!)
Windows Server
Users and Computers"
Esiste il2003
valore:"AD
(!(MyCorpSpecial=*)
Comparazione:
=, <=, >=
> e < non sono consentiti
(&(Attribute>=Value)(!(Attribute=Value)))
Alcuni esempi di query LDAP
Tutti gli oggetti computer senza descrizione:
(&(objectCategory=computer)(!description=*))
Tutti gli utenti in lockout
(&(objectCategory=person)(objectClass=user)
(userAccountControl:1.2.840.113556.1.4.803:=2))
Tutti gli utenti con impostato "Password Never
Expires"
(&(objectCategory=person)(objectClass=user)
(userAccountControl:1.2.840.113556.1.4.803:=655
36))
Alcuni esempi di query LDAP
Utenti che non hanno fatto logon negli ultimi x giorni
d = DateAdd("h", -days, Now()) : i =
DateToInt8(d)(&(objectCategory=person)(ob
jectClass=user)(lastLogon<=" & i & "))
Utenti che non hanno cambiato la password negli
utlimi x giorni
&(objectCategory=person)(objectClass=user
)(pwdLastSet<=" & i & "))
Utenti creati dopo una certa data (es. 11/10/2004)
&objectCategory=person)(objectClass=user)
(whenCreated>=20041110000000.0Z))"
Risorse della Community
Community Resources
http://www.microsoft.com/communities/default.mspx
Most Valuable Professional (MVP)
http://www.microsoft.com/communities/mvp
Newsgroups
http://communities2.microsoft.com/communities
/newsgroups/en-us/default.aspx
User Groups
http://www.microsoft.com/communities/usergroups
default.mspx
© 2003-2004 Microsoft Corporation. All rights reserved.
This presentation is for informational purposes only. Microsoft makes no warranties, express or implied, in this summary.