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.