我有一个ASP .NET WEb Forms项目,我想执行power-shell脚本来更新hosts
文件。
private void ExecutePowerShellScript(string scriptToExecute)
{
using (PowerShell powershelInstance = PowerShell.Create())
{
var authManger = powershelInstance.Runspace.RunspaceConfiguration.AuthorizationManager;
powershelInstance.AddScript(scriptToExecute);
Collection<PSObject> results = powershelInstance.Invoke();
if (powershelInstance.Streams.Error.Count > 0)
{
throw powershelInstance.Streams.Error[0].Exception;
}
foreach (var result in results)
{
}
}
}
有脚本:
$hostsPath = "$env:windir\System32\drivers\etc\hosts";
$hosts = get-content $hostsPath;
[System.Collections.ArrayList]$arr = $hosts;
$arr.Add(someValueHere);
$arr | Out-File $hostsPath -enc ascii;
# returns results;
$arr;
# end of the script";
我试过这个:调用(Set-ExecutionPolicy -Scope CurrentUser -ExecutionPolicy Unrestricted
);
然后在脚本开头粘贴Set-ExecutionPolicy -Scope CurrentUser -ExecutionPolicy Unrestricted
。使用此Set-ExecutionPolicy Unrestricted
- 相同且相同的错误。路径 C:\ Windows \ System32 \ drivers \ etc \ hosts'被拒绝。
如果我遇到控制台应用程序,该脚本将完美运行。
更新:我以管理员身份运行Visual Studio。
更新2:好的,现在我正在使用ImpersonatedUser
,但会发生另一个异常。 “不允许请求注册表访问。”
堆栈跟踪:
at System.ThrowHelper.ThrowSecurityException(ExceptionResource resource)
at Microsoft.Win32.RegistryKey.OpenSubKey(String name, Boolean writable)
at System.Environment.GetEnvironmentVariable(String variable, EnvironmentVariableTarget target)
at System.Management.Automation.ModuleIntrinsics.SetModulePath()
at System.Management.Automation.ExecutionContext.InitializeCommon(AutomationEngine engine, PSHost hostInterface)
at System.Management.Automation.AutomationEngine..ctor(PSHost hostInterface, RunspaceConfiguration runspaceConfiguration, InitialSessionState iss)
at System.Management.Automation.Runspaces.LocalRunspace.DoOpenHelper()
at System.Management.Automation.Runspaces.RunspaceBase.CoreOpen(Boolean syncCall)
at System.Management.Automation.PowerShell.Worker.CreateRunspaceIfNeededAndDoWork(Runspace rsToUse, Boolean isSync)
at System.Management.Automation.PowerShell.CoreInvokeHelper[TInput,TOutput](PSDataCollection`1 input, PSDataCollection`1 output, PSInvocationSettings settings)
在System.Management.Automation.PowerShell.CoreInvoke [TInput,TOutput](PSDataCollection 1 input, PSDataCollection
1输出,
using (ImpersonatedUser impersonatedUser = new ImpersonatedUser(username, domain, password))
{
using (PowerShell powershelInstance = PowerShell.Create())
{
powershelInstance.AddScript(scriptToExecute);
//When the .Invoke() method is called, an exception with message "Requested registry access is not allowed." was thrown.
Collection<PSObject> results = powershelInstance.Invoke();
if (powershelInstance.Streams.Error.Count > 0)
{
throw powershelInstance.Streams.Error[0].Exception;
}
}
}
答案 0 :(得分:1)
您的ASP.NET使用应用程序池的工作进程的凭据执行PowerShell脚本,该进程可能不是管理帐户(除非您更改了它)。
修改hosts文件仅限于管理帐户,在更改工作进程的凭据之前,您应该非常谨慎地考虑。
如果您要进行此更改,请按照此处的说明进行操作:https://technet.microsoft.com/en-us/library/cc771170(v=ws.10).aspx
同样,此更改可能会影响您的应用程序更容易受到安全漏洞攻击(因为您的应用程序中的任何漏洞都可以与管理权限一起使用)。
如果打开了UAC(用户帐户控制),您可能还需要关闭它。
另一种方法是使用模拟暂时提升你的特权。你可以在这里看到一个类的样本,允许你(包装起来):https://blogs.msdn.microsoft.com/joncole/2009/09/21/impersonation-code-in-c/
希望这有帮助。
答案 1 :(得分:0)
我找到了一些其他解决方案,但也许这不是最好的解决方案。在IIS服务器中只需添加一个新的应用程序池。在高级设置中,将身份更改为自定义帐户并输入您的凭据到Windows。使用新的应用程序池到站点。