Rilevamento dello schema master
Dominio di Active Directory Services dispone di un sistema di aggiornamento multimaster. Ogni controller di dominio contiene una copia scrivibile della directory. Gli aggiornamenti dello schema vengono propagati a tutti i domini appartenenti alla stessa struttura ad albero o foresta. Poiché è difficile riconciliare gli aggiornamenti in conflitto con lo schema, gli aggiornamenti dello schema possono essere eseguiti solo in un singolo server. Il server con il diritto di eseguire gli aggiornamenti può cambiare, ma solo un server avrà tale diritto in qualsiasi momento. Questo server è denominato master dello schema. Il primo controller di dominio installato in un'organizzazione è, per impostazione predefinita, il master dello schema.
Le modifiche dello schema possono essere apportate solo a livello master dello schema. Per rilevare il controller di dominio master dello schema, seguire questa procedura.
Rilevamento dello schema del controller di dominio master
- Leggere l'attributo fsmoRoleOwner del contenitore dello schema in qualsiasi controller di dominio. L'attributo fsmoRoleOwner restituisce il nome distinto (DN) dell'oggetto nTDSDSA per il master dello schema.
- Eseguire il binding all'oggetto nTDSDSA di cui è stato appena recuperato il DN. L'elemento padre di questo oggetto è l'oggetto server per il controller di dominio contenente il master dello schema.
- Ottenere l'oggetto ADsPath per l'elemento padre dell'oggetto nTDSDSA . L'elemento padre è un oggetto server.
- Eseguire l'associazione all'oggetto server.
- Ottiene l'attributo dNSHostName dell'oggetto server. Si tratta del nome DNS del controller di dominio che contiene il master dello schema.
- Specificare il nome DNS del master dello schema come server e il DN come DN del contenitore dello schema da associare al master dello schema. Ad esempio, se il server è "dc1.fabrikam.com" e il DN del contenitore dello schema è "cn=schema,cn=configuration,dc=fabrikam,dc=com", l'ADsPath sarà il seguente.
LDAP://dc1.fabrikam.com/cn=schema,cn=configuration,dc=fabrikam,dc=com
È consigliabile trovare il master dello schema e associarlo per apportare modifiche allo schema. Tuttavia, è possibile spostare il master dello schema in un altro server.
Per rendere un altro server il master dello schema, un utente con privilegi adeguato può:
Usare lo snap-in MMC gestione schemi.
Nota
Lo snap-in MMC dello schema di Active Directory deve essere registrato manualmente. Per registrare lo snap-in Schema, è necessario eseguire il comando seguente dal prompt dei comandi nella directory di Windows System32.
regsvr32.exe schmmgmt.dll
Usare l'utilità della riga di comando NTDSUTIL.
Usare un'applicazione di terze parti (un'applicazione che rilascia la scrittura LDAP appropriata).
Per diventare il master dello schema a livello di codice, un'applicazione in esecuzione nel contesto di un utente con privilegi appropriato può rilasciare una scrittura LDAP dell'attributo operativo diventaSchemaMaster nel rootD edizione Standard in tale controller di dominio. In questo modo viene avviato un trasferimento atomico del master dello schema direttamente dal titolare corrente al controller di dominio locale.
Nell'esempio di codice seguente viene trovato il master dello schema. La funzione seguente viene associata al contenitore dello schema nel computer che è il master dello schema.
HRESULT BindToSchemaMaster(IADsContainer **ppSchemaMaster)
{
HRESULT hr = E_FAIL;
// Get rootDSE and the schema container DN.
IADs *pObject = NULL;
IADs *pTempSchema = NULL;
IADs *pNTDS = NULL;
IADs *pServer = NULL;
BSTR bstrParent;
LPOLESTR szPath = new OLECHAR[MAX_PATH];
VARIANT var, varRole,varComputer;
hr = ADsOpenObject(L"LDAP://rootDSE",
NULL,
NULL,
ADS_SECURE_AUTHENTICATION, // Use Secure Authentication.
IID_IADs,
(void**)&pObject);
if (hr == S_OK)
{
hr = pObject->Get(CComBSTR("schemaNamingContext"), &var);
if (hr == S_OK)
{
wcscpy_s(szPath,L"LDAP://");
wcscat_s(szPath,var.bstrVal);
hr = ADsOpenObject(szPath,
NULL,
NULL,
ADS_SECURE_AUTHENTICATION, // Use Secure Authentication.
IID_IADs,
(void**)&pTempSchema);
if (hr == S_OK)
{
/*
Read the fsmoRoleOwner attribute to identify which server is
the schema master.
*/
hr = pTempSchema->Get(CComBSTR("fsmoRoleOwner"), &varRole);
if (hr == S_OK)
{
// The fsmoRoleOwner attribute returns the nTDSDSA object.
// The parent is the server object.
// Bind to NTDSDSA object and get parent.
wcscpy_s(szPath,L"LDAP://");
wcscat_s(szPath,varRole.bstrVal);
hr = ADsOpenObject(szPath,
NULL,
NULL,
ADS_SECURE_AUTHENTICATION,
IID_IADs,
(void**)&pNTDS);
if (hr == S_OK)
{
hr = pNTDS->get_Parent(&bstrParent);
if (hr == S_OK)
{
/*
Bind to server object and get the DNS name of
the server.
*/
wcscpy_s(szPath,bstrParent);
hr = ADsOpenObject(szPath,
NULL,
NULL,
ADS_SECURE_AUTHENTICATION,
IID_IADs,
(void**)&pServer);
if (hr == S_OK)
{
// Get the dns name of the server.
hr = pServer->Get(CComBSTR("dNSHostName"),
&varComputer);
if (hr == S_OK)
{
wcscpy_s(szPath,L"LDAP://");
wcscat_s(szPath,varComputer.bstrVal);
wcscat_s(szPath,L"/");
wcscat_s(szPath,var.bstrVal);
hr = ADsOpenObject(szPath,
NULL,
NULL,
ADS_SECURE_AUTHENTICATION,
IID_IADs,
(void**)ppSchemaMaster);
if (FAILED(hr))
{
if (*ppSchemaMaster)
{
(*ppSchemaMaster)->Release();
(*ppSchemaMaster) = NULL;
}
}
}
VariantClear(&varComputer);
}
if (pServer)
pServer->Release();
}
SysFreeString(bstrParent);
}
if (pNTDS)
pNTDS->Release();
}
VariantClear(&varRole);
}
if (pTempSchema)
pTempSchema->Release();
}
VariantClear(&var);
}
if (pObject)
pObject->Release();
return hr;
}
Nell'esempio di codice seguente viene visualizzato il nome DNS per il computer che è il master dello schema.
On Error Resume Next
'''''''''''''''''''
' Bind to the rootDSE
''''''''''''''''''''
sPrefix = "LDAP://"
Set root= GetObject(sPrefix & "rootDSE")
If (Err.Number <> 0) Then
BailOnFailure Err.Number, "on GetObject method"
End If
'''''''''''''''''''
' Get the DN for the schema
''''''''''''''''''''
sSchema = root.Get("schemaNamingContext")
If (Err.Number <> 0) Then
BailOnFailure Err.Number, "on Get method"
End If
'''''''''''''''''''
' Bind to the schema container
''''''''''''''''''''
Set Schema= GetObject(sPrefix & sSchema )
If (Err.Number <> 0) Then
BailOnFailure Err.Number, "on GetObject method to bind to schema"
End If
''''''''''''''''''''
' Read the fsmoRoleOwner attribute to see which server is the
' schema master.
''''''''''''''''''''
sMaster = Schema.Get("fsmoRoleOwner")
If (Err.Number <> 0) Then
BailOnFailure Err.Number, "on IADs::Get method for fsmoRoleOwner"
End If
''''''''''''''''''''
' The fsmoRoleOwner attribute returns the nTDSDSA object.
' The parent is the server object.
' Bind to NTDSDSA object and get the parent object.
''''''''''''''''''''
Set NTDS = GetObject(sPrefix & sMaster)
If (Err.Number <> 0) Then
BailOnFailure Err.Number, "on GetObject method for NTDS"
End If
sServer = NTDS.Parent
If (Err.Number <> 0) Then
BailOnFailure Err.Number, "on IADs::get_Parent method"
End If
''''''''''''''''''''
' Bind to server object
' and get the reference to the computer object.
''''''''''''''''''''
Set Server = GetObject(sServer)
If (Err.Number <> 0) Then
BailOnFailure Err.Number, "on GetObject method for " & sServer
End If
sComputer = Server.Get("dNSHostName")
''''''''''''''''''''
' Display the DNS name for the computer.
''''''''''''''''''''
strText = "Schema master has the following DNS name: "& sComputer
WScript.echo strText
''''''''''''''''''''
' Display subroutines
''''''''''''''''''''
Sub BailOnFailure(ErrNum, ErrText)
strText = "Error 0x" & Hex(ErrNum) & " " & ErrText
MsgBox strText, vbInformation, "ADSI Error"
WScript.Quit
End Sub