簡體   English   中英

為什么Powershell Start-Process在從go(golang)調用時不起作用?

[英]Why does Powershell Start-Process not work when called from go (golang)?

我希望在不同的用戶下運行Windows批處理腳本,運行go程序的用戶。 運行go的用戶比應該運行批處理腳本的用戶擁有更多權限。

從go開始,有幾個選項可以在Windows上的不同用戶下執行進程,例如使用go中的syscall包直接編寫Windows調用。 我還沒有嘗試過這個,但我嘗試過使用PsExec和Powershell。 Powershell是首選,因為它在Windows 2008 R2上作為標准安裝。

以下代碼演示了我遇到的問題。 在下面的演示中,我運行一個批處理腳本。 此批處理腳本直接調用Powershell腳本,然后從go程序中調用它。 結果不同。 Powershell腳本輸出3個文件,但從go調用時,只輸出2個文件。

為了完整起見,我還展示了如何創建用戶。

C:\\計算器\\ 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:\\計算器\\ 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:\\計算器\\ 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:\\計算器\\ whoami.bat:

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

現在,結果 - 在這里你看到從批處理腳本調用時,文件的start.txt,whoami.txt,finished.txt都被創建了。 從go調用時,只創建了starts.txt和finished.txt。 這是為什么?

輸出:

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>

修復。

  1. 默認情況下,用戶Tom無法訪問C:\\Stackoverflow文件夾,為了運行任何內容,我必須讓Everyone訪問該文件夾中的Read / Execute項,否則start-process失敗了

  2. 將profilepath添加到net user命令。 這阻止了我在評論中提到的額外文件夾:

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

  3. Start-Process行替換為:

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

為什么?

將工作目錄設置為C:\\ StackOverflow,執行批處理文件的命令解釋whoami.bat在內置之前找到whoami.bat ,並發生各種破壞。 將工作目錄移動到Tom的文件夾后,一切都按照您的意願運行。

替代方案:

不要將批處理文件命名為內置命令。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM