【问题标题】:powershell Start-Process exit code -1073741502 when used with Credential from a windows service environment与 Windows 服务环境中的凭据一起使用时的 powershell 启动进程退出代码 -1073741502
【发布时间】:2015-06-19 15:33:34
【问题描述】:

我在使用 powershell Start-Process 调用时遇到了一个奇怪的行为。

来电:

$process = start-process `
    "C:\somepath\MyBinary.exe" `
    -PassThru `
    -Credential $defaultCredential `
    -Wait `
    -WorkingDirectory  "C:\somepath" `
    -LoadUserProfile
if ($process.ExitCode -ne 0)
{
#do something
}

此调用始终返回退出代码 -1073741502
快速搜索后,此退出代码似乎与程序无法加载所需的 dll(又名。STATUS_DLL_INIT_FAILED)时的一般错误有关。

当我在没有-Credential $credential 的情况下运行它时,程序运行正常。

为了隔离问题,我用我的目标凭据在提示符中手动启动了some.exe,它运行顺利。

所以问题似乎只是来自 start-process cmdlet 有效启动进程的方式。

我为这个问题找到了一些潜在的解决方案,但没有成功:linklink

你知道这里发生了什么吗?

编辑 1:
当直接启动或通过 powershell 脚本启动时,我运行一个 proc mon 来监视程序活动。加载kernelbase.dll时似乎出现问题。

本地 procmon 转储(工作):

9:06:35.3837439 AM  MyBinary.exe    2620    Load Image  C:\Windows\SysWOW64\kernelbase.dll  SUCCESS Image Base: 0x76270000, Image Size: 0x47000
9:06:35.4317417 AM  MyBinary.exe    2620    RegOpenKey  HKLM\System\CurrentControlSet\Control\Nls\Sorting\Versions  REPARSE Desired Access: Read
9:06:35.4317751 AM  MyBinary.exe    2620    RegOpenKey  HKLM\System\CurrentControlSet\Control\Nls\Sorting\Versions  SUCCESS Desired Access: Read
9:06:35.4318016 AM  MyBinary.exe    2620    RegSetInfoKey   HKLM\System\CurrentControlSet\Control\Nls\Sorting\Versions  SUCCESS KeySetInformationClass: KeySetHandleTagsInformation, Length: 0
9:06:35.4318152 AM  MyBinary.exe    2620    RegQueryValue   HKLM\System\CurrentControlSet\Control\Nls\Sorting\Versions\(Default)    SUCCESS Type: REG_SZ, Length: 36, Data: 00060101.00060101
...

Powershell procmon(失败,见线程退出,进程退出代码-1073741502):

9:35:07.9455191 AM  MyBinary.exe    2276    Load Image  C:\Windows\SysWOW64\kernelbase.dll  SUCCESS Image Base: 0x76270000, Image Size: 0x47000
9:35:07.9537146 AM  MyBinary.exe    2276    Thread Exit     SUCCESS Thread ID: 5112, User Time: 0.0000000, Kernel Time: 0.0000000
9:35:07.9537386 AM  MyBinary.exe    2276    QueryNameInformationFile    C:\Windows\System32\apisetschema.dll    SUCCESS Name: \Windows\System32\apisetschema.dll
9:35:07.9537686 AM  MyBinary.exe    2276    QueryNameInformationFile    C:\somepath\MyBinary\MyBinary.exe   SUCCESS Name: \somepath\MyBinary\MyBinary.exe
9:35:07.9537914 AM  MyBinary.exe    2276    QueryNameInformationFile    C:\Windows\System32\wow64cpu.dll    SUCCESS Name: \Windows\System32\wow64cpu.dll
9:35:07.9538134 AM  MyBinary.exe    2276    QueryNameInformationFile    C:\Windows\System32\wow64win.dll    SUCCESS Name: \Windows\System32\wow64win.dll
9:35:07.9538349 AM  MyBinary.exe    2276    QueryNameInformationFile    C:\Windows\System32\wow64.dll   SUCCESS Name: \Windows\System32\wow64.dll
9:35:07.9538579 AM  MyBinary.exe    2276    QueryNameInformationFile    C:\Windows\System32\ntdll.dll   SUCCESS Name: \Windows\System32\ntdll.dll
9:35:07.9538796 AM  MyBinary.exe    2276    QueryNameInformationFile    C:\Windows\SysWOW64\ntdll.dll   SUCCESS Name: \Windows\SysWOW64\ntdll.dll
9:35:07.9539425 AM  MyBinary.exe    2276    Process Exit        SUCCESS Exit Status: -1073741502, User Time: 0.0000000 seconds, Kernel Time: 0.0000000 seconds, Private Bytes: 339,968, Peak Private Bytes: 401,408, Working Set: 1,523,712, Peak Working Set: 1,826,816

