在web应用程序中通过C#调用Powershell-应用程序池标识问题

在web应用程序中通过C#调用Powershell-应用程序池标识问题,c#,powershell,C#,Powershell,我已经编写了一些东西,使用RunspaceFactory通过C#执行Powershell 我正在加载默认的Powershell配置文件,如下所示: Runspace runspace = RunspaceFactory.CreateRunspace(); runspace.Open(); string scriptText = @". .\" + scriptFileName + "; " + command; Pipeline pipeline = runspace.C

我已经编写了一些东西,使用RunspaceFactory通过C#执行Powershell

我正在加载默认的Powershell配置文件,如下所示:

   Runspace runspace = RunspaceFactory.CreateRunspace();
   runspace.Open();
   string scriptText = @". .\" + scriptFileName + "; " + command;
   Pipeline pipeline = runspace.CreatePipeline(scriptText);
Command=我知道的概要文件中的一个函数可以工作

所有这些Powershell内容都包装在Impersonator中

为免生疑问,$profile=C:\Users\Administrator\Documents\WindowsPowerShell\Microsoft.PowerShell\U profile.ps1

这是一个在IIS 7.5下运行的web应用程序

如果我的IIS应用程序在“管理员”帐户下运行,则它可以工作。在任何其他帐户下,它抛出错误:

术语“.\Microsoft.PowerShell\u profile.ps1”无法识别为cmdlet、函数、脚本文件或可操作程序的名称。请检查名称的拼写,或者如果包含路径,请验证路径是否正确,然后重试

由于我模拟的是“管理员”帐户,所以我假设位置是正确的

一些带有调用的“get location”的日志记录会报告目录应该是什么

出于血淋淋的想法,我试图用:

  System.Environment.CurrentDirectory = dir;
。。。以及尝试调用“设置位置”。这些都可以工作,但是如果我从运行空间调用“get location”,它会报告与以前相同的目录(正确的目录)

我认为,也许模拟可能有问题,所以我编写了一些测试,以应用程序池无法实现的方式触及文件系统。这些工作

我还检查了这个:

string contextUserName = System.Security.Principal.WindowsIdentity.GetCurrent().Name;
当代码在模拟程序中“包装”时,以及通过应用程序池标识执行时,它都会报告正确的用户。然后我绝望地试着调用:

 @"cmd /c dir"
。。。(并获取Childitem)。两个命令都返回:

{}
…在应用程序池标识下运行时(无论模拟如何),但在应用程序池以“管理员”身份运行时,提供正确目录的完整准确目录列表

我确信我在这里遗漏了一些愚蠢和基本的东西,如果有人能给我一些关于我在思考(和代码)中犯了错误的指导,那就太好了

在模拟环境中使用ASP.NET中的PowerShell时,这是一个“众所周知”的问题:它不能按人们认为应该的方式工作

这是因为PowerShell在封面后面旋转另一个线程来完成其所有工作。PowerShell中的新线程不会继承模拟的上下文

修复工作并不十分完美。建议将ASP.NET设置为始终流动模拟策略(以便幕后线程获得标识):


. 您可以将环回PowerShell会话(连接到本地主机)与PowerShell一起使用,并让WinRM处理模拟。这需要System.Management.Automation的3.0.0.0版

var password = "HelloWorld";
var ss = new SecureString();
foreach (var passChar in password)
{
    ss.AppendChar(passChar);
}
var psCredential = new PSCredential("username", ss);
var connectionInfo = new WSManConnectionInfo(new Uri("http://localhost:5985/wsman"), "http://schemas.microsoft.com/powershell/Microsoft.PowerShell", psCredential);
using (var runspace = RunspaceFactory.CreateRunspace(connectionInfo))
{
    connectionInfo.EnableNetworkAccess = true;
    using (var powershell = PowerShell.Create())
    {
这也是一个俗气的解决方案,因为它需要运行WinRM的Windows服务并配置WinRM。WinRM并不完全是“可以正常工作”的东西,但是它在第一个选项中完成任务是不合适的


WSManConnectionInfo中使用的URL是本地主机WinRM端点,默认情况下,它侦听版本3中的端口5985,并为连接指定凭据。

非常感谢。我知道我找错了方向。我想你不知道我可以从应用程序中检查alwaysFlowImpersonationPolicy的值吗?我已经对相关框架的aspnet.config文件进行了更改,但没有任何区别,这几乎肯定是原因所在,我现在肯定已经阅读了一些内容。愚蠢的问题,但是如果在C:\Windows\Microsoft.NET\Framework\中编辑文件,Visual Studio将尊重对机器配置的更改,不是吗?我的测试是在VisualStudio中通过调试完成的,带有IIS 7.5的完整版本。@hobgadling-Hm,不,对不起,我没有。