简体   繁体   English

powershell从Windows服务环境与Credential一起使用时,启动 - 处理退出代码-1073741502

[英]powershell Start-Process exit code -1073741502 when used with Credential from a windows service environment

I'm running into a strange behavior with a powershell Start-Process call. 我正在使用PowerShell Start-Process调用遇到一种奇怪的行为。

Here is the call: 这是电话:

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

This call always return with the exit code - 1073741502 . 此调用始终返回退出代码 - 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 ). 快速搜索后,当程序无法加载其所需的dll(又名STATUS_DLL_INIT_FAILED )时,此退出代码似乎与一般错误有关。

When I run it without -Credential $credential the program runs correctly. 当我在没有-Credential $credential的情况下运行它时,程序运行正常。

In order to isolate the problem, I manually launched some.exe in a prompt with my target credential and it runs smoothly. 为了隔离问题,我在目标凭证的提示中手动启动了some.exe ,它运行顺利。

So the problem only seems to come from the way the start-process cmdlet effectively launch the process. 所以问题似乎只来自start-process cmdlet有效启动进程的方式。

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 ? 你知道这里发生了什么吗?

Edit 1: 编辑1:
I run a proc mon for monitoring program activities when launched directly or via the powershell script. 我直接或通过powershell脚本启动监视程序活动的proc mon。 The problem seems to occur when loading kernelbase.dll . 加载kernelbase.dll时似乎发生了这个问题。

Local procmon dump (working): 本地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 (failing, see thread exit, and process exit code - 1073741502 ): 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

Edit 2: 编辑2:
I should mention the powershell script is run from a service (it's a bamboo service agent). 我应该提到powershell脚本是从服务运行的(它是一个竹子服务代理)。 And i just found this thread saying: 我刚刚发现这个帖子说:

Process.Start internally calls CreateProcessWithLogonW(CPLW) when credentials are specified. 当指定凭据时,Process.Start在内部调用CreateProcessWithLogonW(CPLW)。 CreateProcessWithLogonW cannot be called from a Windows Service Environment (such as an IIS WCF service). 无法从Windows服务环境(例如IIS WCF服务)调用CreateProcessWithLogonW。 It can only be called from an Interactive Process (an application launched by a user who logged on via CTRL-ALT-DELETE). 它只能从Interactive Process(由通过CTRL-ALT-DELETE登录的用户启动的应用程序)调用。

My guess is that powershell start-process call is making uses of CreateProcessWithLogonW ... 我的猜测是PowerShell启动进程调用正在使用CreateProcessWithLogonW ...

Edit 3: 编辑3:
My service is run with a custom user (because I cannot impersonate from System), so as read link . 我的服务是使用自定义用户运行的(因为我无法模拟来自System),因此作为读取链接 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 ). 因为它仅适用于非自定义帐户,所以我通过更改HKLM\\System\\CurrentControlSet\\Services\\%myservice% Type键(如此此处所述 )在注册表上手动设置。

start-process is an 'alias' for System.Diagnostics.Process.Start() , so yes, it does make use of CreateProcessWithLogonW() . start-processSystem.Diagnostics.Process.Start()的'别名',所以是的,它确实使用了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.) (这实际上甚至可能是一个错误 - 我与之谈过这个问题的微软支持工程师“感到惊讶”它完全有效。)

The only (supported) way to launch another process from inside a service process is to use the native Win32 API method CreateProcessAsUser() . 从服务进程内部启动另一个进程的唯一(支持)方法是使用本机Win32 API方法CreateProcessAsUser() An example of how to do this is C#.NET can be found in the answer to the question mentioned in edit #2. 如何执行此操作的示例是C#.NET可以在编辑#2中提到的问题的答案中找到。

A Windows process must launched as part of a user session. Windows进程必须作为用户会话的一部分启动。 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. 如果启动过程作为交互式会话的一部分运行 - 您使用CTRL + ALT + DELETE登录并打开桌面的类型 - 那么您可以使用CreateProcessWithLogonW() ,它将自动使用您当前的用户会话。 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.) 如果启动过程是服务或“批处理”过程(如计划任务那样),则启动过程必须创建新的用户会话(或标识现有的会话)以启动新进程(这就是代码)在上述答案中。)

Only solution I have found so far is to disable UAC (set EnableLUA to 0 = Admin approval mode in Local Security Policy). 到目前为止,我找到的唯一解决方案是禁用UAC(将EnableLUA设置为0 =本地安全策略中的管理员批准模式)。 So, it definitely seem to be a file/folder/registry access problem which the UAC ignores when disabled. 因此,它肯定是一个文件/文件夹/注册表访问问题,UAC在禁用时会忽略。

There is a Microsoft KB 2701373 on a similar issue with a hotfix available. Microsoft KB 2701373在类似问题上提供了修补程序。 Helped me to resolve the problem. 帮我解决了这个问题。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM