多进程监控自动关机工具升级远程关闭多台server——C# works with PowerShell-阿里云开发者社区

开发者社区> 天外归云> 正文

多进程监控自动关机工具升级远程关闭多台server——C# works with PowerShell

简介: 之前给单位做过一个多进程监控的自动关机工具,详见那篇blog。 这次领导又加了需求,说要等进程监控结束后,不止需要关闭主控端server,还需要关闭其他servers。于是就用到了我上篇文章所介绍的知识——通过PowerShell来远程管理计算机。
+关注继续查看

之前给单位做过一个多进程监控的自动关机工具,详见那篇blog

这次领导又加了需求,说要等进程监控结束后,不止需要关闭主控端server,还需要关闭其他servers。于是就用到了我上篇文章所介绍的知识——通过PowerShell来远程管理计算机。

由于PowerShell和C#都是基于.NET的,所以也不需要胶水把这两种语言粘合到一起。可以充分的利用两者各自的优点,结合到一起!(PowerShell在远程管理server这方面是很擅长的。)

于是我修改了之前的工具UI界面,多出了两个textbox,分别用来选择server配置文件(需要关闭的除主控端的server的相关信息都记录在该配置文件中)和PowerShell脚本文件(主要负责远程方面的操作):

server配置文件格式如下,一行对应一台server,每一行中的server ip、用户名、密码用空格隔开:

选用的PowerShell脚本文件代码如下:

