Justin Justin - 1 year ago 79
ASP.NET (C#) Question

Access denied reading Perfmon counters from a remote machine (Asp.Net)

I'm trying to create a simple Asp.Net page to read Perfmon counters from a remote machine.

When I run the page using the Visual Studio development web server all is well, however when I attempt to run the same page when its hosted on IIS I get an access denied error on the line that instantiates the Perfmon counter:

PerformanceCounter freeSpaceCounter = new PerformanceCounter("LogicalDisk", "Free Megabytes", "D:", "RemoteMachine12");

This is the exception I get:

Exception Details: System.ComponentModel.Win32Exception: Access is denied

I've tried using both anonymous access (with myself as the anonymous user) and Integrated Windows Authentication - both dont work. Clearly some other account is be used to read the PerfMon counters (like the ASPNET account). How do I get my page to access the PerfMon counters using my account rather than that account?

Answer Source

The problem you have here is that IIS runs under the context of a local account (by default). This local account doesn't exist on the remote machine, and so can't connect to get the performance counters. When you use the VS development web server it runs under your own local account and so everything works.

If you're in a domain environment you can configure the IIS application pool to run as a domain account with access to both machines, and everything will work, however you may want more control over this.

You could either use basic authentication, with the application configured for impersonation (or if you're using IIS7 having the pool configured to run under the authenticated account) or you impersonate just before you read the counter.

There are a couple of ways to impersonate - the safest is to configure IIS to use integrated authentication and then wrap the call up

PerformanceCounter freeSpaceCounter = null;
using (((WindowsIdentity)HttpContext.Current.User.Identity).Impersonate())
    freeSpaceCounter = new PerformanceCounter("LogicalDisk", 
                               "Free Megabytes", "D:", "RemoteMachine12");

If you don't want authentication then you'll have to configure the app pool, or hard code a username and password in your application - this should be the last resort, see KB306158