2015-06-18 12 views
7

Chcę uruchomić skrypt wsadowy Windows od go, pod innym użytkownikiem, do użytkownika uruchomionego programu go. Użytkownik uruchamiający go ma więcej uprawnień niż użytkownik, który powinien uruchomić skrypt wsadowy.Dlaczego Powershell Start-Process nie działa po wywołaniu z go (golang)?

Od tej pory istnieje kilka opcji wykonania procesu pod innym użytkownikiem w systemie Windows, na przykład podczas pisania wywołań okien bezpośrednio przy użyciu pakietu syscall w programie. Nie próbowałem jeszcze tego, ale próbowałem zarówno przy użyciu PsExec, jak i Powershell. Powershell jest preferowany, ponieważ jest instalowany jako standard w systemie Windows 2008 R2.

Poniższy kod ilustruje problem, który mam. W poniższym demo uruchamiam skrypt wsadowy. Ten skrypt wsadowy wywołuje bezpośrednio skrypt Powershell, a następnie wywołuje go z programu go. Wyniki są różne. Skrypt Powershell wyprowadza 3 pliki, ale po wywołaniu z wyjścia, wyprowadza tylko 2 pliki.

W celu uzupełnienia, pokazuję również, w jaki sposób został utworzony użytkownik.

C: \ StackOverflow \ demo.bat:

::::: create a new user for the demo ::::: 

:: first create a home directory 
mkdir C:\Users\Tom 
:: remove Users group 
icacls C:\Users\Tom /remove:g Users 
:: remove Everyone 
icacls C:\Users\Tom /remove:g Everyone 
:: create user Tom and set his home directory 
net user Tom _Jerry123_ /add /expires:never /passwordchg:no /homedir:C:\Users\Tom /y 
:: Give Tom access to his home directory 
icacls C:\Users\Tom /grant:r Tom:(CI)F SYSTEM:(CI)F Administrators:(CI)F 
:: give him access to Remote Desktop 
net localgroup "Remote Desktop Users" /add Tom 

::::: now call powershell directly ::::: 

powershell -command C:\stackoverflow\demo.ps1 
:: show which files were created 
dir C:\Users\Tom 
:: cleanup 
del /f /q C:\Users\Tom\* 

::::: run the go version to do the same thing ::::: 

go run C:\stackoverflow\demo.go 
:: compare results 
dir C:\Users\Tom 
:: cleanup 
del /f /s /q C:\Users\Tom 
rmdir /s /q C:\Users\Tom 
:: delete user 
net user Tom /delete 

C: \ StackOverflow \ demo.ps1

write-output "test output" | out-file C:\Users\Tom\started.txt 
$credentials = New-Object System.Management.Automation.PSCredential -ArgumentList @("Tom",(ConvertTo-SecureString -String "_Jerry123_" -AsPlainText -Force)) 
Start-Process C:\stackoverflow\whoami.bat -WorkingDirectory C:\stackoverflow -Credential ($credentials) -Wait 
write-output "test output" | out-file C:\Users\Tom\finished.txt 

C: \ StackOverflow \ demo.go

package main 

import (
    "fmt" 
    "os" 
    "os/exec" 
) 

func main() { 
    run(exec.Command("PowerShell", "-Command", "C:\\stackoverflow\\demo.ps1")) 
} 

func run(cmd *exec.Cmd) { 
    cmd.Stdout = os.Stdout 
    cmd.Stderr = os.Stderr 
    cmd.Stdin = os.Stdin 
    err := cmd.Start() 
    if err != nil { 
     panic(err) 
    } 
    err = cmd.Wait() 
    if err != nil { 
     panic(err) 
    } 
    fmt.Println("Done") 
} 

C: \ stackoverflow \ whoami.bat:

whoami > C:\Users\Tom\whoami.txt 

A teraz wyniki - tutaj widzimy, gdy wywoływane ze skryptu wsadowego, pliki start.txt, whoami.txt, finished.txt wszystkie zostaną utworzone. Po wywołaniu z pliku tworzone są tylko pliki begin.txt i finished.txt. Dlaczego?

wyjściowa:

C:\stackoverflow>demo.bat 

C:\stackoverflow>mkdir C:\Users\Tom 

C:\stackoverflow>icacls C:\Users\Tom /remove:g Users 
processed file: C:\Users\Tom 
Successfully processed 1 files; Failed processing 0 files 

C:\stackoverflow>icacls C:\Users\Tom /remove:g Everyone 
processed file: C:\Users\Tom 
Successfully processed 1 files; Failed processing 0 files 

C:\stackoverflow>net user Tom _Jerry123_ /add /expires:never /passwordchg:no /homedir:C:\Users\Tom /y 
The command completed successfully. 


C:\stackoverflow>icacls C:\Users\Tom /grant:r Tom:(CI)F SYSTEM:(CI)F Administrators:(CI)F 
processed file: C:\Users\Tom 
Successfully processed 1 files; Failed processing 0 files 

C:\stackoverflow>net localgroup "Remote Desktop Users" /add Tom 
The command completed successfully. 


C:\stackoverflow>powershell -command C:\stackoverflow\demo.ps1 

C:\stackoverflow>dir C:\Users\Tom 
Volume in drive C is OSDisk 
Volume Serial Number is CCD6-C9E7 

Directory of C:\Users\Tom 

