[Sample of Feb 26th] Write / add SPN to user or computer account in Active Directory
![]() | ![]() | |
![]() | ![]() |
Sample Download: https://code.msdn.microsoft.com/CSDsWriteAccountSPN-95c31397
Today’s code sample is related to Active Directory. It demonstrates how to write/add Service Principal Name (SPN) to any user or computer account object in Active Directory. This sample must be run on domain environment and under the Domain Admin privileges.
The sample was written by Microsoft Support Escalation Engineer: Shaleen Thapa.
You can find more code samples that demonstrate the most typical programming scenarios by using Microsoft All-In-One Code Framework Sample Browser or Sample Browser Visual Studio extension. They give you the flexibility to search samples, download samples on demand, manage the downloaded samples in a centralized place, and automatically be notified about sample updates. If it is the first time that you hear about Microsoft All-In-One Code Framework, please watch the introduction video on Microsoft Showcase, or read the introduction on our homepage https://1code.codeplex.com/.
Introduction
This sample application demonstrates how to write/add Service Principal Name (SPN) to any user or computer account object in Active Directory. This sample must be run on domain environment and under the Domain Admin privileges.
Running the Sample
You can execute this sample by creating the exe via Visual Studio but it must be running under the domain admin credentials. Also this code must be running either on Domain controller or any one of the member servers.
Using the Code
We are using first DsCrackSpn to parse its SPN into its component strings. Then we need to bind to the Domain Controller using DsBind. Now we would require constructing the SPN using DsGetSpn by specifying its type. Once we get the pointer to the SPN, we can write it to the object by calling DsWriteAccountSpn.
// Initial call to DsCrackSpn should result in BUFFER_OVERFLOW...
uint crackSpnResult = DsCrackSpn(spn, ref serviceClassSize, sTemp, ref serviceNameSize,
sTemp, ref instanceNameSize, sTemp, out port);
// Check for buffer overflow
if (crackSpnResult == ERROR_BUFFER_OVERFLOW)
{
// Resize our SB's
StringBuilder serviceClass = new StringBuilder(serviceClassSize);
StringBuilder serviceName = new StringBuilder(serviceNameSize);
StringBuilder instanceName = new StringBuilder(instanceNameSize);
// Crack this spn using DsCrackSpn
crackSpnResult = DsCrackSpn(spn, ref serviceClassSize, serviceClass, ref serviceNameSize,
serviceName, ref instanceNameSize, instanceName, out port);
// If Success
if (crackSpnResult == NO_ERROR)
{
string[] hostArray = { serviceName.ToString() };
ushort[] portArray = { port };
ushort spnCount = 1;
IntPtr spnArrayPointer = new IntPtr();
Int32 spnArrayCount = 0;
// Call to DsBind to get handle for Directory
System.IntPtr hDS;
uint result = DsBind(domainControllerName, dnsDomainName, out hDS);
if (result != NO_ERROR)
{
Console.WriteLine("DSBind Failed.");
return;
}
// Call to DsgetSpn to construct an spn
uint getSPNResult = DsGetSpn(DS_SPN_NAME_TYPE.DS_SPN_DNS_HOST, serviceClass.ToString(),
null, port, spnCount, hostArray, portArray, ref spnArrayCount, ref spnArrayPointer);
if (getSPNResult == NO_ERROR)
{
// Call the CSDsWriteAccountSPN for writing this spn to the object
uint dsWriteSpnResult = DsWriteAccountSpn(hDS, DS_SPN_WRITE_OP.DS_SPN_ADD_SPN_OP,
servicePrincipalName, spnArrayCount, spnArrayPointer);
if (dsWriteSpnResult == NO_ERROR)
{
Console.WriteLine("DsWriteAccountSpn Succeed. Please check the user/Computer object for ServicePrincipalName.");
Console.ReadKey();
}
else
{
Console.WriteLine("DsWriteAccountSpn Failed.");
return;
}
}
else
{
Console.WriteLine("DsGetSPN Failed.");
return;
}
}
else
{
Console.WriteLine("DsCrackSpn Failed.");
return;
}
}
More Information
DsWriteAccountSpn
https://msdn.microsoft.com/en-us/library/windows/desktop/ms676056(v=vs.85).aspx
DsGetSpn
https://msdn.microsoft.com/en-us/library/windows/desktop/ms675993(v=vs.85).aspx
DsCrackSpn
https://msdn.microsoft.com/en-us/library/windows/desktop/ms675971(v=vs.85).aspx
DsBind
https://msdn.microsoft.com/en-us/library/windows/desktop/ms675931(v=vs.85).aspx