2015-06-19 9 views
7

Występuje dziwne zachowanie z połączeniem uruchomienia procesu Powerhell.powershell Kod wyjścia uruchomienia procesu -1073741502 w przypadku użycia z poświadczeniem z poziomu środowiska systemu Windows

Oto wezwanie:

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

toll zawsze powrócić z kodem wyjścia - 1073741502.
Po szybkim wyszukiwaniu ten kod wyjścia wydaje się być związany z ogólnym błędem, gdy program nie może załadować wymaganego pliku dll (czyli STATUS_DLL_INIT_FAILED).

Po uruchomieniu go bez -Credential $credential program działa poprawnie.

Aby wyizolować problem, ręcznie uruchomiłem some.exe w wierszu z moimi docelowymi poświadczeniami i działa on płynnie.

Problem pojawia się tylko dlatego, że polecenie cmdlet start-process skutecznie uruchamia proces.

Znalazłem potencjalne rozwiązania tego problemu, które starałem się zastosować bez powodzenia: link i link.

Czy masz pojęcie, co się tutaj dzieje?

Edit 1:
Prowadzę mon proc dla działań programu monitorowania po uruchomieniu bezpośrednio lub za pośrednictwem skryptu PowerShell. Problem pojawia się podczas ładowania kernelbase.dll.

Local procmon dump (roboczy):

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 (braku znaleźć wyjście gwintu oraz wyjście procesu kodu - 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 

Edycja 2:
I powinien wspomnieć o skrypcie powershell uruchamianym z usługi (to bambusowy agent usługi). A ja po prostu znaleźć to thread mówiąc:

Process.Start zwraca wewnętrznie CreateProcessWithLogonW (CPLW) gdy poświadczenia są określone. CreateProcessWithLogonW nie można nazwać ze środowiska usług systemu Windows (takiego jak usługa IIS WCF). To może być wywołane tylko z procesu interaktywnego (aplikacja uruchomiona przez użytkownika, który zalogował się przez CTRL-ALT-DELETE).

Domyślam się, że wezwanie proces uruchamiania PowerShell czyni zastosowań CreateProcessWithLogonW ...

Edit 3:
Mój serwis jest prowadzony z niestandardowych użytkownika (bo nie może podszyć od systemu) , tak jak przeczytaj link. Sprawdziłem, czy włączono opcję "Zezwalaj na interakcję z komputerem". Ponieważ jest on dostępny tylko dla kont niestandardowych, ustawiam go ręcznie w rejestrze, zmieniając klucz typu HKLM\System\CurrentControlSet\Services\%myservice% (zgodnie z opisem here i here).

+0

Konto, na którym używasz referencji, prawdopodobnie nie ma praw dostępu do miejsca, w którym znajduje się część biblioteki dll, którą próbuje załadować. – EBGreen

+0

Sprawdź prawa systemu plików w folderze z programem, sprawdź, czy użytkownik, którego używasz, ma co najmniej dostęp do całego łańcucha folderów i biblioteki DLL (jeśli jest zapisany) lub cały folder, jeśli nie jest. Jeśli występują problemy z uprawnieniami dostępu, udziel mu odczytu + wykonania. – Vesper

+0

Dzięki temu już sprawdziłem, uprawnienia wydają się być poprawnie ustawione. Użytkownik jest członkiem zarówno Użytkowników, jak i Administratora i ma pełną kontrolę nad folderem zawierającym plik binarny. –

Odpowiedz

4

start-process to "alias" dla System.Diagnostics.Process.Start(), więc tak, korzysta z CreateProcessWithLogonW(). Jak wspomniano, tej metody nie można wywołać z procesu usługi, można ją wywołać tylko z procesu "interaktywnego". Zastrzeżenie dla tego "jedynego" jest tym, co odkryłeś - że jeśli nie zmieniasz poświadczeń, to przynajmniej możesz zacząć ten proces. (To może być nawet błąd - inżynier pomocy technicznej Microsoft, z którym rozmawiałem na ten temat, był "zaskoczony", że zadziałało.)

Jedynym (obsługiwanym) sposobem uruchomienia innego procesu z procesu serwisowego jest użyj natywnej metody Win32 API CreateProcessAsUser(). Przykładem tego, jak to zrobić jest C# .NET można znaleźć w the answer na pytanie wymienione w edycji # 2.

Proces systemu Windows musi zostać uruchomiony jako część sesji użytkownika. Jeśli proces uruchamiania działa w ramach interaktywnej sesji - takiej, w której logowałeś się przy użyciu CTRL + ALT + DELETE i masz otwarty pulpit - możesz użyć CreateProcessWithLogonW(), który automatycznie użyje bieżącej sesji użytkownika. Jeśli proces uruchamiania jest usługą lub procesem "wsadowym" (tak jak zaplanowane zadania), wówczas proces uruchamiania musi albo utworzyć sesję nowego użytkownika (albo zidentyfikować istniejącą), aby uruchomić nowy proces (co jest tym, co kod w powyższej odpowiedzi.)

+1

Dzięki @nateirvin, dla przypomnienia, udało nam się uruchomić nasz agent bambusowy jako prosty proces zamiast usługi. To rozwiązało problem łatwiej. –

0

Jedyne rozwiązanie, które do tej pory znalazłem, to wyłączyć UAC (ustawić EnableLUA na 0 = tryb zatwierdzania admina w Lokalnej polityce bezpieczeństwa). Wydaje się, że jest to problem z dostępem do plików/folderów/rejestru, który UAC ignoruje po wyłączeniu.

Powiązane problemy