11

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

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

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

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

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 ?

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.

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 (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

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

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

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

Community
  • 1
  • 1
John-Philip
  • 2,838
  • 2
  • 20
  • 48
  • the account that you are using the credentials for probably does not have access rights to where some dll it is trying to load resides. – EBGreen Jun 19 '15 at 15:58
  • Check file system rights on the folder with program, check that the user which credentials you use has at least read access to entire folder chain and the DLL in question (if it's written) or the entire folder if it's not. If there are issues with access rights, grant him read+execute. – Vesper Jun 20 '15 at 16:11
  • Thanks I already checked this, the permissions seems to be correctly set. The user is member of both Users and Administrator and has full control over the folder containing the binary. – John-Philip Jun 22 '15 at 08:04
  • If so, launch Process Monitor (the tool from Sysinternals) then start your process, then debug what error against what DLL is thrown. Can't help much further I'm afraid. – Vesper Jun 22 '15 at 08:06
  • 1
    @Vesper, you just didn't see my edit right :p ? – John-Philip Jun 22 '15 at 08:10
  • From this ProcMon log - how do I know which dll it could not load (or folder not access)? Last row it says ntdll.dll was a success. I am working on a the same problem. Only solution I have found is to disable UAC (set EnableLUA to 0) - then it works! – serializer Dec 02 '15 at 16:05

3 Answers3

7

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

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.

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

Community
  • 1
  • 1
nateirvin
  • 1,084
  • 1
  • 10
  • 28
  • 1
    Thanks @nateirvin, for the record, we managed running our bamboo agent as a simple process instead of a service. This solved the problem more easily. – John-Philip Jun 23 '15 at 14:30
0

Only solution I have found so far is to disable UAC (set EnableLUA to 0 = Admin approval mode in Local Security Policy). So, it definitely seem to be a file/folder/registry access problem which the UAC ignores when disabled.

serializer
  • 913
  • 1
  • 11
  • 27
0

There is a Microsoft KB 2701373 on a similar issue with a hotfix available. Helped me to resolve the problem.

Rod
  • 1,113
  • 11
  • 16