Удалённый перезапуск службы Windows через WMI

Board index Программирование .NET

Description: Программирование с использованием платформы Microsoft.NET

#1by mexan » 09.08.2025, 23:11

WMI (Windows Management Instrumentation) — это встроенный интерфейс Windows, который позволяет управлять удалёнными и локальными компьютерами, в том числе:
  • просматривать и изменять свойства системы,
  • запускать и останавливать службы,
  • перезапускать службы без RDP-доступа,
  • собирать статистику (CPU, память и т.д.).

WMI работает поверх DCOM и требует, чтобы:
  1. На удалённой машине был включён WMI.
  2. Пользователь имел права администратора на удалённом ПК.
  3. Между машинами был доступ по TCP-портам 135 и динамическим портам RPC.

Подготовка удалённого ПК
На удалённой машине нужно:
Включить WMI:
Code: Select all
Enable-PSRemoting -Force
Разрешить удалённый WMI в брандмауэре:
Code: Select all
netsh advfirewall firewall set rule group="Windows Management Instrumentation (WMI)" new enable=yes
Убедиться, что служба Windows Management Instrumentation (winmgmt) запущена.

Логика перезапуска службы
Чтобы перезапустить службу через WMI, мы:
  1. Подключаемся к удалённому ПК через WMI.
  2. Находим службу по имени (ServiceName).
  3. Вызываем метод StopService().
  4. Ждём, пока служба остановится.
  5. Вызываем метод StartService().

Code: Select all
using System;
using System.Management;

class Program
{
    static void Main()
    {
        string remoteComputer = "PC-NAME";       // Имя или IP удалённого ПК
        string username = "DOMAIN\\Username";    // Учётка с правами администратора
        string password = "YourPassword";
        string serviceName = "Spooler";          // Например, диспетчер печати

        try
        {
            ConnectionOptions options = new ConnectionOptions
            {
                Username = username,
                Password = password,
                Authority = "ntlmdomain:DOMAIN", // или "ntlmdomain:WORKGROUP"
                Impersonation = ImpersonationLevel.Impersonate,
                Authentication = AuthenticationLevel.PacketPrivacy,
                EnablePrivileges = true
            };

            string path = $@"\\{remoteComputer}\root\cimv2";
            ManagementScope scope = new ManagementScope(path, options);
            scope.Connect();

            // Находим службу
            ObjectQuery query = new ObjectQuery($"SELECT * FROM Win32_Service WHERE Name = '{serviceName}'");
            ManagementObjectSearcher searcher = new ManagementObjectSearcher(scope, query);

            foreach (ManagementObject service in searcher.Get())
            {
                Console.WriteLine($"Служба: {service["DisplayName"]}, статус: {service["State"]}");

                // Останавливаем службу
                if (service["State"].ToString() == "Running")
                {
                    Console.WriteLine("Останавливаю службу...");
                    service.InvokeMethod("StopService", null);
                    System.Threading.Thread.Sleep(3000);
                }

                // Запускаем службу
                Console.WriteLine("Запускаю службу...");
                service.InvokeMethod("StartService", null);

                Console.WriteLine("Перезапуск завершён.");
            }
        }
        catch (Exception ex)
        {
            Console.WriteLine("Ошибка: " + ex.Message);
        }
    }
}

Разбор кода
ConnectionOptions — задаёт учётные данные для подключения.
ManagementScope — область WMI-запроса, указываем root\cimv2.
Win32_Service — WMI-класс, который описывает службу.
StopService() и StartService() — методы WMI для управления службой.

Возможные ошибки и их решения
Ошибка: Access is denied
Причина: Нет прав администратора
Решение: Запускать с админскими правами, использовать админскую учётку

Ошибка: RPC server unavailable
Причина: Закрыт порт 135 или RPC
Решение: Разрешить WMI и RPC в брандмауэре

Ошибка: The service cannot accept control messages at this time
Причина: Служба в процессе запуска/остановки
Решение: Сделать паузу и повторить команду

Ошибка: Invalid class
Причина: WMI отключен или повреждён
Решение: Запустить winmgmt /verifyrepository
Image
mexan
Администратор
Reputation: 0
Posts: 167
Topics: 129

Return to .NET