function ShutDownRemoteComputers
{
    param($ip,$user,$pwd)
    #winrm s winrm/config/client '@{TrustedHosts=10.1.23.60"}'
    $sen = "'@{TrustedHosts=`""+$ip+"`"}'"
    winrm s winrm/config/client $sen
    $pw = convertto-securestring -AsPlainText -Force -String $pwd
    $cred = new-object -typename System.Management.Automation.PSCredential -argumentlist $user,$pw
    $session = New-PSSession $ip -Credential $cred
    icm $session {shutdown -s -t 0}
}

Winform程序在主控端结束进程检查后,会先关闭server配置文件中的servers,然后关闭主控端server(本机)。

代码如下(粉色部分为新加的和远程相关的主要内容):

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using System.Windows.Forms;
using System.Diagnostics;
using System.Text.RegularExpressions;
using System.IO;
using System.Management.Automation;
using System.Management.Automation.Runspaces;

namespace AutoShutDown2
{
    public partial class MainForm : Form
    {
        public MainForm()
        {
            InitializeComponent();
        }

        private void chooseFileButton_Click(object sender, EventArgs e)
        {
            OpenFileDialog fileName = new OpenFileDialog();
            fileName.Filter = "文本文件|*.*|C#文件|*.cs|所有文件|*.*";
            if (fileName.ShowDialog() == DialogResult.OK)
            {
                filePath.Text = fileName.FileName;
            }
        }

        private void filePath_Click(object sender, EventArgs e)
        {
            filePath.Text = "";
        }

        private void startButton_Click(object sender, EventArgs e)
        {
            if (filePath.Text.ToString().Substring(filePath.Text.Length - 3, 3) == "txt")
            {
                if (Regex.IsMatch(duration.Text, "^([0-9]{1,})$"))
                {
                    if (int.Parse(duration.Text) >= 30)
                    {
                        if (serverFilePath.Text == "")
                        {
                            MessageBox.Show("You should choose a server configuration file first.");
                        }
                        else
                        {
                            MessageBox.Show("PCAS will check with a duration of " + duration.Text + "s.");
                            this.Hide();
                            //Check the processes with the duration.
                            DurationStart();
                        }
                    }
                    else 
                    {
                        MessageBox.Show("The integer number should be greater than 30 seconds.");
                    }
                }
                else
                {
                    MessageBox.Show("You can only type in an integer for duration.");
                    duration.Text = "";
                }
            }
            else 
            {
                MessageBox.Show("You can only choose a txt to be a configuration file.");
                filePath.Text = "";
            }
        }

        private void DurationStart()
        {
            //Check the process's status with the duration.
            System.Timers.Timer tmr = new System.Timers.Timer(int.Parse(duration.Text)*1000);
            tmr.Elapsed += new System.Timers.ElapsedEventHandler(CheckProcess);
            tmr.AutoReset = true;
            tmr.Enabled = true;
        }

        private void CheckProcess(object source, System.Timers.ElapsedEventArgs e)
        {
            //Check the processes's status in the config file.
            using (FileStream fs = new FileStream(filePath.Text, FileMode.Open))
            {
                using (StreamReader sr = new StreamReader(fs))
                {
                    string line;
                    int numOfTheProcesses = 0;
                    while ((line = sr.ReadLine()) != null)
                    {
                        var processes = System.Diagnostics.Process.GetProcesses();
                        foreach (var process in processes)
                        {
                            if (process.ProcessName == line)
                            {
                                //Find the objective process.
                                //MessageBox.Show(line);
                                numOfTheProcesses++;
                            }
                        }
                    }
                    if (numOfTheProcesses == 0)
                    {
                        //No such process, shut down the computer.
                        //MessageBox.Show("The computer is ready to be shut down.");
                        //Shut down the computer
                        ShutDown();
                    }
                    sr.Close();
                }
                fs.Close();
            }
        }

        private void ShutDown()
        {
            //Shut down the other computers.
            ShutDownOthers(serverFilePath.Text, scriptPathText.Text);
            //Shut down this computer.
            System.Diagnostics.Process myProcess = new System.Diagnostics.Process();
            myProcess.StartInfo.FileName = "cmd.exe";
            myProcess.StartInfo.UseShellExecute = false;
            myProcess.StartInfo.RedirectStandardInput = true;
            myProcess.StartInfo.RedirectStandardOutput = true;
            myProcess.StartInfo.RedirectStandardError = true;
            myProcess.StartInfo.CreateNoWindow = true;
            myProcess.Start();
            Thread.Sleep(3000);
            myProcess.StandardInput.WriteLine("shutdown -s -t 0"); 
            //MessageBox.Show("Shut down self.");
        }

        private void ShutDownOthers(string serverFilePath,string scriptPath)
        {
            //Read servers from the server file and shut down the servers.
            //Read the servers.
            string filePath = serverFilePath;
            using (FileStream fs1 = new FileStream(filePath, FileMode.Open))
            {
                try
                {
                    using (StreamReader sr1 = new StreamReader(fs1))
                    {
                        string line;
                        try
                        {
                            while ((line = sr1.ReadLine()) != null)
                            {
                                var elements = line.Split();
                                string ip = elements[0].ToString();
                                string user = elements[1].ToString();
                                string pwd = elements[2].ToString();
                                //Shut down the server checked from the line.
                                //Open the PowerShell.
                                using (Runspace runspace = RunspaceFactory.CreateRunspace())
                                {
                                    //MessageBox.Show("Run PowerShell.");
                                    string script = File.ReadAllText(scriptPath);
                                    runspace.Open();
                                    PowerShell ps = PowerShell.Create();
                                    ps.Runspace = runspace;
                                    ps.AddScript(script);
                                    ps.Invoke();
                                    ps.AddCommand("ShutDownRemoteComputers").AddParameter("ip", ip).AddParameter("user", user).AddParameter("pwd", pwd);
                                    ps.Invoke();
                                    //MessageBox.Show("Shut down others");
                                }
                            }
                        }
                        finally
                        {
                            sr1.Close();
                        }
                    }
                }
                finally
                {
                    fs1.Close();
                }
            }       
        }

        private void chooseServerFileButton_Click(object sender, EventArgs e)
        {
            OpenFileDialog fileName = new OpenFileDialog();
            fileName.Filter = "文本文件|*.*|C#文件|*.cs|所有文件|*.*";
            if (fileName.ShowDialog() == DialogResult.OK)
            {
                serverFilePath.Text = fileName.FileName;
            }
        }

        private void serverFilePath_Click(object sender, EventArgs e)
        {
            serverFilePath.Text = "";
        }

        private void scriptPathText_Click(object sender, EventArgs e)
        {
            scriptPathText.Text = "";
        }

        private void chooseScriptButton_Click(object sender, EventArgs e)
        {
            OpenFileDialog fileName = new OpenFileDialog();
            fileName.Filter = "文本文件|*.*|C#文件|*.cs|所有文件|*.*";
            if (fileName.ShowDialog() == DialogResult.OK)
            {
                scriptPathText.Text = fileName.FileName;
            }
        }
    }
}

至于远程所需要在主控端和被控端所做的准备工作,一语概括就是在主控端和被控端都Enable-PSRemoting(全选A),然后互相配置Winrm信任就ok了(这两步都是在PowerShell中进行的,详见通过PowerShell来远程管理计算机这篇blog)。

//Open the PowerShell.
using (Runspace runspace = RunspaceFactory.CreateRunspace())
{
     //MessageBox.Show("Run PowerShell.");
     string script = File.ReadAllText(scriptPath);
     runspace.Open();
     PowerShell ps = PowerShell.Create();
     ps.Runspace = runspace;
     ps.AddScript(script);
     ps.Invoke();
     ps.AddCommand("ShutDownRemoteComputers")
        .AddParameter("ip", ip)
        .AddParameter("user", user)
        .AddParameter("pwd", pwd);
     ps.Invoke();
}

上面这段代码就是在C#中调用PowerShell脚本的关键。想要在C#中引用PowerShell需要事先add reference:

找到这个reference最快捷的方式就是在PowerShell中输入[psobject].Assembly.Location

然后在代码里using相应的命名空间就可以了:

亲测通过后获得了相关部门领导赠送的可爱多一个。

版权声明:本文内容由阿里云实名注册用户自发贡献,版权归原作者所有,阿里云开发者社区不拥有其著作权,亦不承担相应法律责任。具体规则请查看《阿里云开发者社区用户服务协议》和《阿里云开发者社区知识产权保护指引》。如果您发现本社区中有涉嫌抄袭的内容,填写侵权投诉表单进行举报,一经查实,本社区将立刻删除涉嫌侵权内容。

相关文章
用C#写一个多进程监控自动关机工具
因为据说某server开着就很贵,所以我们跑完测试的job后就要赶紧关机才行,但是测试的job要跑很久,过程中又不需要干什么,所以就得有个守家的,有时候会走很晚。如果有一个自动化关机的工具就好了,当指定的进程结束了以后系统就会自动关机。
793 0
客户端自动升级的一个代码例子【C/S】
经常看到有问客户端自动更新问题,把一个以前看到的常用的方法整理了一下,放在网上供大家使用。 详细代码下载地址 http://cid-56b433ad3d1871e3.office.live.com/self.
589 0
Linux网络进程监控工具nethogs
  Linux网络监控工具nethogs 标签: 监控工具linux 2015-12-17 22:06 448人阅读 评论(0) 收藏 举报  分类: linux(40)  版权声明:本文为博主原创文章,未经博主允许不得转载。
963 0
redis-server进程CPU百分百问题
结论: 待确认是否为redis的BUG,原因是进程实际占用的内存远小于配置的最大内存,所以不会是内存不够需要淘汰。 CPU百分百redis-server进程集群状态: slave 解决办法: 使用gdb将d.ht[0].used的值改为0 问题原因: dictGetRandomKey()过程中, 无法走到分支“if (dictSize(d) == 0) return NULL;”, 导致函数dbRandomKey()进入死循环。
2468 0
【终极解决方案】为应用程序池“XXX”提供服务的进程在与 Windows Process Activation Service 通信时出现严重错误。该进程 ID 为“XXXX”。数据字段包含错误号。
原文:【终极解决方案】为应用程序池“XXX”提供服务的进程在与 Windows Process Activation Service 通信时出现严重错误。该进程 ID 为“XXXX”。数据字段包含错误号。
2233 0
Python WMI获取Windows系统信息 监控系统
1 #!/usr/bin/env python 2 # -*- coding: utf-8 -*- 3 #http://www.cnblogs.com/liu-ke/ 4 import wmi 5 import os 6 import sys 7 import...
1034 0
kill命令"-1"这个参数到底是杀进程还是reload?(转)
kill-1:重新读取一次参数的配置文件 (类似 reload) 这句话给我的感觉是把进程杀掉后重启进程,即 reload。而我查了下 man kill,-1 对应的 signal 是 SIGHUP,用个find / -perm +7000 > /dev/null 2>&1 &命令试验了下确实是杀进程,鸟哥说反了? SIGHUP - hangup or exit a foreground running process from a terminal 原因:对daemon是重新读取配置,对普通进程就是杀掉。
670 0
SharePoint自动化系列——通过PowerShell创建SharePoint List Items
转载请注明出自天外归云的博客园:http://www.cnblogs.com/LanTianYou/ 代码如下(保存到本地ps1文件中,右键run with PowerShell即可): Add-PSSnapin microsoft.
711 0
SharePoint自动化系列——通过PowerShell创建SharePoint Lists
转载请注明出自天外归云的博客园:http://www.cnblogs.com/LanTianYou/ 代码如下(保存到本地ps1文件中,右键run with PowerShell即可): Add-PSSnapin microsoft.
680 0
+关注
天外归云
测试开发工程师,目前就职于网易。
200
文章
0
问答
文章排行榜
最热
最新
相关电子书
更多
《2021云上架构与运维峰会演讲合集》
立即下载
《零基础CSS入门教程》
立即下载
《零基础HTML入门教程》
立即下载