Is there a way to do this in ServiceDefinition.csdef
or other place without go to the IIS and adjust by hand?
I tried executionContext="elevated"
for webrole, not working.
UPDATE
If you install "IIS 6 Metabase Compatibility" on Azure IIS, the error I shown below will gone.
This raise another issue, howto install "IIS 6 Metabase Compatibility" automatically at deployment stage on Azure.
@astaykov, I like to comment but the code below too big, so I use this place.
I use the same code that wrote by Wade Wagner as:
public override bool OnStart()
{
// http://code.msdn.microsoft.com/windowsazure/CSAzureChangeAppPoolIdentit-27099828
// This variable is used to iterate through list of Application pools
string metabasePath = "IIS://localhost/W3SVC/AppPools";
string appPoolName;
using (ServerManager serverManager = new ServerManager())
{
//Get the name of the appPool that is created by Azure
appPoolName = serverManager.Sites[RoleEnvironment.CurrentRoleInstance.Id + "_Web"].Applications.First().ApplicationPoolName;
// Get list of appPools at specified metabasePath location
using (DirectoryEntry appPools = new DirectoryEntry(metabasePath))
{
// From the list of appPools, Search and get the appPool that is created by Azure
using (DirectoryEntry azureAppPool = appPools.Children.Find(appPoolName, "IIsApplicationPool"))
{
if (azureAppPool != null)
{
// Refer to:
// http://www.microsoft.com/technet/prodtechnol/WindowsServer2003/Library/IIS/e3a60d16-1f4d-44a4-9866-5aded450956f.mspx?mfr=true,
// http://learn.iis.net/page.aspx/624/application-pool-identities/
// for more info on AppPoolIdentityType
azureAppPool.InvokeSet("AppPoolIdentityType", new Object[] { 0 }); // MD_APPPOOL_IDENTITY_TYPE_LOCALSYSTEM
// Write above settings to IIS metabase
azureAppPool.Invoke("SetInfo", null);
// Commit the above configuration changes that are written to metabase
azureAppPool.CommitChanges();
}
}
}
}
RoleInRun = true;
TaskInRun = false;
return base.OnStart();
}
I can get rigth value at appPoolName
, But error happened here:
using (DirectoryEntry azureAppPool = appPools.Children.Find(appPoolName, "IIsApplicationPool"))
I am searching solutions everywhere but still cannot find a clue Error below, from IIS events:
Application: WaIISHost.exe
Framework Version: v4.0.30319
Description: The process was terminated due to an unhandled exception.
Exception Info: System.Runtime.InteropServices.COMException
Stack:
at System.DirectoryServices.DirectoryEntry.Bind(Boolean)
at System.DirectoryServices.DirectoryEntry.Bind()
at System.DirectoryServices.DirectoryEntry.get_IsContainer()
at System.DirectoryServices.DirectoryEntries.Find(System.String, System.String)
at GimmeRank.Redirector.WebRole.OnStart()
at Microsoft.WindowsAzure.ServiceRuntime.RoleEnvironment.InitializeRoleInternal(Microsoft.WindowsAzure.ServiceRuntime.Implementation.Loader.RoleType)
at Microsoft.WindowsAzure.ServiceRuntime.Implementation.Loader.RoleRuntimeBridge.<InitializeRole>b__0()
at System.Threading.ExecutionContext.runTryCode(System.Object)
at System.Runtime.CompilerServices.RuntimeHelpers.ExecuteCodeWithGuaranteedCleanup(TryCode, CleanupCode, System.Object)
at System.Threading.ExecutionContext.Run(System.Threading.ExecutionContext, System.Threading.ContextCallback, System.Object, Boolean)
at System.Threading.ExecutionContext.Run(System.Threading.ExecutionContext, System.Threading.ContextCallback, System.Object)
at System.Threading.ThreadHelper.ThreadStart()
Anyideas?
executionContext="elevated" will only run your RoleEntryPoint as the local SYSTEM account, but it is not the IIS pool identity.
You may want to check out this blog post by Wade Wagner. What he describes there, can be run in your OnStart method along with executionContext="elevated" (because only admin can change pool identity). If that does not work for Local System, you can create a user for RDP, it will added in the Administrators group, and you can set the iis app pool identity to that user.
UPDATE
Hm, I used the following method (which is similar) and it worked fine:
private void SetAppPoolIdentity()
{
string appPoolUser = "myRDP_admin_user";
string appPoolPass = "my_super_secure_password";
Action<string> iis7fix = (appPoolName) =>
{
bool committed = false;
while (!committed)
{
try
{
using (ServerManager sm = new ServerManager())
{
var applicationPool = sm.ApplicationPools[appPoolName];
applicationPool.ProcessModel.IdentityType = ProcessModelIdentityType.SpecificUser;
applicationPool.ProcessModel.UserName = appPoolUser;
applicationPool.ProcessModel.Password = appPoolPass;
sm.CommitChanges();
committed = true;
}
}
catch (FileLoadException fle)
{
Trace.TraceError("Trying again because: " + fle.Message);
}
}
};
// ServerManager in %WinDir%System32InetSrvMicrosoft.Web.Administration.dll
var sitename = RoleEnvironment.CurrentRoleInstance.Id + "_Web";
var appPoolNames = new ServerManager().Sites[sitename].Applications.Select(app => app.ApplicationPoolName).ToList();
appPoolNames.ForEach(iis7fix);
}
Could you try that? Note that it will not work with Local System account, as it is not real account and we cannot set it this way (at least I don't know how to do it, but with specific account for RDP it works fine).