title: How to get the defaultNamingContext in .NET Core?
body: <p>I'm trying to do ActiveDirectory/LDAP-Authentication in .NET Core. <br />
  However, there is no System.DirectoryServices in <strong>.NET Core (NetStandard 1.6)</strong>.<br /> 
  So instead, I use Novell.Directory.Ldap, which works fine, as long as you know the rootDSE. </p>
  
  <p>Normally, I would get the ActiveDirectory RootDSE-defaultNamingContext like this:</p>
  
  <pre><code>public static string GetRootDSE()
  {
      DirectoryEntry rootDSE = new DirectoryEntry("LDAP://rootDSE");
      string defaultNamingContext = rootDSE.Properties["defaultNamingContext"].Value;
      return defaultNamingContext:
  }
  </code></pre>
  
  <p>However, since there is no System.DirectoryServices, I can't do that. <br />
  Novell.Directory.Ldap seems not to have an equivalent function for that, or at the very least I can't find it.</p>
  
  <p>Now for example in VBScript, you could get the defaultNamingContext like this:</p>
  
  <pre><code>Set objRootDSE = GetObject("LDAP://rootDSE")
  strADsPath = "LDAP://" &amp; objRootDSE.Get("defaultNamingContext")
  Set objDomain = GetObject(strADsPath)
  </code></pre>
  
  <p>So I tried to use the same COM-Object in C# (since there is no VB.NET for .NET Core, I can't call the VB.NET runtime). <br />
  This is what I have managed to get so far:</p>
  
  <pre><code>[System.Runtime.InteropServices.DllImport("Activeds", ExactSpelling = true, 
  EntryPoint = "ADsGetObject",
  CharSet = System.Runtime.InteropServices.CharSet.Unicode)]
  public static extern int ADsGetObject(string path
      , [System.Runtime.InteropServices.In, System.Runtime.InteropServices.Out] ref System.Guid iid
      , [System.Runtime.InteropServices.Out, System.Runtime.InteropServices.MarshalAs(System.Runtime.InteropServices.UnmanagedType.Interface)] out object ppObject
  );
  
  
  public static void Test()
  {
      dynamic ppObject;
  
      // System.Guid IID_IDirectorySearch = new System.Guid("{ 0x109BA8EC, 0x92F0, 0x11D0, { 0xA7, 0x90, 0x00, 0xC0, 0x4F, 0xD8, 0xD5, 0xA8 } }");
      // System.Guid IID_IADsContainer = new System.Guid("{ 0x001677D0, 0xFD16, 0x11CE, { 0xAB, 0xC4, 0x02, 0x60, 0x8C, 0x9E, 0x75, 0x53 } }");
      System.Guid IID_IADs = new System.Guid("{ 0xFD8256D0, 0xFD15, 0x11CE, { 0xAB, 0xC4, 0x02, 0x60, 0x8C, 0x9E, 0x75, 0x53 } }");
      ADsGetObject("LDAP://rootDSE", ref IID_IADs, out ppObject);
      System.Console.WriteLine(ppObject);
  
      object objDSE;
      // System.IntPtr objDSE;
      // https://msdn.microsoft.com/en-us/library/aa705950(v=vs.85).aspx
      // https://msdn.microsoft.com/en-us/library/aa746347(v=vs.85).aspx
      // HRESULT Get( [in]  BSTR    bstrName, [out] VARIANT *pvProp);
      // ppObject.Get("defaultNamingContext", out objDSE);
  
      System.IntPtr bstr = System.Runtime.InteropServices.
        Marshal.StringToBSTR("defaultNamingContext");
      ppObject.Get(bstr, out objDSE);
      System.Console.WriteLine(objDSE);
  }
  </code></pre>
  
  <p>I get the COM-Object ("ppObject"), and it seems to work fine until I call Get on ppObject. <br />
  There I get <code>"Not Implemented-Exception: Method or process is not implemented."</code>
  <br />What am I doing wrong ? </p>
  
  <p>Also, if anybody has a better way of getting the RootDSE in .NET Core, then I'm all ears.</p>
  
  <p>PS: <br />
  I know this will only work on Windows - I just set it to manually configure on Linux. </p>