【问题标题】:Access hosts file with powershell script from C#从 C# 使用 powershell 脚本访问主机文件
【发布时间】:2016-04-19 15:43:22
【问题描述】:

我有一个 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](PSDataCollection1 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;
        }
    }
}

【问题讨论】:

    标签: c# asp.net powershell hosts hosts-file


    【解决方案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/

    希望这会有所帮助。

    【讨论】:

    • 您可以使用模拟,但风险仍然相同。我将其添加到我的答案中。
    • 确保您模拟的用户是管理员帐户,您以该用户身份运行 powershell 并更改了执行策略并检查它是否有帮助。
    • 我认为它是管理员,它是我唯一的一个用户。您的意思是在调用方法中传递“Set-ExecutionPolicy -Scope CurrentUser -ExecutionPolicy Unrestricted”?
    • 检查用户是否在您服务器上的管理员组中。我的意思是以该用户身份登录(如果它不是您的普通用户)并运行您曾经编写的确切命令。您是否也禁用了 UAC?
    【解决方案2】:

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

    【讨论】:

    • 这是我的第一个建议。正如我所说,从安全角度来看,这是非常危险的。
    • 哦,是的,对。我正在寻找另一种解决方案,却忘记了这一点。我只是把它作为最后的解决方案。
    猜你喜欢
    • 2022-10-14
    • 1970-01-01
    • 2011-07-07
    • 1970-01-01
    • 1970-01-01
    • 2021-03-06
    • 1970-01-01
    • 2017-01-31
    • 2014-09-12
    相关资源
    最近更新 更多