func (s *StepConnectWinRM) waitForWinRM(state multistep.StateBag, cancel <-chan struct{}) (packer.Communicator, error) { var comm packer.Communicator for { select { case <-cancel: log.Println("[INFO] WinRM wait cancelled. Exiting loop.") return nil, errors.New("WinRM wait cancelled") case <-time.After(5 * time.Second): } host, err := s.Host(state) if err != nil { log.Printf("[DEBUG] Error getting WinRM host: %s", err) continue } port := s.Config.WinRMPort if s.WinRMPort != nil { port, err = s.WinRMPort(state) if err != nil { log.Printf("[DEBUG] Error getting WinRM port: %s", err) continue } } user := s.Config.WinRMUser password := s.Config.WinRMPassword if s.WinRMConfig != nil { config, err := s.WinRMConfig(state) if err != nil { log.Printf("[DEBUG] Error getting WinRM config: %s", err) continue } if config.Username != "" { user = config.Username } if config.Password != "" { password = config.Password } } log.Println("[INFO] Attempting WinRM connection...") comm, err = winrm.New(&winrm.Config{ Host: host, Port: port, Username: user, Password: password, Timeout: s.Config.WinRMTimeout, }) if err != nil { log.Printf("[ERROR] WinRM connection err: %s", err) continue } break } return comm, nil }
// // WinRMUpload uploads data to a file on a Windows Server. Uses WinRM, which // should be enabled on the target server // // Parameters: // host: target Windows server host // username: username for the host // password: password for the host // indata: data to be sent // outfile: target file to write to. the path should be specified in Windows // filepath format // Returns: // error: errors from establishing connection and copying the file // func WinRMUpload(host string, username string, password string, indata string, outfile string) error { log.Debug("Connecting to ", username, "@", password, ":", host, " copying to ", outfile) c, err := winrm.New(&winrm.Config{ Host: host, Port: 5985, Username: username, Password: password, Timeout: 30 * time.Second, }) if err != nil { return err } err = c.Upload(outfile, bytes.NewReader([]byte(indata)), nil) if err != nil { return err } return nil }
// // WinRMRunCmd runs a command on a Windows Server. Uses WinRM, which // should be enabled on the target server // // Parameters: // host: target Windows server host // username: username for the host // password: password for the host // command: command to run // Returns: // string: stdout from command execution // error: errors from establishing connection and copying the file // int: exit status from the command being run // func WinRMRunCmd(host string, username string, password string, command string) (string, error, int) { log.Debug("Connecting to ", username, "@", password, ":", host, " running command ", command) c, err := winrm.New(&winrm.Config{ Host: host, Port: 5985, Username: username, Password: password, Timeout: 30 * time.Second, }) if err != nil { return "", err, 1 } var cmd packer.RemoteCmd stdout := new(bytes.Buffer) stderr := new(bytes.Buffer) cmd.Command = command cmd.Stdout = stdout cmd.Stderr = stderr err = c.Start(&cmd) if err != nil { return "", err, 1 } cmd.Wait() // after waiting for command to complete execition, retrieve exit status exit := cmd.ExitStatus log.Debug("stdout:", stdout, "stderr:", stderr, "exit:", exit) var returnerr error if stderr.String() == "" { returnerr = nil } else { returnerr = errors.New(stderr.String()) } return stdout.String(), returnerr, exit }