在Golang中使用psexec时缺少stdout

On remote machine I just used psexec.exe to run specific command, the output of the cmd is intact while testing in shell.

Only the first line was printed out when submitting the cmd in Golang.

I tried to use winexe on linux platform, but the Symantec anti-virus treats it as PUA, then I turned back to windows platform.

func main() {
  cmd := exec.Command("C:\\Users\\v\\go\\src\\asys\\ss\\psexec.exe", "\\\\192.168.0.64",  "-nobanner", "-accepteula", "-u", "vz", "-p", "1",  "-s", "cmd", "/c", "ipconfig")
  var out bytes.Buffer
  multi := io.MultiWriter(os.Stdout, &out)
  cmd.Stdout = multi
  if err := cmd.Run(); err != nil {
    log.Fatalln(err)
  }
  fmt.Printf("
*** FULL OUTPUT *** %s
", out.String())
}

output:

Windows IP Configuration
*** FULL OUTPUT ***
Windows IP Configuration
Process finished with exit code 0

Not to answer your question directly, but I'm afraid you might be falling victim of the so-called XY Problem: there's no point in jumping through that many hoops to merely collect an information about the configuration of the IP stack of the target host—Windows provides special means, called WMI, to carry out such tasks.

So, instead of calling psexec.exe to call—on the target host—cmd.exe to call ipconfig.exe, you may just defer this task to one of the queries supported by WMI.

I'd suggest using either Win32_NetworkAdapter or Win32_IP4RouteTable (or both)—depending on which kind of data you actually need (configuration of NICs or routing data).

A working sample, using github.com/StackExchange/wmi is:

package main

import (
    "log"
    "os"
    "time"

    "github.com/StackExchange/wmi"
)

type win32_NetworkAdapter struct {
    AdapterType string
    AdapterTypeID uint16
    AutoSense bool
    Availability uint16
    Caption string
    ConfigManagerErrorCode uint32
    ConfigManagerUserConfig bool
    CreationClassName string
    Description string
    DeviceID string
    ErrorCleared bool
    ErrorDescription string
    GUID string
    Index uint32
    InstallDate time.Time
    Installed bool
    InterfaceIndex uint32
    LastErrorCode uint32
    MACAddress string
    Manufacturer string
    MaxNumberControlled uint32
    MaxSpeed uint64
    Name string
    NetConnectionID string
    NetConnectionStatus uint16
    NetEnabled bool
    NetworkAddresses []string
    PermanentAddress string
    PhysicalAdapter bool
    PNPDeviceID string
    PowerManagementCapabilities []uint16
    PowerManagementSupported bool
    ProductName string
    ServiceName string
    Speed uint64
    Status string
    StatusInfo uint16
    SystemCreationClassName string
    SystemName string
    TimeOfLastReset time.Time
}

type win32_IP4RouteTable struct {
    Age int32
    Caption string
    Description string
    Destination string
    Information string
    InstallDate time.Time
    InterfaceIndex int32
    Mask string
    Metric1 int32
    Metric2 int32
    Metric3 int32
    Metric4 int32
    Metric5 int32
    Name string
    NextHop string
    Protocol uint32
    Status string
    Type uint32
}

func main() {
    var compName string
    switch len(os.Args) {
    case 1:
        compName = "."
    case 2:
        compName = os.Args[1]
    default:
        log.Fatalf("usage: %s [COMPUTER]", os.Args[0])
    }

    var dst []win32_NetworkAdapter
    //var dst []win32_IP4RouteTable
    q := wmi.CreateQuery(&dst, "")
    err := wmi.Query(q, &dst, compName)
    if err != nil {
        log.Fatalf("%#v
", err)
    }

    for _, v := range dst {
        log.Printf("%#v
", v)
    }
}

As presented, it queries the host whose name is passed on the command line (or, missing that, localhost) for the NIC config.

To get routing data instead, comment out the first var dst ... statement and uncomment the second one. Hope you'll get the idea.

The relevant starting points are this and that.