编辑 2:
我应该提到 powershell 脚本是从服务运行的(它是一个竹服务代理)。我刚刚发现这个thread 说:

Process.Start 在内部调用 CreateProcessWithLogonW(CPLW) 时 凭据被指定。无法调用 CreateProcessWithLogonW 来自 Windows 服务环境(例如 IIS WCF 服务)。它 只能从交互式进程(应用程序 由通过 CTRL-ALT-DELETE 登录的用户启动)。

我的猜测是 powershell start-process 调用正在使用 CreateProcessWithLogonW...

编辑 3:
我的服务是使用自定义用户运行的(因为我无法从系统模拟),因此请阅读 link。我测试确保启用了“允许服务与桌面交互”。因为它仅适用于非自定义帐户,所以我通过更改 HKLM\System\CurrentControlSet\Services\%myservice% 类型键(如 herehere 所述)在注册表中手动设置它。

【问题讨论】:

  • 您使用凭据的帐户可能没有访问它尝试加载的某些 dll 所在位置的权限。
  • 使用程序检查文件夹的文件系统权限,检查您使用的凭据的用户是否至少具有对整个文件夹链和有问题的 DLL(如果已写入)或整个文件夹的读取权限,如果它不是。如果访问权限有问题,请授予他读取+执行权限。
  • 谢谢我已经检查过了,权限似乎设置正确。用户是用户和管理员的成员,并且可以完全控制包含二进制文件的文件夹。
  • 如果是这样,启动进程监视器(来自 Sysinternals 的工具)然后启动你的进程,然后针对抛出的 DLL 调试什么错误。恐怕帮不上什么忙了。
  • @Vesper,你只是没有看到我的编辑:p?

标签: powershell credentials start-process


【解决方案1】:

start-processSystem.Diagnostics.Process.Start() 的“别名”,所以是的,它确实使用了CreateProcessWithLogonW()。如前所述,此方法不能从服务进程调用,它只能从“交互式”进程调用。对“唯一”的警告是您发现的那个 - 当您不更改凭据时,它至少可以启动该过程。 (这实际上甚至可能是一个错误 - 我与一位 Microsoft 支持工程师就这个问题交谈过,对此感到“惊讶”。)

从服务进程内部启动另一个进程的唯一(支持)方法是使用本机 Win32 API 方法CreateProcessAsUser()。如何做到这一点的一个例子是 C#.NET 可以在the answer 中找到编辑#2 中提到的问题。

Windows 进程必须作为用户会话的一部分启动。如果启动过程作为交互式会话的一部分运行 - 您使用 CTRL+ALT+DELETE 登录并打开桌面的那种 - 那么您可以使用CreateProcessWithLogonW(),它将自动使用您当前的用户会话。如果启动进程是一项服务或“批处理”进程(如计划任务),那么启动进程必须要么创建一个新的用户会话(或识别现有的用户会话)来启动新进程(这就是代码在上述答案中确实如此。)

【讨论】:

  • 感谢@nateirvin,我们将竹代理作为一个简单的进程而不是服务运行。这更容易解决问题。
【解决方案2】:

到目前为止,我发现的唯一解决方案是禁用 UAC(将 EnableLUA 设置为 0 = 本地安全策略中的管理员批准模式)。因此,这肯定是 UAC 在禁用时忽略的文件/文件夹/注册表访问问题。

【讨论】:

    【解决方案3】:

    有一个类似问题的Microsoft KB 2701373 有可用的修补程序。帮我解决了问题。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2011-07-19
      • 1970-01-01
      • 1970-01-01
      • 2014-03-09
      • 2017-02-04
      • 2019-12-19
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多