0

我有一个 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";

我试过这个: Invoke( 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, PSDataCollection1 输出,

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;
        }
    }
}
4

2 回答 2

1

您的 ASP.NET 使用应用程序池的工作进程的凭据执行 PowerShell 脚本,这可能不是管理帐户(除非您更改了它)。

修改 hosts 文件仅限于管理帐户,您应该在更改工作进程的凭据之前非常谨慎地考虑。

如果您想进行此更改,请按照此处的说明进行操作:https ://technet.microsoft.com/en-us/library/cc771170(v=ws.10).aspx

同样,此更改可能会使您的应用程序更容易受到安全漏洞的攻击(因为在您的应用程序中发现的任何漏洞都可以通过管理权限使用)。

如果 UAC(用户帐户控制)已打开,您可能还需要关闭它。

另一种方法是使用冒充来临时提升您的特权。您可以在此处查看允许您执行此操作的类的示例(包装 evething):https ://blogs.msdn.microsoft.com/joncole/2009/09/21/impersonation-code-in-c/

希望这可以帮助。

于 2016-04-19T15:50:50.110 回答
0

我找到了一些其他的解决方案,但也许它不是最好的。在 IIS 服务器中,只需添加一个新的应用程序池。在高级设置中将身份更改为自定义帐户并将您的凭据输入到 windows。使用该站点的新应用程序池。

于 2016-04-20T11:26:53.487 回答