06/18/2015 06:36 AM <DIR>   . 
06/18/2015 06:36 AM <DIR>   .. 
06/18/2015 06:36 AM    28 finished.txt 
06/18/2015 06:36 AM    28 started.txt 
06/18/2015 06:36 AM    55 whoami.txt 
       3 File(s)   111 bytes 
       2 Dir(s) 16,489,889,792 bytes free 

C:\stackoverflow>del /f /q C:\Users\Tom\* 

C:\stackoverflow>go run C:\stackoverflow\demo.go 
Done 

C:\stackoverflow>dir C:\Users\Tom 
Volume in drive C is OSDisk 
Volume Serial Number is CCD6-C9E7 

Directory of C:\Users\Tom 

06/18/2015 06:36 AM <DIR>   . 
06/18/2015 06:36 AM <DIR>   .. 
06/18/2015 06:36 AM    28 finished.txt 
06/18/2015 06:36 AM    28 started.txt 
       2 File(s)    56 bytes 
       2 Dir(s) 16,489,889,792 bytes free 

C:\stackoverflow>del /f /s /q C:\Users\Tom 
Deleted file - C:\Users\Tom\finished.txt 
Deleted file - C:\Users\Tom\started.txt 

C:\stackoverflow>rmdir /s /q C:\Users\Tom 

C:\stackoverflow>net user Tom /delete 
The command completed successfully. 


C:\stackoverflow> 
+0

Widzę, że licznik "wolnych bajtów" nie jest zmieniany między dwoma komendami 'dir', podczas gdy powinien, ponieważ w programie były trzy pliki po uruchomieniu Powershell, a dwa po uruchomieniu Go. Dlatego plik został utworzony, chociaż nie jest widoczny (sprawdź "attrib -r -h -s c: \ users \ tom \ whoami.txt") lub znajduje się w innym miejscu. Proszę poszukać pliku (ów) o nazwie zawierającej 'whoami' po uruchomieniu polecenia go, prawdopodobnie istnieje problem z uprawnieniami do pliku lub przekierowaniem folderu. – Vesper

+1

Dzięki Vesper, to był dobry pomysł. Niestety nie jest to powód; komenda 'attrib' zwróciła' File not found', a plik nie pojawił się podczas wyszukiwania. Następnie zrobiłem szybki test i utworzyłem kilka małych plików, a "bajtów za darmo" również się nie zmieniło podczas uruchamiania 'dir' - więc myślę, że może to być czerwony śledzia. Domyślam się, że 'bytes free' nie zawsze jest od razu aktualizowane. –

+0

Czy możliwe jest, że zakres 'go' sprawia, że ​​PowerShell zapomina, że ​​skrypty .bat są powiązane z' cmd/c', podczas gdy PowerShell wywoływany wewnątrz skryptu wsadowego utrzymuje skojarzenie? Czy robi to różnicę, jeśli uruchomisz "Start-Process cmd.exe"/c c: \ stackoverflow \ whoami.bat "-otherargs'? Jeśli nie, czy robi to różnicę, wstawiając 'set-executionpolicy remotesigned' na początku pliku demo.ps1? – rojo

Odpowiedz

1

naprawił.

  1. Użytkownik Tom nie może uzyskać dostępu do folderu C:\Stackoverflow domyślnie, aby cokolwiek do uruchomienia, musiałem dać dostęp wszystkich do przeczytania/Wykonanie elementów w tym folderze, w przeciwnym razie uruchomienie procesu nie zdało egzaminu

  2. Dodaj profil_profilu do polecenia użytkownika sieci. To zapobiega dodatkowe foldery tworzone że wspominałem w komentarzu:

    net user Tom _Jerry123_ /add /expires:never /passwordchg:no /homedir:C:\Users\Tom /profilepath:C:\Users\Tom /y

  3. Zamień linię Start-Process z:

    Start-Process C:\stackoverflow\whoami.bat -WorkingDirectory C:\Users\Tom -Credential ($credentials) -Wait

Dlaczego?

Przy katalogu roboczym ustawionym na C: \ StackOverflow, interpreter poleceń, który wykonuje plik wsadowy, znajduje whoami.bat przed wbudowanym, a wszystkie rodzaje zepsutych zdarzeń występują. Kiedy przeniosłem katalog roboczy do folderu Toma, wszystko działało dokładnie tak, jak chciałeś.

Alternatywa:

Nie nazwać partię pliki tak samo jak wbudowanych poleceń.

+0

Wielkie dzięki za Eris, za czas, który zajęło mi przyjrzenie się mojemu pytaniu. Niestety uważam, że jeszcze nie odpowiedział na to dla mnie. Przepraszam, zbyt szybko wcisnąłem! Pozwól mi kontynuować ... –

+0

Proponowane zmiany nie spowodowały wygenerowania trzech plików programu go. Również skrypt powershell zadziałał po wywołaniu z pliku demo.bat, więc zmiana (1) na konto użytkownika nie może być konieczna. Zmiana (2) jest przydatna, ale niezwiązana z opisanym problemem. Zmiana (3) nie miała dla mnie żadnego wpływu, a także w pliku demo.bat katalog roboczy jest C: \ stackoverflow, więc jest równoważny z programem go, więc nie wyjaśnia rozbieżności. Wielkie dzięki. –

+0

Skrypt go uruchamia się jako użytkownik admin, skrypt powershell jest uruchamiany jako użytkownik admin. Tylko plik wsadowy jest uruchamiany przy użyciu 'Start-Process' jako nowy użytkownik. – Eris