使用Go调用Powershell加域

发布时间 2023-07-28 17:22:49作者: yangras
package main

import (
	"fmt"
	"github.com/go-ldap/ldap/v3"
	"github.com/mozillazg/go-pinyin"
	"os"
	"os/exec"
	"strings"
	"time"
)


func ChineseToAbbreviation(chinese string) string {
	// 获取拼音
	pinyinArgs := pinyin.NewArgs()
	pinyinSlice := pinyin.Pinyin(chinese, pinyinArgs)

	// 提取拼音首字母
	abbreviation := ""
	for _, pinyin := range pinyinSlice {
		abbreviation += string(pinyin[0][0])
	}

	return strings.ToUpper(abbreviation)
}

func getHostname() string {
	// 获取当前机器名

	hostname, err := os.Hostname()
	if err != nil {
		fmt.Println("获取机器名失败:", err)
		os.Exit(1)
	}

	return hostname
}

func GetName(username string, password string) (string, string) {

	// 域控制器的地址和端口
	ldapServer := "ldap://192.168.1.1:389"

	// 连接到域控制器
	l, err := ldap.DialURL(ldapServer)
	if err != nil {
		fmt.Println("无法连接到域控制器,是否连接到网络:", err)
		os.Exit(1)
	}
	defer l.Close()

	// 绑定用户凭据
	err = l.Bind(username+"@abc.com", password)
	if err != nil {
		fmt.Println(password + "---" + username)
		fmt.Println("身份验证失败,检查用户名是否正确:", err)
		os.Exit(1)
	}

	// 查询用户属性
	searchRequest := ldap.NewSearchRequest(
		"dc=ccepc,dc=com",      // 根目录
		ldap.ScopeWholeSubtree, // 查询范围
		ldap.NeverDerefAliases, // 不解析别名
		0,                      // 查询超时
		0,                      // 查询限制
		false,                  // 是否只返回属性
		fmt.Sprintf("(sAMAccountName=%s)", username), // 查询条件
		[]string{"name"}, // 返回的属性
		nil,
	)

	sr, err := l.Search(searchRequest)
	if err != nil {
		fmt.Println("查询失败:", err)
		os.Exit(1)
	}

	// 检查是否找到结果
	if len(sr.Entries) == 0 {
		fmt.Println("未找到用户")
		os.Exit(1)
	}

	// 获取用户的名称属性
	nameAttribute := sr.Entries[0].GetAttributeValue("name")
	return nameAttribute, ChineseToAbbreviation(nameAttribute)
}

func main() {
	// 提示用户输入用户名和密码
	fmt.Print("请输入工号: ")
	var username string
	var pctype string
	var isPC bool
	_, err := fmt.Scanln(&username)
	if err != nil {
		fmt.Println("无效的工号输入:", err)
		os.Exit(1)
	}

	fmt.Print("请输入密码: ")
	var password string
	_, err = fmt.Scanln(&password)
	if err != nil {
		fmt.Println("无效的密码输入:", err)
		os.Exit(1)
	}

	fmt.Print("请输入计算机类型,笔记本输入0,台式机输入1: ")

	_, err = fmt.Scanln(&isPC)
	if err != nil {
		fmt.Println("无效的密码输入:", err)
		os.Exit(1)
	}
	if isPC {
		pctype = "PC"
	} else {
		pctype = "NB"
	}
	chinestname, shortname := GetName(username, password)
	newPcName := pctype + username + shortname
	fmt.Println("您的中文名字是\n***" + chinestname + "***")
	fmt.Println("您的名字拼字首字母大写是\n***" + shortname + "***")
	fmt.Print("您的计算机将被更名为\n***" + newPcName + "***\n")
	fmt.Print("确认请按Y: ")

	var IsYesStr string
	_, err = fmt.Scanln(&IsYesStr)
	if err != nil {
		fmt.Println("读取输入时发生错误:", err)
		os.Exit(1)
	}

	// 去除输入中的空白字符
	IsYesStr = strings.TrimSpace(IsYesStr)
	IsYesStr = strings.ToUpper(IsYesStr)

	// 根据用户输入进行相应操作
	if strings.EqualFold(IsYesStr, "Y") {

		
		
		fmt.Println("开始加域操作")
		time.Sleep(2 * time.Second)
		cmd := exec.Command("powershell", "-Command", `$securePassword = ConvertTo-SecureString -String `+password+` -AsPlainText -Force;$credential = New-Object System.Management.Automation.PSCredential( `+username+` , $securePassword);$cred = Get-Credential -Credential $credential;Rename-Computer -NewName `+newPcName+` -DomainCredential $cred -Force;Add-Computer -Domain "abc.com" -Options JoinWithNewName -Credential $cred -force`)
		fmt.Println(cmd)
		err := cmd.Run()
		if err != nil {
			fmt.Println("转化密码失败:", err)
			return
		}
		fmt.Println("计算机重命名为:", newPcName)
	


		fmt.Println("请保存工作,重启电脑后,使用域账号登录")
		_, err = fmt.Scanln(&isPC)

	}

}