WMI를 사용하여 C#에서 원격으로 서비스 상태 및 스토리지 정보 가져오기

저는 최근에 pet project에서 여러 서버 인스턴스에서 일부 서비스의 상태를 찾고 이를 웹 페이지에 표시하고 싶었습니다. 그러면 내 응용 프로그램 중 하나라도 상태를 확인하려는 경우 볼 단일 페이지가 있습니다 모든 서버 인스턴스에서 서비스가 중지되었습니다. 또한 동일한 페이지에서 이러한 서비스를 시작하거나 중지할 수 있기를 원했습니다. 이렇게 하면 더 이상 서비스를 확인하기 위해 원격 서버에 로그인할 필요가 없습니다. 그리고 추가 기능으로서 빨리 채워지는 드라이브에 조치를 취할 수 있도록 이러한 서버의 스토리지 정보를 볼 수 있기를 원했습니다.

이러한 웹 앱을 만드는 가장 쉬운 방법을 찾아내려고 하는 동안 Windows 기반 운영 체제에서 관리 데이터 및 작업을 위한 인프라인 Windows Management Instrumentation을 발견했습니다. 개발자는 WMI를 사용하여 원격 컴퓨터의 하드웨어 및 소프트웨어를 원격으로 모니터링할 수 있습니다. 관리 코드에 대한 원격 연결은 System.Management 네임스페이스를 통해 수행됩니다.

System.Management 네임스페이스와 함께 WMI를 사용하여 원격으로 서비스 및 스토리지 정보를 가져오는 방법을 살펴보겠습니다.

ConnectionOptions 설정


System.Management 네임스페이스의 ConnectionOptions 클래스는 WMI 연결에 필요한 모든 설정을 지정합니다. ConnectionOptions 개체를 만들고 기본 연결 옵션으로 원격 컴퓨터에 연결하기 위해 속성을 설정하지 않고 사용할 수 있습니다. 이 예에서는 원격 서버에 대한 연결 요구 사항을 기반으로 일부 속성을 설정했습니다.

ConnectionOptions connection = new ConnectionOptions();
connection.Username = "User";
connection.Password = "AStrongPassword";
connection.Authority = "ntlmdomain:DOMAINNAME";
connection.EnablePrivileges = true;
connection.Authentication = AuthenticationLevel.Default;
connection.Impersonation = ImpersonationLevel.Impersonate;


ManagementScope를 사용하여 원격 서버에 연결



ManagementScope 클래스는 관리 작업의 범위를 나타냅니다. 특정 경로로 새 ManagementScope을 초기화한 다음 ConnectionOptions 개체를 사용하여 범위 개체를 원격 컴퓨터의 네임스페이스에 연결할 수 있습니다.

ManagementScope scope = new ManagementScope(
                        $"\\\\{serverName}\\root\\CIMV2", connection);
scope.Connect();


ManagementObjectSearcher 및 ObjectQuery를 사용하여 관리 정보 가져오기



ObjectQuery 클래스는 ManagementObjectSearcher에서 쿼리를 지정하는 데 사용됩니다.
ManagementObjectSearcher 클래스는 지정된 쿼리를 기반으로 관리 개체 컬렉션을 검색하는 데 사용됩니다. 이 클래스는 관리 정보 검색에 가장 일반적으로 사용되는 진입점 중 하나입니다. 이 예에서는 LogicalDisk 정보를 가져오기 위해 ObjectQuery을 생성했으며 각 디스크의 정보를 가져오기 위해 ManagementObjectSearcher을 사용하고 있습니다.

ObjectQuery query = new ObjectQuery("SELECT * FROM Win32_LogicalDisk");

ManagementObjectSearcher searcher = new ManagementObjectSearcher(scope, query);

foreach (ManagementObject managementObject in searcher.Get())
{
   Console.WriteLine("Drive Name :" +
                      managementObject["Name"].ToString());
   Console.WriteLine("Volume Size :" +
                      managementObject["Size"].ToString());
   Console.WriteLine("Free Space :" +
                      managementObject["FreeSpace"].ToString());
}


마찬가지로 아래와 같이 서비스 정보를 가져올 수도 있습니다.

ObjectQuery query = new ObjectQuery("SELECT * FROM Win32_Service");

ManagementObjectSearcher searcher = new ManagementObjectSearcher(scope, query);

foreach (ManagementObject managementObject in searcher.Get())
{
   Console.WriteLine("Service Name :" +
                      managementObject["DisplayName"].ToString());
   Console.WriteLine("Service State :" +
                      managementObject["State"].ToString());
}


ManagementObject에서 InvokeMethod() 사용


ManagementObject에서 InvokeMethod() 메서드를 사용하여 비동기식으로 작업을 수행할 수 있습니다. 아래 예제에서 ObjectQuery이 service_name에 저장되어 있는 특정 서비스를 나타내기 위해 ManagementObject을 가져오기 위해 DisplayName을 만들었습니다. 그런 다음 원격 서버에서 비동기적으로 서비스를 시작하는 옵션 없이 InvokeMethod() 메서드를 호출하기 위해 StartService을 호출합니다.

ObjectQuery query = new ObjectQuery("SELECT * FROM Win32_Service where
                                     DisplayName= '" + service_name + "'");

using (ManagementObjectSearcher searcher = new
                                   ManagementObjectSearcher(scope, query))
{
  foreach (ManagementObject myservice in searcher.Get())
  {
     myservice.InvokeMethod("StartService", null);
  }
}


따라서 우리는 System.Management 네임스페이스를 사용하는 방법과 Windows 시스템에서 관리 정보를 가져오고 원격으로 작업을 수행하는 클래스를 보았습니다. 내 Github 프로필 here 에서 만든 전체 ASP .Net Core 웹 앱을 볼 수 있습니다.

나는 당신이 이것을 흥미로웠기를 바랍니다. 읽어 주셔서 감사합니다!

좋은 웹페이지 즐겨찾기