在 Azure 中将应用程序池的标识设置为 LocalSystem
有没有办法在 ServiceDefinition.csdef
或其他地方执行此操作,而无需转到 IIS 并手动调整?
我尝试了 executionContext="elevated"
的 webrole,但不起作用。
更新
如果您在 Azure IIS 上安装“IIS 6 Metabase Compatibility”,下面显示的错误将会消失。
这引发了另一个问题,如何在 Azure 上的部署阶段自动安装“IIS 6 Metabase Compatibility”。
@astaykov,我喜欢评论,但下面的代码太大,所以我使用这个地方。
我使用 Wade Wagner 编写的相同代码:
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();
}
我可以在 appPoolName
处获取正确的值,但这里发生了错误: using (DirectoryEntry azureAppPool = appPools.Children.Find(appPoolName, "IIsApplicationPool"))
我正在到处搜索解决方案,但仍然找不到线索 以下错误来自 IIS 事件:
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()
有什么想法吗?
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?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
executionContext="elevated" 只会将您的 RoleEntryPoint 作为本地 SYSTEM 帐户运行,但它不是 IIS 池标识。
您可能需要查看 韦德·瓦格纳的这篇博文。他在那里描述的内容可以在您的 OnStart 方法中与executionContext="elevated" 一起运行(因为只有管理员可以更改池身份)。如果这对本地系统不起作用,您可以为 RDP 创建一个用户,它将添加到管理员组中,并且您可以将 iis 应用程序池标识设置为该用户。
更新
嗯,我使用了以下方法(类似)并且效果很好:
你能尝试一下吗?请注意,它不适用于本地系统帐户,因为它不是真实帐户,我们不能以这种方式设置它(至少我不知道如何做到这一点,但对于 RDP 的特定帐户,它可以正常工作)。
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:
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).
创建start.cmd:
Create start.cmd: