Commit b9e5176d by 陶腾飞

2022-03-31

parent f21c5cff
......@@ -53,8 +53,8 @@
- 2020/05/15 v0.7 加入Error Json,walk.Resouce.Icon()使用绝对路径,修改users.exe的报错机制
- 2020/05/18 v0.8 更新 大屏主机的文件共享,取消TXHD的凌晨关机.
- 2020/05/27 v0.9 新增微盘备份与同步功能,adct能够强制备份用户文件,用注册表来存储信息
- 2020/06/03 v1.0 完善代码,强制备用户文件方法,日志输出到特定目录,优化变量名,输出日志并由filebeat发送到elk,修复一堆错误
- 2020/05/27 v0.9 新增微盘备份与同步功能,adct能够强制备份用户文件用注册表来存储信息
- 2020/06/03 v1.0 完善代码,强制备用户文件方法,日志输出到特定目录,优化变量名,输出日志并由filebeat发送到elk,修复一堆错误
- 2020/06/08 v1.0.1 修改函数文件结构,新增部分格式化错误,修改备份方案(一)
- 2020/06/12 v1.0.2 第二版用户备份方案更新完成
- 2020/06/17 v1.1.0 更新在注册表中用户状态记录和修正电源状态的记录
......@@ -62,7 +62,7 @@
- 2020/07/07 v1.1.2 优化备份策略
- 2020/07/09 v1.2.0 更新批量打开工具
- 2020/07/22 v1.3.1 修复文件共享打开失败问题,支持对非域用户的唤醒
- 2020/07/20 v1.3.0 升级备份,优化注册表值记录,启动企业微信知微运维平台
- 2020/07/20 v1.3.0 升级备份,优化注册表值记录启动企业微信知微运维平台
- 2020/07/22 v1.3.1 修复文件共享打开失败问题,支持对非域用户的唤醒
- 2020/07/27 v1.4.0 更新图标显示/隐藏工具,优化exec消息处理逻辑,优化企业微信知微运维平台
- 2020/07/30 v1.5.0 知微运维平台升级支持开机重启关机、支持批量百度搜索
......@@ -70,18 +70,19 @@
- 2020/08/10 v1.5.2 修复文件共享BUG
- 2020/08/11 v1.6.0 域用户备份升级
- 2020/08/12 v1.6.1 优化备份方案
- 2020/08/19 v1.7.0 更新PDF转化工具,优化用户备份
- 2020/08/21 v1.8.0 合并企业微信推送,转型HTTP服务器,增加活动检测,用户备份升级
- 2020/08/19 v1.7.0 更新PDF转化工具优化用户备份
- 2020/08/21 v1.8.0 合并企业微信推送,转型HTTP服务器,增加活动检测用户备份升级
- 2020/08/21 v1.8.1 解决无法处理收到的消息问题
- 2020/08/26 v1.8.2 解决因消息框未返回而出现的关机停止问题
- 2020/08/26 v1.8.4 解决个人共享读取失败的问题
- 2020/10/18 v1.9.0 修复双向备份文件Bug,针对704室主机唤醒做调整,增加远程唤醒功能
- 2020/10/18 v1.9.0 修复双向备份文件Bug,针对704室主机唤醒做调整增加远程唤醒功能
- 2020/10/22 v1.10.0 升级批量打开,增加重启软件按钮,检测并关闭保护试图
- 2020/10/26 v1.10.1 修复批量打开失败问题
- 2020/10/27 v1.10.2 优化软件安装和重启小工具的程序逻辑,更新64位的程序清单和新ico文件
- 2020/10/27 v1.10.2 优化软件安装和重启小工具的程序逻辑更新64位的程序清单和新ico文件
- 2020/11/05 v1.10.3 更新备份策略
- 2022/03/29 v2.0.0 删除备份策略,同步域计算机信息到cmdb,添加账户、主机管理管理,唤醒策略更新,日志统一收集处理,运维平台添加管理员指令
- 2022/03/30 v2.1.0 支持通过cmdb获取字段来唤醒主机,日志输出优化,支持通过运维平台打开远程终端
- 2022/03/29 v2.0.0 删除备份策略,同步域计算机信息到cmdb,添加账户、主机管理管理,唤醒策略更新,日志统一收集处理,运维平台添加管理员指令
- 2022/03/30 v2.1.0 支持通过cmdb获取字段来唤醒主机,日志输出优化,支持通过运维平台打开远程终端
- 2022/03/31 v2.2.0 知微运维平台功能完善,修复cmdb的位置错误问题,修复用户会属于多个主要计算机的问题,修复内存条DDR4无法显示的问题,清除扫描硬盘出现U盘的情况
## 五、其他说明
......
......@@ -19,7 +19,6 @@ var f struct {
}
func main() {
var reportText = flag.String(pub.Msg_Report, "", "report to AD")
var wolMacText = flag.String("wolmac", "", "input MACAddress for waking pc")
var wolHostText = flag.String("wolhost", "", "input hostname for waking pc")
......@@ -126,7 +125,7 @@ func wolMac(mac *string) {
pub.Wol_enter("", mac)
}
func wolHost(pc *string) {
var hostname string = *pc
var hostname string = strings.ToUpper(*pc)
// 判断主机名的格式
if _, err := pub.GetHostnamePart(hostname); err != nil {
......
......@@ -7,11 +7,37 @@ import (
"io"
"io/ioutil"
"net/http"
"net/url"
"strings"
)
var client = http.Client{}
func getVFromK(cir *CIRecordResult, k string) string {
var r string
switch k {
case Cmdb_Bumen:
r = cir.Bumen
case Cmdb_Product_name:
r = cir.Product_name
case Cmdb_Username:
r = cir.Username
case Cmdb_Mac:
r = cir.Mac
}
return r
}
func cmdbChineseURL(k, v string) string {
switch k {
case Cmdb_Bumen:
v = url.QueryEscape(v)
case Cmdb_Username:
v = url.QueryEscape(v)
}
return v
}
// 将键值转化为json
func cmdbKVtoJSON(k, v string) (string, error) {
......@@ -38,6 +64,7 @@ func cmdbExistRecord(k, v string) (int, bool) {
var count string = "1"
var cmdbPath string = "api/v0.1/ci/s?q="
v = cmdbChineseURL(k, v)
search := fmt.Sprintf("%s:%s", k, v)
url := fmt.Sprintf("%s/%s_type:%s,%s&count=%s", cmdbUrl, cmdbPath, cmdbCITypeComputer, search, count)
LOG(DEBUG, CMDB, url)
......@@ -145,6 +172,7 @@ func cmdbGetCI(k, v string) (int, error) {
var count string = "1"
var cmdbPath string = "api/v0.1/ci/s?q="
v = cmdbChineseURL(k, v)
search := fmt.Sprintf("%s:%s", k, v)
url := fmt.Sprintf("%s/%s_type:%s,%s&count=%s", cmdbUrl, cmdbPath, cmdbCITypeComputer, search, count)
LOG(DEBUG, CMDB, url)
......@@ -170,11 +198,48 @@ func cmdbGetCI(k, v string) (int, error) {
}
}
// 保证k字段只有一个v字段
func CmdbRecordValueClear(k, v string) error {
var cmdbPath string = "api/v0.1/ci/s?q="
v = cmdbChineseURL(k, v)
search := fmt.Sprintf("%s:%s", k, v)
url := fmt.Sprintf("%s/%s_type:%s,%s", cmdbUrl, cmdbPath, cmdbCITypeComputer, search)
LOG(DEBUG, CMDB, url)
var cir CIRecordReq
data, err := cmdbGET(url)
if err != nil {
LOG(ERROR, CMDB, err)
return err
}
if err := json.Unmarshal(data, &cir); err != nil {
LOG(ERROR, CMDB, err)
return err
}
LOG(DEBUG, CMDB, string(data))
if cir.Numfound == 0 {
return nil
}
s, err := cmdbKVtoJSON(k, "")
if err != nil {
return err
}
for _, j := range cir.R {
if err := cmdbUpdateRecordFromJSON(s, j.Ci_id); err != nil {
return err
}
}
return nil
}
// 根据键值获取1个字段
func CmdbGetWordFromKV(k, v, w string) (string, error) {
var count string = "1"
var cmdbPath string = "api/v0.1/ci/s?q="
v = cmdbChineseURL(k, v)
search := fmt.Sprintf("%s:%s", k, v)
url := fmt.Sprintf("%s/%s_type:%s,%s&count=%s", cmdbUrl, cmdbPath, cmdbCITypeComputer, search, count)
LOG(DEBUG, CMDB, url)
......@@ -206,6 +271,8 @@ func CmdbGetWordFromKV2(k, v, a, b string) (string, string, error) {
var count string = "1"
var cmdbPath string = "api/v0.1/ci/s?q="
v = cmdbChineseURL(k, v)
search := fmt.Sprintf("%s:%s", k, v)
url := fmt.Sprintf("%s/%s_type:%s,%s&count=%s", cmdbUrl, cmdbPath, cmdbCITypeComputer, search, count)
LOG(DEBUG, CMDB, url)
......@@ -231,14 +298,7 @@ func CmdbGetWordFromKV2(k, v, a, b string) (string, string, error) {
}
}
func getVFromK(cir *CIRecordResult, k string) string {
var r string
switch k {
case Cmdb_Mac:
r = cir.Mac
}
return r
}
func cmdbPOST(url string, reqdata []byte) ([]byte, error) {
buf := bytes.NewBuffer(nil)
buf.Write(reqdata)
......@@ -311,7 +371,7 @@ func cmdbGET(url string) ([]byte, error) {
}
res, err := (&client).Do(h)
if err != nil {
LOG(ERROR, "CMDB_GET", fmt.Sprintf("状态码:%d,路径:%s", res.StatusCode, url))
LOG(ERROR, "CMDB_GET", fmt.Sprintf("路径:%s", url))
return nil, err
}
defer res.Body.Close()
......
......@@ -6,7 +6,7 @@ import (
"sync"
)
const cmdb_Dept string = "bumen"
const Cmdb_Bumen string = "bumen"
const Cmdb_Product_name string = "product_name"
const Cmdb_Username string = "username"
const Cmdb_Mac string = "Mac"
......@@ -144,28 +144,28 @@ func (cir *CIRecordResult) position(location, dept string) string {
case "NB":
switch dept {
case "JL":
resutlt = cmdbPosition1
resutlt = cmdbPosition2
case "ZJ":
resutlt = cmdbPosition1
resutlt = cmdbPosition2
case "MT":
resutlt = cmdbPosition1
resutlt = cmdbPosition2
case "DD":
resutlt = cmdbPosition1
resutlt = cmdbPosition2
case "JR":
resutlt = cmdbPosition1
resutlt = cmdbPosition2
case "TXHD":
resutlt = cmdbPosition1
resutlt = cmdbPosition2
case "TXWJ":
resutlt = cmdbPosition1
resutlt = cmdbPosition2
case "JS":
resutlt = cmdbPosition1
resutlt = cmdbPosition2
case "JD":
resutlt = cmdbPosition2
resutlt = cmdbPosition1
case "HW":
resutlt = cmdbPosition2
resutlt = cmdbPosition1
case "BGYJ":
resutlt = cmdbPosition2
resutlt = cmdbPosition1
default:
resutlt = ERROR
......
......@@ -8,7 +8,7 @@ const SymbolHostname = "-"
// AD-Control //
const Version string = "2.1.0"
const Version string = "2.2.0"
const Host_adserver string = "ADSERVER"
const Host_thserver string = "THSERVER"
const Host_zzserver string = "ZZSERVER"
......
......@@ -21,7 +21,7 @@ var Error_Not_Msg = errors.New("isn't defined msg")
var Error_WXWork_Down = errors.New(Error_WXWork_Down_STR)
var Error_WXWork_Down_STR = "后台更新中..."
var Error_WXWork_NotDominUser_STR = "您的主机暂时不支持该功能"
var Error_WXWork_Fail_ReTry = "后台错误,稍后重试!"
const Error_CMDB_UPDATE_REQ = "更新失败"
const Sccessful_CMDB_UPDATE_REQ = "更新成功"
......
......@@ -113,6 +113,11 @@ func (rep *MJreport) MsgDeal() interface{} {
switch rep.Status {
// 服务器
case Msg_status_commit:
if err := CmdbRecordValueClear(Cmdb_Username, rep.DataStr); err != nil {
rep.DataStr = Error_CMDB_UPDATE_REQ
LOG(ERROR, rep.Instruction, err)
break
}
ci, err := cmdbGetCI(Cmdb_Product_name, rep.Computername)
if err != nil {
rep.DataStr = Error_CMDB_UPDATE_REQ
......@@ -130,7 +135,7 @@ func (rep *MJreport) MsgDeal() interface{} {
LOG(ERROR, rep.Instruction, err)
break
}
LOG(INFO, rep.Instruction, fmt.Sprintf("%s is %s's PrimryComputer", Cmdb_Product_name, rep.DataStr))
LOG(INFO, rep.Instruction, fmt.Sprintf("%s is %s's PrimryComputer", rep.Computername, rep.DataStr))
rep.DataStr = Sccessful_CMDB_UPDATE_REQ
// 客户端
......@@ -250,7 +255,10 @@ func (wake *MJwake) MsgDeal() interface{} {
func (wxwork *MJwxwork) MsgDealSend() {
switch wxwork.Instruction {
// 芝麻开机
case WXEK_zwDevopsPowerWake:
wxwork.SendText("收到唤醒指令,正在处理!")
if c, err := LDAP_CheckExistName(wxwork.Name); err != nil {
LOG(ERROR, wxwork.Instruction, err)
......@@ -271,24 +279,23 @@ func (wxwork *MJwxwork) MsgDealSend() {
case nil:
break
default:
wxwork.SendText(`后台错误?!`)
SendWxworkTextToAdmins("后台系统错误!")
wxwork.SendText(Error_WXWork_Fail_ReTry)
return
}
// 查看电源状态
// 查看 电源状态
status, err := PSTest_Connection(pc)
if err != nil {
wxwork.Result = Error_WXWork_Down_STR
break
wxwork.SendText(Error_WXWork_Fail_ReTry)
return
}
if status {
LOG(INFO, wxwork.Instruction, fmt.Sprintf("name:%s,host:%s", wxwork.Name, mac))
wxwork.Result = "已经开机了哦~"
break
}
LOG(INFO, "Wxwork_Rec", fmt.Sprintf("host:%s,mac:%s,name:%s,execstatus:%s,status:%v", pc, mac, wxwork.Name, "wakeup", status))
wxwork.SendText("收到唤醒指令,正在处理!")
LOG(INFO, wxwork.Instruction, fmt.Sprintf("host:%s,mac:%s,name:%s", pc, mac, wxwork.Name))
// 进行唤醒
go Wol_enter(pc, &mac)
......@@ -307,92 +314,114 @@ func (wxwork *MJwxwork) MsgDealSend() {
wxwork.Result = "开始唤醒,请等待~"
case WXEK_zwDevopsPowerReboot:
var pc string
wxwork.SendText("收到重启指令,正在处理")
// coding
// 检查是否是域用户
// err := Reg_IfExist_item(Reg_Root_ac, Reg_Path_home_du+wxwork.Name)
// if err != nil {
// wxwork.Result = Error_WXWork_NotDominUser_STR
// break
// }
// coding
// 检查注册表的主机 是否存在
// pc := wxwork.Reg_Query_ADUsers(Reg_Name_PrimayComputerName)
// if pc == "" {
// wxwork.Result = Error_WXWork_Down_STR
// break
// }
// 检查 主机连接情况
if c, err := LDAP_CheckExistName(wxwork.Name); err != nil {
LOG(ERROR, wxwork.Instruction, err)
} else {
if !c {
wxwork.SendText("请先申请知微域的个人账号!")
return
}
}
var pc string
var err error
pc, err = CmdbGetWordFromKV(Cmdb_Username, wxwork.Name, Cmdb_Product_name)
switch err {
case Error_CMDB_No_Record:
wxwork.SendText(`您还没有绑定个人主机,请使个人账号登录系统后,打开小工具,点击"主机管理"-"绑定主机"`)
return
case nil:
break
default:
wxwork.SendText(Error_WXWork_Fail_ReTry)
return
}
// 检查 主机连接情况
status, err := PSTest_Connection(pc)
if err != nil {
wxwork.Result = Error_WXWork_Down_STR
break
LOG(ERROR, wxwork.Instruction, err)
wxwork.SendText(Error_WXWork_Fail_ReTry)
return
}
if !status {
wxwork.Result = "主机已关机或无法连接主机"
break
}
LOG(INFO, "Wxwork_Rec", fmt.Sprintf("host:%s,name:%s,execstatus:%s,status:%v", pc, wxwork.Name, "reboot", status))
Execcmd_wait(`shutdown -r -t 0 -m \\` + pc)
// Reg_Write_ADDC(pc, Reg_Name_BeWakedID, wxwork.UserID)
LOG(INFO, wxwork.Instruction, fmt.Sprintf("host:%s,name:%s", pc, wxwork.Name))
if err := PowerRestartForNow(pc); err != nil {
LOG(ERROR, wxwork.Instruction, err)
wxwork.SendText(Error_WXWork_Fail_ReTry)
return
}
Delay(10)
go func(name, userid string) {
var rebooted bool = false
for i := 0; i < 30; i++ {
for i := 0; i < 20; i++ {
status, _ := PSTest_Connection(pc)
if !status {
rebooted = true
}
if status && rebooted {
wxwork.SendText("重启完成~")
wxwork.SendText("重启已完成~")
return
}
Delay(10)
}
}(wxwork.Name, wxwork.UserID)
wxwork.Result = "开始重启,请等待~"
break
// 芝麻关机
case WXEK_zwDevopsPowerTurnOFF:
wxwork.SendText("收到关机指令,正在处理!")
if c, err := LDAP_CheckExistName(wxwork.Name); err != nil {
LOG(ERROR, wxwork.Instruction, err)
} else {
if !c {
wxwork.SendText("请先申请知微域的个人账号!")
return
}
}
var pc string
wxwork.SendText("收到关机指令,正在处理")
// coding
// 检查是否是域用户
// err := Reg_IfExist_item(Reg_Root_ac, Reg_Path_home_du+wxwork.Name)
// if err != nil {
// wxwork.Result = Error_WXWork_NotDominUser_STR
// break
// }
// 检查注册表的主机 是否存在
// pc := wxwork.Reg_Query_ADUsers(Reg_Name_PrimayComputerName)
// if pc == "" {
// wxwork.Result = Error_WXWork_Down_STR
// break
// }
var err error
pc, err = CmdbGetWordFromKV(Cmdb_Username, wxwork.Name, Cmdb_Product_name)
switch err {
case Error_CMDB_No_Record:
wxwork.SendText(`您还没有绑定个人主机,请使个人账号登录系统后,打开小工具,点击"主机管理"-"绑定主机"`)
return
case nil:
break
default:
wxwork.SendText(Error_WXWork_Fail_ReTry)
return
}
// 检查 主机连接情况
status, err := PSTest_Connection(pc)
if err != nil {
wxwork.Result = Error_WXWork_Down_STR
break
LOG(ERROR, wxwork.Instruction, err)
wxwork.SendText(Error_WXWork_Fail_ReTry)
return
}
if !status {
wxwork.Result = "主机已关机或无法连接主机"
break
}
LOG(INFO, "Wxwork_Rec", fmt.Sprintf("host:%s,name:%s,execstatus:%s,status:%v", pc, wxwork.Name, "shutdown", status))
Execcmd_wait(`shutdown -s -t 0 -m \\` + pc)
//Reg_Write_ADDC(pc, Reg_Name_BeWakedID, wxwork.UserID)
LOG(INFO, wxwork.Instruction, fmt.Sprintf("host:%s,name:%s", pc, wxwork.Name))
if err := PowerShutdownForNow(pc); err != nil {
LOG(ERROR, wxwork.Instruction, err)
wxwork.SendText(Error_WXWork_Fail_ReTry)
return
}
go func(name, userid string) {
for i := 0; i < 10; i++ {
Delay(30)
for i := 0; i < 20; i++ {
Delay(10)
status, _ := PSTest_Connection(pc)
if !status {
wxwork.SendText("关机已完成~")
......@@ -403,24 +432,29 @@ func (wxwork *MJwxwork) MsgDealSend() {
wxwork.Result = "开始关机,请等待~"
case WXEK_zwDevopsPowerStatus:
wxwork.SendText("收到查询指令,正在处理")
var domainUser bool = true
wxwork.SendText("收到查询指令,正在处理!")
if c, err := LDAP_CheckExistName(wxwork.Name); err != nil {
LOG(ERROR, wxwork.Instruction, err)
} else {
if !c {
wxwork.SendText("请先申请知微域的个人账号!")
return
}
}
var pc string
var err error
// coding
// 在注册表中查询 域用户 记录
// if err = Reg_IfExist_item(Reg_Root_ac, Reg_Path_home_du+wxwork.Name); err == nil {
// pc = wxwork.Reg_Query_ADUsers(Reg_Name_PrimayComputerName)
// // 在注册表中查询 知微用户 记录
// } else if err = Reg_IfExist_item(Reg_Root_ac, Reg_Path_home_zhu+wxwork.Name); err == nil {
// pc = wxwork.Reg_Query_ZhiWeiUsers(Reg_Name_PrimayComputerName)
// domainUser = false
// } else {
// wxwork.Result = Error_WXWork_NotDominUser_STR
// break
// }
pc, err = CmdbGetWordFromKV(Cmdb_Username, wxwork.Name, Cmdb_Product_name)
switch err {
case Error_CMDB_No_Record:
wxwork.SendText(`您还没有绑定个人主机,请使个人账号登录系统后,打开小工具,点击"主机管理"-"绑定主机"`)
return
case nil:
break
default:
wxwork.SendText(Error_WXWork_Fail_ReTry)
return
}
// 检查 主机连接情况
status, err := PSTest_Connection(pc)
......@@ -429,12 +463,10 @@ func (wxwork *MJwxwork) MsgDealSend() {
LOG(ERROR, NULL, err)
break
}
LOG(INFO, "Wxwork_Rec", fmt.Sprintf("host:%s,name:%s,execstatus:%s,status:%v", pc, wxwork.Name, "check", status))
LOG(INFO, "Wxwork_Rec", fmt.Sprintf("host:%s,name:%s", pc, wxwork.Name))
if status {
wxwork.Result = "主机已启动"
} else if !status && !domainUser {
wxwork.Result = "主机已关闭或禁用了ICMP(请允许防火墙)"
} else {
wxwork.Result = "主机已关闭"
}
......
......@@ -545,6 +545,12 @@ func getHardwareMemoryForPS() ([]int, []string, []string, int) {
m = "DDR3"
case "26":
m = "DDR4"
case "0":
if i, err := strconv.Atoi(Speed[j]); err != nil {
m = ""
} else if i >= 2133 {
m = "DDR4"
}
default:
m = ""
}
......@@ -579,6 +585,10 @@ func getHardwareHardDiskForPS(mini bool) ([]string, []int64, []string, int) {
m = "固态硬盘"
case "HDD":
m = "机械硬盘"
// 跳过U盘
case "Unspecified":
// 2+1后开始重置
c = 2
}
}
......@@ -633,3 +643,14 @@ func GetMacaddressFromIP(ip string) string {
result, _ := PSCommandOutputNoSplit(cmd)
return strings.TrimSpace(result)
}
// 电源管理
func PowerRestartForNow(pc string) error {
_, err := PSCommandOutputNoSplit(fmt.Sprintf("Invoke-Command -ComputerName %s -ScriptBlock{ Restart-Computer }", pc))
return err
}
func PowerShutdownForNow(pc string) error {
_, err := PSCommandOutputNoSplit(fmt.Sprintf("Invoke-Command -ComputerName %s -ScriptBlock{ Stop-Computer }", pc))
return err
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment