"Unknown error (0x80005000)" trying to read remote IIS 6 Metabase with DirectoryEntry and Impersonation (C#)


(EDIT) The plot thickens: The same code (with no need for impersonation!) runs successfully from a Windows 7 client, but NOT from a Windows 2008 R2 client! Here's the code in question. (Original message follows code below.)

var entry = new DirectoryEntry("IIS://" + tbHost.Text + "/W3SVC", tbUsername.Text, tbPassword.Password);
foreach (DirectoryEntry site in entry.Children)
    Console.Write("Site {0}\n", site.Name);
    foreach (PropertyValueCollection prop in site.Properties)
        Console.Write("{0}={1}\n", prop.PropertyName, prop.Value);

I read here that, for the IIS provider, you can't pass credentials when creating the DirectoryEntry object. You have to do impersonation. So I tried the following code, but I still get a COMException with a text of "Unknown error (0x80005000)" when I try to read a property, just as I did when I previously tried to pass username and password for the DirectoryEntry constructor. Here's the rundown:

  • LogonUser() succeeds, credentials are OK. I had banged by head a little before I found out I had to use LOGON32_LOGON_NEW_CREDENTIALS instead of LOGON32_LOGON_INTERACTIVE.
  • The remote machine is not in the same domain. Actually, it isn't in a domain at all. In fact, I put its name in the client's hosts file so I could get to it by name.
  • Running Metabase Explorer in the target machine shows me the key I want to read does exist. (See picture at end of the post.)


const int LOGON32_LOGON_NETWORK = 3;

const int LOGON32_PROVIDER_WINNT50 = 3;
const int LOGON32_PROVIDER_WINNT40 = 2;
const int LOGON32_PROVIDER_WINNT35 = 1;

[DllImport("advapi32.dll", SetLastError = true, CharSet = CharSet.Unicode)]
public static extern int LogonUser(String lpszUserName, string lpszDomain, string lpszPassword, int dwLogonType, int dwLogonProvider, ref IntPtr phToken);

[DllImport("kernel32.dll", CharSet = CharSet.Auto)]
public extern static bool CloseHandle(IntPtr handle);

extern static int GetLastError();


IntPtr myToken = IntPtr.Zero;
if (LogonUser(tbUsername.Text, tbHost.Text, tbPassword.Password, LOGON32_LOGON_NEW_CREDENTIALS, LOGON32_PROVIDER_DEFAULT, ref myToken) == 0)
    int causingError = GetLastError();
    throw new System.ComponentModel.Win32Exception(causingError);

WindowsImpersonationContext myMission = WindowsIdentity.Impersonate(myToken);

string mbUri = "IIS://" + tbHost.Text + "/MimeMap";
DirectoryEntry myDirEntry = new DirectoryEntry(mbUri);
Console.Write("{0}\n", myDirEntry.Properties["KeyType"]);

if (myToken != IntPtr.Zero)

enter image description here

asked on Stack Overflow Apr 12, 2011 by JCCyC • edited Apr 13, 2011 by JCCyC

2 Answers


Got it. All I had to do was go to Server Management → Roles → Web Server (IIS) and enable the service Management Tools → IIS 6 Management Compatibility → IIS 6 Metabase Compatibility. See pic below.

It's in the client machine, so you don't really have to have anything else from IIS installed.

I wonder how that will work for a non-server Windows (XP, Vista, 7).

enter image description here

answered on Stack Overflow Apr 14, 2011 by JCCyC

You can also open Powershell as an administrator and use the following to enable IIS 6 Management Compatibility:

Import-Module Servermanager
Add-WindowsFeature Web-Mgmt-Compat -IncludeAllSubFeature
Get-WindowsFeature #Show list of all installed features
answered on Stack Overflow Oct 22, 2013 by Greg Bray

User contributions licensed under CC BY-SA 3.0