与Windows服务环境中的凭据一起使用时,powershell Start-Process退出代码-1073741502 [英] powershell Start-Process exit code -1073741502 when used with Credential from a windows service environment

查看:277
本文介绍了与Windows服务环境中的凭据一起使用时,powershell Start-Process退出代码-1073741502的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我通过Powershell的Start-Process调用遇到了一种奇怪的行为.

I'm running into a strange behavior with a powershell Start-Process call.

这是电话:

$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)时,此退出代码似乎与一般错误有关.

This call always return with the exit code -1073741502.
After a quick search, this exit code seems related to a generic error when the program could not load its required dll (aka. STATUS_DLL_INIT_FAILED).

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

When I run it without -Credential $credential the program runs correctly.

为了找出问题所在,我在带有目标凭据的提示符下手动启动了some.exe,它运行顺利.

In order to isolate the problem, I manually launched some.exe in a prompt with my target credential and it runs smoothly.

因此,问题似乎仅在于启动过程cmdlet有效启动过程的方式.

So the problem only seems to come from the way the start-process cmdlet effectively launch the process.

对于这个我想运气不佳的问题,我发现了一些可能的解决方案:

I found some potential solutions for this problem I tried to apply with no luck : link and link.

您对这里发生的事情有任何了解吗?

Would you have any idea of what's going on here ?


我直接或通过powershell脚本运行时,运行proc mon监视程序活动.加载kernelbase.dll时似乎会出现此问题.

Edit 1:
I run a proc mon for monitoring program activities when launched directly or via the powershell script. The problem seems to occur when loading kernelbase.dll.

本地procmon转储(正在运行):

Local procmon dump (working):

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):

Powershell procmon (failing, see thread exit, and process exit code -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


我应该提到Powershell脚本是从服务运行的(这是一个竹子服务代理).我刚刚发现了这个
线程说:

Edit 2:
I should mention the powershell script is run from a service (it's a bamboo service agent). And i just found this thread saying:

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

Process.Start internally calls CreateProcessWithLogonW(CPLW) when credentials are specified. CreateProcessWithLogonW cannot be called from a Windows Service Environment (such as an IIS WCF service). It can only be called from an Interactive Process (an application launched by a user who logged on via CTRL-ALT-DELETE).

我的猜测是Powershell启动过程调用正在使用CreateProcessWithLogonW ...

My guess is that powershell start-process call is making uses of CreateProcessWithLogonW...


我的服务是由自定义用户运行的(因为我无法从System进行模拟),因此请阅读HKLM\System\CurrentControlSet\Services\%myservice%类型键在注册表上进行了手动设置(如

Edit 3:
My service is run with a custom user (because I cannot impersonate from System), so as read link. I tested ensuring the "Allow service to interact with desktop" was enabled. Because it's only available for non custom accounts I set it up by hand on registry by altering HKLM\System\CurrentControlSet\Services\%myservice% Type key (as described here and here).

推荐答案

start-processSystem.Diagnostics.Process.Start()的别名",所以是的,它确实使用了CreateProcessWithLogonW().如前所述,不能从服务流程中调用此方法,只能从交互"流程中调用.对仅"的警告是您发现的-仅当您不更改凭据时,它至少可以启动该过程. (这实际上甚至可能是一个错误-与我讨论此问题的Microsoft支持工程师完全惊讶于它的工作.)

start-process is an 'alias' for System.Diagnostics.Process.Start(), so yes, it does make use of CreateProcessWithLogonW(). As noted, this method can't be called from a service process, it can only be called from an 'interactive' process. The caveat to that "only" is the one you've discovered - that when you aren't changing credentials, it can at least get the process started. (This may actually even be a bug - a Microsoft Support engineer I spoke with about this issue was "surprised" it worked at all.)

从服务进程内部启动另一个进程的唯一(受支持的)方法是使用本机Win32 API方法CreateProcessAsUser().有关C#.NET的示例,请参见答案(在编辑#2中提到的问题).

The only (supported) way to launch another process from inside a service process is to use the native Win32 API method CreateProcessAsUser(). An example of how to do this is C#.NET can be found in the answer to the question mentioned in edit #2.

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

A Windows process must launched as part of a user session. If the launching process is running as part of an interactive session - the kind where you logged in using CTRL+ALT+DELETE and have a desktop open - then you can use CreateProcessWithLogonW(), which will use your current user session automatically. If the launching process is a service, or "batch" process (as Scheduled Tasks are), then the launching process must either create a new user session (or identify an existing one) to launch the new process in (which is what the code in the afore-mentioned answer does.)

这篇关于与Windows服务环境中的凭据一起使用时,powershell Start-Process退出代码-1073741502的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