2015-06-19 21 views
7

Si sta verificando uno strano comportamento con una chiamata Start-Process di PowerShell.powershell Start-Process codice di uscita -1073741502 se utilizzato con le credenziali da un ambiente di servizio Windows

Ecco la chiamata:

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

Questa chiamata restituisce sempre con il codice di uscita - 1073741502.
Dopo una ricerca rapida, questo codice di uscita sembra correlato a un errore generico quando il programma non è riuscito a caricare la sua dll richiesta (ovvero STATUS_DLL_INIT_FAILED).

Quando lo eseguo senza -Credential $credential, il programma viene eseguito correttamente.

Per isolare il problema, ho lanciato manualmente some.exe in un prompt con le credenziali di destinazione e funziona senza intoppi.

Quindi il problema sembra venire solo dal modo in cui il cmdlet del processo di avvio avvia in modo efficace il processo.

Ho trovato alcune soluzioni potenziali per questo problema che ho provato ad applicare senza fortuna: link e link.

Avete qualche idea di cosa sta succedendo qui?

Edit 1:
Ho eseguito un mon proc per le attività di monitoraggio del programma una volta lanciato, direttamente o tramite lo script PowerShell. Il problema sembra verificarsi durante il caricamento di kernelbase.dll.

locale discarica ProcMon (di lavoro):

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 (in mancanza, vedi uscita filo, e l'uscita di processo del codice - 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 dovrebbe menzionare lo script PowerShell viene eseguito da un servizio (è un agente di servizio di bambù). E ho appena trovato questo thread dicendo:

Process.Start chiama internamente CreateProcessWithLogonW (CPLW) quando vengono specificati credenziali. CreateProcessWithLogonW non può essere chiamato da un ambiente di servizio Windows (come un servizio WCF IIS). È possibile chiamare solo da un processo interattivo (un'applicazione avviata da un utente che ha effettuato l'accesso tramite CTRL-ALT-DELETE).

La mia ipotesi è che la chiamata processo di start-PowerShell sta facendo uso di CreateProcessWithLogonW ...

Edit 3:
Il mio servizio è gestito con un utente personalizzata (perché non posso impersonare da System) , quindi leggi link. Ho provato a verificare che "Consenti al servizio di interagire con il desktop" fosse abilitato. Poiché è disponibile solo per gli account non personalizzati, l'ho impostato manualmente sul registro alterando la chiave di tipo (come descritto here e here).

+0

l'account per cui si stanno utilizzando le credenziali per probabilmente non dispone dei diritti di accesso a dove alcuni dll sta tentando di caricare risiede. – EBGreen

+0

Controllare i diritti del file system sulla cartella con il programma, controllare che l'utente con le credenziali utilizzate abbia almeno accesso in lettura all'intera catena di cartelle e alla DLL in questione (se è scritta) o all'intera cartella, se non lo è. Se ci sono problemi con i diritti di accesso, concedigli di leggere + eseguire. – Vesper

+0

Grazie ho già controllato, le autorizzazioni sembra essere correttamente impostato. L'utente è membro di entrambi gli utenti e amministratore e ha il pieno controllo sulla cartella contenente il file binario. –

risposta

4

start-process è un 'alias' per System.Diagnostics.Process.Start(), quindi sì, fa uso di CreateProcessWithLogonW(). Come notato, questo metodo non può essere chiamato da un processo di servizio, può essere chiamato solo da un processo 'interattivo'. L'avvertimento a quel "solo" è quello che hai scoperto - che quando non si cambiano le credenziali, può almeno avviare il processo. (Questo potrebbe persino essere un bug - un ingegnere del supporto Microsoft con cui ho parlato di questo problema è stato "sorpreso" ha funzionato affatto.)

L'unico modo (supportato) per avviare un altro processo all'interno di un processo di servizio è utilizzare il metodo API Win32 nativo CreateProcessAsUser(). Un esempio di come farlo è C# .NET può essere trovato in the answer alla domanda citata in modifica # 2.

Un processo Windows deve essere avviato come parte di una sessione utente. Se il processo di avvio è in esecuzione come parte di una sessione interattiva, il tipo in cui è stato effettuato l'accesso utilizzando CTRL + ALT + CANC e il desktop è aperto, è possibile utilizzare CreateProcessWithLogonW(), che utilizzerà automaticamente la sessione utente corrente. Se il processo di avvio è un servizio, o processo "batch" (come attività pianificate), il processo di avvio deve o creare una nuova sessione utente (o identificarne una esistente) per avviare il nuovo processo in (che è ciò che il codice nella risposta sopra citata.)

+1

Grazie a @nateirvin, per la cronaca, siamo riusciti a gestire il nostro agente di bambù come un processo semplice anziché un servizio. Questo ha risolto il problema più facilmente. –

0

Solo la soluzione che ho trovato finora è disabilitare UAC (impostare EnableLUA su 0 = modalità di approvazione amministratore in Criteri di sicurezza locali). Quindi, sicuramente sembra essere un problema di accesso al file/cartella/registro che l'UAC ignora quando disabilitato.

0

C'è un Microsoft KB 2701373 su un problema simile con un aggiornamento rapido disponibile. Mi ha aiutato a risolvere il problema