首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> .NET 網頁程式設計 >> C# >> 關於C#

C# 透過 WMI 遠端重啟電腦完整實作指南

     編輯:關於C#

Windows Management Instrumentation (WMI) 提供統一管理介面,可遠端查詢系統資訊、執行管理操作 (如重啟、關機、服務控制)。本文示範使用 System.Management 命名空間,透過 ConnectionOptions、ManagementScope、ManagementObjectSearcher 呼叫 Win32_OperatingSystem.Reboot() 方法實現遠端重啟。

WMI 遠端操作前置條件

  • 目標電腦啟用 Windows Management Instrumentation 服務 (預設啟動)。
  • 防火牆允許 WMI 遠端管理 (埠 135 + DCOM 動態埠),或預設共用 \\Admin$ 存取。
  • 呼叫端具備目標電腦 本機系統管理員 權限帳號密碼。
  • 網路連通:可解析主機名/IP、ICMP/Ping 通。

核心類別與流程

類別用途
ConnectionOptions設定認證 (Username, Password, Authority, Impersonation, Authentication)
ManagementScope連線範圍:\\{host}\root\cimv2
ObjectQueryWQL 查詢:SELECT * FROM Win32_OperatingSystem
ManagementObjectSearcher執行查詢取得 ManagementObjectCollection
ManagementObject代表單一管理物件,呼叫 InvokeMethod("Reboot", args)

完整程式碼範例 (WinForms)


using System;
using System.Management;
using System.Windows.Forms;

public class RemoteRebootForm : Form
{
    private TextBox txtHost, txtUser, txtPass;
    private Button btnReboot;

    public RemoteRebootForm()
    {
        InitializeComponent();
    }

    private async void btnReboot_Click(object sender, EventArgs e)
    {
        string host = txtHost.Text.Trim(); // 主機名或 IP
        string user = txtUser.Text.Trim();
        string pass = txtPass.Text;

        if (string.IsNullOrEmpty(host) || string.IsNullOrEmpty(user))
        {
            MessageBox.Show("請輸入主機名/IP 與管理員帳號");
            return;
        }

        btnReboot.Enabled = false;
        btnReboot.Text = "執行中...";

        try
        {
            await Task.Run(() => RebootRemote(host, user, pass));
            MessageBox.Show($"已送出重啟指令至 {host}", "成功", MessageBoxButtons.OK, MessageBoxIcon.Information);
        }
        catch (Exception ex)
        {
            MessageBox.Show($"失敗: {ex.Message}", "錯誤", MessageBoxButtons.OK, MessageBoxIcon.Error);
        }
        finally
        {
            btnReboot.Enabled = true;
            btnReboot.Text = "遠端重啟";
        }
    }

    private void RebootRemote(string host, string user, string password)
    {
        // 1. 連線選項
        var options = new ConnectionOptions
        {
            Username = user,
            Password = password,
            // Authority = "ntlmdomain:DOMAIN", // 網域環境
            Impersonation = ImpersonationLevel.Impersonate,
            Authentication = AuthenticationLevel.PacketPrivacy, // 加密傳輸
            EnablePrivileges = true // 啟用 SeShutdownPrivilege 等特權
        };

        // 2. 管理範圍
        string scopePath = $@"\\{host}\root\cimv2";
        using (var scope = new ManagementScope(scopePath, options))
        {
            scope.Connect(); // 建立連線,失敗拋出 ManagementException/UnauthorizedAccessException
            
            // 3. 查詢作業系統物件
            var query = new ObjectQuery("SELECT * FROM Win32_OperatingSystem");
            using (var searcher = new ManagementObjectSearcher(scope, query))
            using (var collection = searcher.Get())
            {
                foreach (ManagementObject os in collection)
                {
                    // 4. 呼叫 Reboot 方法 (無參數)
                    object[] args = null; // 或 new object[] { }
                    os.InvokeMethod("Reboot", args);
                    // 同步呼叫,回傳時重啟已啟動
                }
            }
        }
    }
    // InitializeComponent 略
}

主控台應用程式精簡版


class Program
{
    static int Main(string[] args)
    {
        if (args.Length < 3)
        {
            Console.WriteLine("Usage: RemoteReboot.exe   ");
            return 1;
        }
        try
        {
            RebootRemote(args[0], args[1], args[2]);
            Console.WriteLine("Reboot command sent.");
            return 0;
        }
        catch (Exception ex)
        {
            Console.Error.WriteLine($"Error: {ex.Message}");
            return 2;
        }
    }
    // RebootRemote 方法同上
}

常見錯誤代碼與解決

例外/錯誤原因解決
Access denied (0x80070005)帳號非本機管理員、UAC 封鎖、LocalAccountTokenFilterPolicy確認帳號權限、目標機登錄表 HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\System\LocalAccountTokenFilterPolicy=1 (工作群組)
RPC server unavailable (0x800706BA)防火牆阻擋、WMI 服務未啟動、主機名解析失敗防火牆開放 WMI、啟動服務、IP 直連測試
Invalid namespace路徑錯誤 (應為 root\cimv2)檢查 scopePath 字串格式
Privilege not held缺少 SeShutdownPrivilegeEnablePrivileges=true、帳號需具備關機權限 (本機管理員預設有)

替代方案:Win32 API / PsExec / PowerShell Remoting

  • InitiateSystemShutdownEx (advapi32.dll):需開啟遠端登錄服務、調整權限,較 WMI 複雜。
  • PsExec (Sysinternals):psexec \\host -u user -p pass shutdown /r /t 0,部署簡單但需複製執行檔。
  • PowerShell Remoting:Enter-PSSession -ComputerName host -Credential cred; Restart-Computer -Force,需啟用 WinRM、設定 TrustedHosts。
  • Shutdown.exe:shutdown /m \\host /r /t 0 /c "原因",需 RPC/檔案共用通暢。

安全性最佳實務

  • **不要**在程式碼/設定檔硬編碼密碼,使用 Windows Credential Manager、DPAPI、Azure Key Vault 等安全儲存。
  • 網域環境優先使用 Kerberos 委派,避免傳遞明文密碼 (Ntlmdomain authority)。
  • 記錄稽核日誌:誰、何時、對哪台機器發出重啟指令。
  • 生產環境加入確認機制 (二次驗證、審核流程) 避免誤操作。

WMI 是 Windows 管理自動化的核心基礎設施。掌握 ConnectionOptions、ManagementScope、InvokeMethod 核心模式,不僅能實現遠端重啟,更可延伸至服務控制、軟體部署、效能監控、事件日誌查詢等企業級管理自動化場景。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved