Как найти имя пользователя на удаленном компьютере?

У меня есть IP-адреса некоторых компьютеров в моей сети. Есть ли какой-либо инструмент командной строки, такой как PsExec, который может принимать IP-адрес в качестве входных данных и узнавать имя пользователя, вошедшего в систему в данный момент? Я могу устанавливать что-то на свою рабочую станцию, но не на другие. Я также могу запустить Metasploit/NMap/любую другую подобную программу на своей рабочей станции.


Для ящиков Windows установите psLoggedOn. Он сообщает вам, кто в данный момент вошел в систему через console/rdp, а кто подключен через сетевые ресурсы.

Если вы не хотите устанавливать приложение, есть также команды qwinsta и query сеанс, который можно запустить из командной строки следующим образом:

  qwinsta/server: name_of_host или запрос сеанс/сервер: name_of_host  

10

Попробуйте следующее:

  wmic.exe/node: "IP-or-HostName" ComputerSystem Получить имя пользователя  

Пример:

  wmic.exe /node:"172.28.1.100 "ComputerSystem Получить имя пользователя  

Вывод:

  UserNameDOMAIN  User  

(Да, значение /node должно быть заключено в кавычки)

Улучшите этот ответ
отредактировано 17 июня ’17 в 3:44
Георгий Чахидзе
15511 серебряных знаков66 бронзовых знаков
ответил 21 июня ’12 в 07:21
  • 2
    Работал у меня . Мне нужно было запустить cmd от имени администратора домена, иначе я получил ошибку «Доступ запрещен». — Отиэль, 22 янв., 15:01
  • По-видимому, у вас две учетные записи: первая и вторая. Возможно, вы захотите использовать это руководство Справочного центра и попросить персонал суперпользователя объединить учетные записи. — robinCTS 03 авг. ’18 в 13:38
добавить комментарий |

Попробуйте это:

  wmic.exe/node: "IP-or-  HostName "ComputerSystem Получить имя пользователя  

Пример:

  wmic.exe/node:"172.28.1. 100 "ComputerSystem Получить имя пользователя  

Вывод:

  UserNameDOMAIN  User  

(Да, значение /node должно быть заключено в кавычки)


1

Ознакомьтесь с MetaLAN

Улучшите этот ответ
ответил 24 мая 2010 г. в 15:12
добавить комментарий |

Ознакомьтесь с MetaLAN


0

Вы можете сделать это с помощью следующих команд. Это работает, потому что любой зарегистрированный пользователь запустит explorer.exe автоматически после входа в систему:

for/f "TOKENS = 1,2, *" %% a in ('tasklist/s% PCNAME%/FI "IMAGENAME eq explorer.exe"/FO LIST/V') do if/ i "%% a %% b" == "Имя пользователя:" (установить domain_user = %% c) для/f "TOKENS = 1,2 DELIMS = " %% a in ("% domain_user%") установить domain = %% a && set user = %% b

Улучшите этот ответ
отредактировано 7 ноября ’17 в 18:26
I say Reinstate Monica
22.7k1616 золотых знаков8181 серебряных знаков119119 бронзовых знаков
ответил 7 ноября ’17 в 17:59
добавить комментарий |

Вы можете сделать это с помощью следующих команд. Это работает, потому что любой вошедший в систему пользователь будет запускать explorer.exe автоматически после входа в систему:

  for/f "TOKENS = 1,2, *" %% a in ('tasklist /s% PCNAME%/FI "IMAGENAME eq explorer.exe"/FO LIST/V ') do if/i "%% a %% b" == "Имя пользователя:" (установить domain_user = %% c) для/ f "TOKENS = 1,2 DELIMS = " %% a in ("% domain_user%") do set domain = %% a && set user = %% b  


Как мне получить имя компьютера с удаленного компьютера с Windows?

Я пытаюсь найти способ получить имя компьютера с IP-адреса в C #, но все ответы, помеченные в Интернете как поиск имени машины или имени компьютера , фактически получают имя хоста, а не Имя компьютера. Если вы перейдете в Панель управления> система, в этом меню есть свойство «Имя компьютера» … Я ищу это значение на удаленном компьютере. AFAIK, HOSTNAME будет = полное имя компьютера, ЕСЛИ нет сопоставления DNS. Проблема в том, что эти серверы, над которыми я работаю, имеют сопоставление DNS, поэтому имя хоста возвращает их адрес DNS.

Не стесняйтесь поправлять меня в технических деталях, если я сказал что-то не так, но вопрос останется.

Я пробовал это:

  IPHostEntry hostEntry = Dns.GetHostEntry (_ip); _ hostname = hostEntry.HostName;   

, но, очевидно, возвращает HostName, а не имя компьютера. Я мог бы также согласиться на возвращаемое свойство «Полное имя компьютера», а затем просто удалить ненужные части строки, чтобы показать «Имя компьютера».

Кроме того, если вы знаете, как это сделать сделайте это с помощью PowerShell, мне тоже нужна ваша помощь. Я все равно размещаю движок PowerShell в своем приложении … так что могу просто передать вашу команду в PowerShellInstance.AddScript (_yourCommandHere); и передать ее возврат обратно в мое приложение.

Посоветуйте, возможно ли это сделать.

@DanielAWhiteEDIT: Как это дубликат указанного ответа? Ответ в этом сообщении точно говорит о том, что я написал как проблему для этого вопроса. Нет, это не дубликат, потому что я НЕ ищу имя хоста. Я специально сказал вам в своем OP, что я не искал этого, и они не спрашивают, о чем я спрашиваю. Если нет возможности получить имя компьютера из IP-адреса в .NET, просто ответьте на вопрос этим.

Из «дубликата»:

Ну, не у каждого IP-адреса есть имя. Однако, учитывая IPAddress, вы можете использовать> Dns.GetHostEntry, чтобы попытаться решить эту проблему. Также обратите внимание, что если это маршрутизатор NAT>, вы получите IP-адрес маршрутизатора, а не его фактическую> машину.

посмотрите на мой OP … .GetHostEntry DOESN Я работаю. вот и вся причина, по которой я нашел время, чтобы напечатать это.

спасибо

ДВОЙНОЕ РЕДАКТИРОВАНИЕ: у BACON есть ответ, как это сделать; этот пост был заблокирован, потому что кто-то не нашел времени, чтобы прочитать то, что я написал. Поскольку он заблокирован, вы также не можете дать лучшего ответа. Но вот как я это сделал, сохранив это здесь для дальнейшего использования:

 //объявляем строку как имя нашей машины string machineName; //объявляем строку, которую мы передадим в PowerShell позже, поскольку скрипт//присваивает имя хоста или строку IP getComputer = "$ ip =" + "" "+ ip +"  "" + " r  n"; //добавляем в строку this, которая получает Win32_ComputerSystem .. @BACON знал, что я был после//мы передаем это обратно, используя | select -expand Name getComputer + = "get-wmiobject -class Win32_ComputerSystem -property Name -ComputerName" +  "$ ip" + "| select -expand Name"; //создаем экземпляр PowerShell с помощью using (PowerShell PowerShellInstance = PowerShell.Create ()) {//добавляем скрипт в наш экземпляр ps PowerShellInstance. AddScript (getComputer); //создать экземпляр коллекции для размещения нашего вывода из PS//вы также, вероятно, могли бы просто создать экземпляр PSObject вместо коллекции ... но это может быть полезно, если изменить, чтобы получить массив имен компьютеров ... и вот как я сделал  поэтому он не может проверить Collection  psOutput; //назначаем psOutput из метода .Invoke () psOutput = PowerShellInstance.Invoke (); //вы можете обрезать этот цикл и избавиться от него только для одного IP-адреса foreach (var item в psOutput) {//machineName = MachineName || ComputerName string НЕ hostname machineName = item.BaseObject.ToString ();  }}  

О, и, согласно комментариям, вам нужно разрешить WMI через брандмауэр Windows, чтобы это работало. У меня это сработало отлично.


1

Воспроизведение моих комментариев в качестве ответа …

Представьте, что у нас есть интерфейс , подобный этому …

  пространство имен SO56585341 {открытый интерфейс IComputerInfoSource {строка GetComputerName ();  }}  

Есть несколько способов реализовать это, чтобы получить имя машины локального компьютера . Самый простой — вернуть значение свойства Environment.MachineName

  пространство имен SO56585341 {открытый класс EnvironmentClassComputerInfoSource: IComputerInfoSource {общедоступная строка  GetComputerName () {вернуть System.Environment.MachineName;  }}}  

Вы также можете использовать метод Environment.GetEnvironmentVariable () для получения значения % ComputerName% переменная среды …

  пространство имен SO56585341 {открытый класс EnvironmentVariableComputerInfoSource: IComputerInfoSource {общедоступная строка GetComputerName () {return System.Environment.GetEnvironmentVariable ("ComputerName");  }}}  

Вы можете p/вызвать функцию Windows API GetComputerName () , которая и является тем, что Environment.MachineName делает за кулисами …

  с использованием System.Runtime.InteropServices; с использованием System.Text; пространство имен SO56585341 {открытый класс WinApiComputerInfoSource: IComputerInfoSource {private const int MAX_COMPUTERNAME_LENGTH =  15;  [DllImport ("Kernel32.dll", CallingConvention = CallingConvention.Winapi, CharSet = CharSet.Auto, SetLastError = true)] частный статический extern bool GetComputerName (StringBuilder lpBuffer, ref int nSize);  общедоступная строка GetComputerName () {int maxCapacity = MAX_COMPUTERNAME_LENGTH + 1;  StringBuilder nameBuilder = новый StringBuilder (maxCapacity, maxCapacity);  if (! GetComputerName (nameBuilder, ref maxCapacity)) {//TODO: обработка ошибок ... throw new System.ComponentModel.Win32Exception ();  } return nameBuilder.ToString ();  }}}  

Вы можете использовать WMI для получения свойства Name одноэлементного класса Win32_ComputerSystem . Вы можете сделать это, создав экземпляр ManagementClass для класса Win32_ComputerSystem и вызвав для него GetInstances () , чтобы получить массив, содержащий единственный экземпляр …

  using System.Linq; using System.Management; namespace SO56585341 {public class WmiClassComputerInfoSource: IComputerInfoSource {public string GetComputerName () {using (ManagementClass  computerSystemClass = new ManagementClass ("Win32_ComputerSystem")) с использованием (ManagementObjectCollection computerSystemCollection = computerSystemClass.GetInstances ()) с использованием (ManagementObject computerSystem = computerSystemCollection.Cast  () .Single ()) return (string) computerSystem;  }}}  

… или создав ManagementObjectSearcher и используя его для Get () одинокий Win32_ComputerSystem instance …

  using System.Linq; using System.Management; namespace SO56585341 {открытый класс WmiSearcherComputerInfoSource: IComputerInfoSource {общедоступная строка  GetComputerName () {ObjectQuery computerSystemQuery = новый SelectQuery ("Win32_ComputerSystem");  using (ManagementObjectSearcher computerSystemSearcher = new ManagementObjectSearcher (computerSystemQuery)) с использованием (ManagementObjectCollection computerSystemCollection = computerSystemSearcher.Get ()) с использованием (ManagementObject computerSystem = computerSystemCollection.Cast  () .Single () return () () return ()  ;  }}}  

Наконец, значение, возвращаемое всеми вышеперечисленными методами, кажется, в конечном итоге сохраняется в реестре, поэтому, если вы не против полагаться на эту деталь реализации, вы можете получить его оттуда напрямую …

  using Microsoft.Win32; пространство имен SO56585341 {открытый класс RegistryComputerInfoSource: IComputerInfoSource {общедоступная строка GetComputerName () {//См. также @ "SYSTEM   CurrentControlSet  Control  ComputerName  ActiveComputerName  "//https://www.oreilly.com/library/view/windows-nt-workstation/9781565926134/10_chapter-07.html const string valueParentKeyPath = @" SYSTEM  CurrentControlSet  Control   Имя компьютера  Имя компьютера  ";  используя (RegistryKey parentKey = Registry.LocalMachine.OpenSubKey (valueParentKeyPath, false)) return (string) parentKey.GetValue ("ComputerName");  }}}  

Что касается получения того же значения с удаленного компьютера , то будут работать только три последние реализации, указанные выше, хотя с минимальной настройкой. Во-первых, чтобы завершить этот пример IComputerInfoSource , давайте создадим abstract класс для хранения «параметра» имени/адреса удаленного компьютера …

  пространство имен SO56585341 {общедоступный абстрактный класс RemoteComputerInfoSource: IComputerInfoSource {общедоступная строка RemoteNameOrIp {get;  } защищенный RemoteComputerInfoSource (строка nameOrIp) {RemoteNameOrIp = nameOrIp ??  выбросить новое исключение System.ArgumentNullException (nameof (nameOrIp));  } общедоступная абстрактная строка GetComputerName ();  }}  

Получение экземпляра Win32_ComputerSystem через ManagementClass просто превращается в вопрос явной передачи ему ManagementPath , который также указывает NamespacePath и Server

  using System.Linq; using System.Management; namespace SO56585341 {общедоступный класс RemoteWmiClassComputerInfoSource: RemoteComputerInfoSource {общедоступный RemoteWmiClassComputerInfoSource (строка nameOrIp): base (nameOrIp) {} общедоступная переопределенная строка GetComputerNameSame () {путь к системе управления) (путь управления классом)  "Win32_ComputerSystem", NamespacePath = @ "root  cimv2", Server = RemoteNameOrIp};  using (ManagementClass computerSystemClass = new ManagementClass (computerSystemPath)) с использованием (ManagementObjectCollection computerSystemCollection = computerSystemClass.GetInstances ()) с использованием (ManagementObject computerSystem = computerSystemCollection.Cast  () .Single ()) return (string) computerSystem [  ;  }}}  

A ManagementObjectSearcher можно использовать, передав аналогичный ManagementPath , заключенный в ManagementScope

  с использованием System.Linq; с использованием System.Management; пространство имен SO56585341 {открытый класс RemoteWmiSearcherComputerInfoSource: RemoteComputerInfoSource {public RemoteWmiSearcherComputerInfoSource (строка nameOrIp):  base (nameOrIp) {} общедоступная строка переопределения GetComputerName () {ManagementScope computerSystemScope = new ManagementScope (new ManagementPath () {NamespacePath = @ "root  cimv2", Server = RemoteNameOrIp});  ObjectQuery computerSystemQuery = новый SelectQuery ("Win32_ComputerSystem");  using (ManagementObjectSearcher computerSystemSearcher = new ManagementObjectSearcher (computerSystemScope, computerSystemQuery)) с использованием (ManagementObjectCollection computerSystemCollection = computerSystemSearcher.Get ()) с использованием (ManagementObject computerSystem = computerSystemCollection.Cast  

Для запроса удаленного реестра просто требуется дополнительный вызов OpenRemoteBaseKey () для получения дескриптора корня удаленного куста. ..

  с использованием Microsoft.Win32; пространство имен SO56585341 {открытый класс RemoteRegistryComputerInfoSource: RemoteComputerInfoSource {общедоступный RemoteRegistryComputerInfoSource (строка nameOrIp): base (nameOrIp) {} общедоступная строка переопределения GetComputerName () //См. Также @ "SYSTEM  CurrentControlSet  Control  ComputerName  ActiveComputerName "//https://www. oreilly.com/library/view/windows-nt-workstation/9781565926134/10_chapter-07.html const string valueParentKeyPath = @ "SYSTEM  CurrentControlSet  Control  ComputerName  ComputerName ";  using (RegistryKey baseKey = RegistryKey.OpenRemoteBaseKey (RegistryHive.LocalMachine, RemoteNameOrIp)) using (RegistryKey parentKey = baseKey.OpenSubKey (valueParentKeyPath, false)) return (string) parentKey.GetValue ("ComputerName");  }}}  

Если вы скомпилируете весь приведенный выше код в проект, вы можете использовать следующий класс Program для его тестирования …

  using System; using System.Collections.Generic; using System.Linq; using System.Reflection; пространство имен SO56585341 {public static class Program {private const string TestHost = "127.0.0.1  ";  public static void Main () {//Получить все неабстрактные классы в исполняемой сборке, которые реализуют IComputerInfoSource IEnumerable  computerInfoSourceTypes = Assembly.GetExecutingAssembly (). GetTypes () .Where (type => type.IsClass &&! type.  IsAbstract && typeof (IComputerInfoSource) .IsAssignableFrom (тип)); //Для каждого конструктора в каждом классе-кандидате ... foreach (введите computerInfoSourceType в computerInfoSourceTypes) foreach (конструктор ConstructorInfo в computerInfoSourceType.GetConstructors ()) {ParameterInfo [] constructorParameters = constructor.GetParameters ();  объект [] instanceParameters; //Если конструктор не принимает параметров ... if (! ConstructorParameters.Any ()) instanceParameters = Array.Empty  (); //... или один строковый параметр ... иначе if (constructorParameters.Length == 1 && constructorParameters [0] .ParameterType == typeof (string)) instanceParameters = new object [1] {TestHost}; //... иначе пропустить этот конструктор else continue; //Создание экземпляра класса с использованием параметров конструктора, указанных выше IComputerInfoSource computerInfoSource = (IComputerInfoSource) constructor.Invoke (instanceParameters);  строковый результат;  попробуйте {результат = computerInfoSource.GetComputerName ();  } catch (Exception ex) {результат = ex.ToString ();  } Console.WriteLine ("новый {0} ({1}). {2} (): " {3}  "", computerInfoSourceType.Name, string.Join (",", instanceParameters.Select (value =>  $ "" {значение}  "")), nameof (IComputerInfoSource.GetComputerName), результат);  }}}}  

Я обнаружил, что этот код работает независимо от того, установлено ли в TestHost имя компьютера, CNAME или IP-адрес. Обратите внимание, что классы Remote * ComputerInfoSource завершатся ошибкой, если …

  • Соответствующая служба ( RemoteRegistry или Winmgmt ) не запущен на удаленном компьютере, или …
  • Соответствующее правило брандмауэра (например, WMI-WINMGMT-In- TCP ) не включен на удаленном компьютере, или …
  • Код не запускается от имени пользователя с правами доступа к удаленной службе.

Что касается PowerShell, у вас должна быть возможность перенести код любого из вышеперечисленных методов с C # (либо прямой перевод или с использованием возможностей PowerShell) и заключите их в вызов Invoke-Command , поскольку этот код будет выполняться локально на удаленном компьютере. Например …

  Invoke-Command -ComputerName $ nameOrIp -ScriptBlock {$ Env: COMPUTERNAME}  

… или …

  Invoke-Command -ComputerName $ nameOrIp -ScriptBlock {# См. также 'HKLM:  SYSTEM  CurrentControlSet  Control  ComputerName  ActiveComputerName ' # https://www.oreilly.com/library/view/windows-nt-workstation/9781565926134/10_chapter-07.html Get-ItemProperty -Path 'HKLM:  SYSTEM  CurrentControlSet  Control  ComputerName  ComputerName ' -Name 'ComputerName'}   

PowerShell также имеет Get-WmiObject

  Get-WmiObject -  Класс 'Win32_ComputerSystem' -ComputerName $ nameOrIp -Property 'Name'  

… и командлеты Get-CimInstance

  Get-CimInstance -Class 'Win32_ComputerSystem' -ComputerName $ nameOrIp -Property 'Name'  

… которые значительно упрощают работу с WMI . В общем, я бы рекомендовал использовать WMI , поскольку его довольно легко использовать из C # и PowerShell как для локальных, так и для удаленных запросов, и он существует именно для этой цели — получения сведений о системе без необходимости знать об основных вызовах API или представлении данных.

Обратите внимание, что при использовании командлетов Invoke-Command или Get-CimInstance , служба WinRM должна быть запущена на удаленном компьютере и должно быть включено соответствующее правило брандмауэра (например, WINRM-HTTP-In-TCP-NoScope ). Кроме того, при передаче IP-адреса в параметр -ComputerName любого из этих командлетов этот адрес должен совпадать со значением WSMan: localhost Client TrustedHosts код>. Если вам нужно просканировать всю сеть по IP-адресу, я проверил и обнаружил, что TrustedHosts принимает подстановочный знак * , но не принимает маски подсети, нотацию CIDR или ? подстановочный знак.

Улучшить этот ответ
отредактировано 14 января ’20 в 17:15
ответил 14 января ’20 в 16:55
добавить комментарий |

Воспроизведение моих комментариев в качестве ответа …

Представьте себе у нас был такой интерфейс

  пространство имен SO56585341 {открытый интерфейс IComputerInfoSource {строка GetComputerName ();  }}  

Есть несколько способов реализовать это, чтобы получить имя машины локального компьютера . Самый простой — вернуть значение свойства Environment.MachineName

  пространство имен SO56585341 {открытый класс EnvironmentClassComputerInfoSource: IComputerInfoSource {общедоступная строка  GetComputerName () {вернуть System.Environment.MachineName;  }}}  

Вы также можете использовать метод Environment.GetEnvironmentVariable () для получения значения % ComputerName% переменная среды …

  пространство имен SO56585341 {открытый класс EnvironmentVariableComputerInfoSource: IComputerInfoSource {общедоступная строка GetComputerName () {return System.Environment.GetEnvironmentVariable ("ComputerName");  }}}  

Вы можете p/вызвать функцию Windows API GetComputerName () , которая и является тем, что Environment.MachineName делает за кулисами …

  с использованием System.Runtime.InteropServices; с использованием System.Text; пространство имен SO56585341 {открытый класс WinApiComputerInfoSource: IComputerInfoSource {private const int MAX_COMPUTERNAME_LENGTH =  15;  [DllImport ("Kernel32.dll", CallingConvention = CallingConvention.Winapi, CharSet = CharSet.Auto, SetLastError = true)] частный статический extern bool GetComputerName (StringBuilder lpBuffer, ref int nSize);  общедоступная строка GetComputerName () {int maxCapacity = MAX_COMPUTERNAME_LENGTH + 1;  StringBuilder nameBuilder = новый StringBuilder (maxCapacity, maxCapacity);  if (! GetComputerName (nameBuilder, ref maxCapacity)) {//TODO: обработка ошибок ... throw new System.ComponentModel.Win32Exception ();  } return nameBuilder.ToString ();  }}}  

С помощью WMI можно получить свойство Name одноэлементного класса Win32_ComputerSystem . Вы можете сделать это, создав экземпляр ManagementClass для класса Win32_ComputerSystem и вызвав для него GetInstances () , чтобы получить массив, содержащий единственный экземпляр …

  using System.Linq; using System.Management; namespace SO56585341 {public class WmiClassComputerInfoSource: IComputerInfoSource {public string GetComputerName () {using (ManagementClass  computerSystemClass = new ManagementClass ("Win32_ComputerSystem")) с использованием (ManagementObjectCollection computerSystemCollection = computerSystemClass.GetInstances ()) с использованием (ManagementObject computerSystem = computerSystemCollection.Cast  () .Single ()) return (string) computerSystem;  }}}  

… или создав ManagementObjectSearcher и используя его для Get () lone Win32_ComputerSystem instance …

  using System.Linq; using System. Управление, пространство имен SO56585341 {открытый класс WmiSearcherComputerInfoSource: IComputerInfoSource {общедоступная строка GetComputerName () {ObjectQuery computerSystemQuery = new SelectQuery ("Win32_ComputerSystem");  using (ManagementObjectSearcher computerSystemSearcher = new ManagementObjectSearcher (computerSystemQuery)) с использованием (ManagementObjectCollection computerSystemCollection = computerSystemSearcher.Get ()) с использованием (ManagementObject computerSystem = computerSystemCollection.Cast  () .Single () return () () return ()  ;  }}}  

Наконец, значение, возвращаемое всеми вышеперечисленными методами, кажется, в конечном итоге сохраняется в реестре, поэтому, если вы не против полагаться на эту деталь реализации, вы можете получить его оттуда напрямую …

  using Microsoft.Win32; пространство имен SO56585341 {открытый класс RegistryComputerInfoSource: IComputerInfoSource {общедоступная строка GetComputerName () {//См. также @ "SYSTEM   CurrentControlSet  Control  ComputerName  ActiveComputerName  "//https://www.oreilly.com/library/view/windows-nt-workstation/9781565926134/10_chapter-07.html const string valueParentKeyPath = @" SYSTEM  CurrentControlSet  Control   Имя компьютера  Имя компьютера  ";  используя (RegistryKey parentKey = Registry.LocalMachine.OpenSubKey (valueParentKeyPath, false)) return (string) parentKey.GetValue ("ComputerName");  }}}  

Что касается получения того же значения с удаленного компьютера , то будут работать только три последние реализации, указанные выше, хотя с минимальной настройкой. Во-первых, чтобы завершить этот пример IComputerInfoSource , давайте создадим abstract класс для хранения «параметра» имени/адреса удаленного компьютера …

  пространство имен SO56585341 {общедоступный абстрактный класс RemoteComputerInfoSource: IComputerInfoSource {общедоступная строка RemoteNameOrIp {get;  } защищенный RemoteComputerInfoSource (строка nameOrIp) {RemoteNameOrIp = nameOrIp ??  выбросить новое исключение System.ArgumentNullException (nameof (nameOrIp));  } общедоступная абстрактная строка GetComputerName ();  }}  

Получение экземпляра Win32_ComputerSystem через ManagementClass просто превращается в вопрос явной передачи ему ManagementPath , который также указывает NamespacePath и Server

  используя System.Linq; используя System. Управление; пространство имен SO56585341 {общедоступный класс RemoteWmiClassComputerInfoSource: RemoteComputerInfoSource {общедоступный RemoteWmiClassComputerInfoSource (строка nameOrIp): base (nameOrIp) {} общедоступная строка переопределения GetComputerName () {ManagementPath computerSystemPath = @ rootSystemPath = @SystemSystemPath = new Management_namepath () {ManagementPath computerSystemPath = new Management_Namepath () {   cimv2 ", Сервер = RemoteNameOrIp};  using (ManagementClass computerSystemClass = new ManagementClass (computerSystemPath)) с использованием (ManagementObjectCollection computerSystemCollection = computerSystemClass.GetInstances ()) с использованием (ManagementObject computerSystem = computerSystemCollection.Cast  () .Single ()) return (string) computerSystem [  ;  }}}  

A ManagementObjectSearcher можно использовать, передав аналогичный ManagementPath , заключенный в ManagementScope

  с использованием System.Linq; с использованием System.Management; пространство имен SO56585341 {открытый класс RemoteWmiSearcherComputerInfoSource: RemoteComputerInfoSource {public RemoteWmiSearcherComputerInfoSource (строка nameOrIp):  base (nameOrIp) {} общедоступная строка переопределения GetComputerName () {ManagementScope computerSystemScope = new ManagementScope (new ManagementPath () {NamespacePath = @ "root  cimv2", Server = RemoteNameOrIp});  ObjectQuery computerSystemQuery = новый SelectQuery ("Win32_ComputerSystem");  using (ManagementObjectSearcher computerSystemSearcher = new ManagementObjectSearcher (computerSystemScope, computerSystemQuery)) с использованием (ManagementObjectCollection computerSystemCollection = computerSystemSearcher.Get ()) с использованием (ManagementObject computerSystem = computerSystemCollection.Cast  

Для запроса удаленного реестра просто требуется дополнительный вызов OpenRemoteBaseKey () для получения дескриптора корня удаленного куста. ..

  с использованием Microsoft.Win32; пространство имен SO56585341 {открытый класс RemoteRegistryComputerInfoSource: RemoteComputerInfoSource {общедоступный RemoteRegistryComputerInfoSource (строка nameOrIp): base (nameOrIp) {} общедоступная строка переопределения GetComputerName () //См. Также @ "SYSTEM  CurrentControlSet  Control  ComputerName  ActiveComputerName "//https://www.oreilly.com/library/view/windows-nt-workstation/9781565926134/10_chapter-07.html const string valueParentKeyPath =  @ "СИСТЕМА  CurrentControlSet  Control  ComputerName  ComputerName ";  using (RegistryKey baseKey = RegistryKey.OpenRemoteBaseKey (RegistryHive.LocalMachine, RemoteNameOrIp)) using (RegistryKey parentKey = baseKey.OpenSubKey (valueParentKeyPath, false)) return (string) parentKey.GetValue ("ComputerName");  }}}  

Если вы скомпилируете весь приведенный выше код в проект, вы можете использовать следующий класс Program для его тестирования …

  using System; using System.Collections.Generic; using System.Linq; using System. Отражение; пространство имен SO56585341 {Программа статического публичного класса {частная константная строка TestHost = "127.0.0.1";  public static void Main () {//Получить все неабстрактные классы в исполняемой сборке, которые реализуют IComputerInfoSource IEnumerable  computerInfoSourceTypes = Assembly.GetExecutingAssembly (). GetTypes () .Where (type => type.IsClass &&! type.  IsAbstract && typeof (IComputerInfoSource) .IsAssignableFrom (тип)); //Для каждого конструктора в каждом классе-кандидате ... foreach (введите computerInfoSourceType в computerInfoSourceTypes) foreach (конструктор ConstructorInfo в computerInfoSourceType.GetConstructors ()) {ParameterInfo [] constructorParameters = constructor.GetParameters ();  объект [] instanceParameters; //Если конструктор не принимает параметров ... if (! ConstructorParameters.Any ()) instanceParameters = Array.Empty  (); //... или один строковый параметр ... иначе if (constructorParameters.Length == 1 && constructorParameters [0] .ParameterType == typeof (string)) instanceParameters = new object [1] {TestHost}; //... иначе пропустить этот конструктор else continue; //Создание экземпляра класса с использованием параметров конструктора, указанных выше IComputerInfoSource computerInfoSource = (IComputerInfoSource) constructor.Invoke (instanceParameters);  строковый результат;  попробуйте {результат = computerInfoSource.GetComputerName ();  } catch (Exception ex) {результат = ex.ToString ();  } Console.WriteLine ("новый {0} ({1}). {2} (): " {3}  "", computerInfoSourceType.Name, string.Join (",", instanceParameters.Select (value =>  $ "" {значение}  "")), nameof (IComputerInfoSource.GetComputerName), результат);  }}}}  

Я обнаружил, что этот код работает независимо от того, установлено ли в TestHost имя компьютера, CNAME или IP-адрес. Обратите внимание, что классы Remote * ComputerInfoSource завершатся ошибкой, если …

  • Соответствующая служба ( RemoteRegistry или Winmgmt ) не запущен на удаленном компьютере, или …
  • Соответствующее правило брандмауэра (например, WMI-WINMGMT-In- TCP ) не включен на удаленном компьютере или …
  • Код не запускается от имени пользователя с правами доступа к удаленной службе.

Что касается PowerShell, у вас должна быть возможность перенести код любого из вышеперечисленных методов с C # (либо прямой перевод, либо с использованием удобства PowerShell) и заключите их в вызов Invoke-Command , поскольку этот код будет выполняться локально на удаленном компьютере. Например …

  Invoke-Command -ComputerName $ nameOrIp -ScriptBlock {$ Env: COMPUTERNAME}  

… или …

  Invoke-Command -ComputerName $ nameOrIp -ScriptBlock {# См. также 'HKLM:  SYSTEM  CurrentControlSet  Control  ComputerName  ActiveComputerName ' # https://www.oreilly.com/library/view/windows-nt-workstation/9781565926134/10_chapter-07. html Get-ItemProperty -Path 'HKLM:  SYSTEM  CurrentControlSet  Control  ComputerName  ComputerName ' -Name 'ComputerName'}  

PowerShell также имеет Get -WmiObject

  Get-WmiObject -Class 'Win32_ComputerSystem' -ComputerName $ nameOrIp -Property 'Name'  

… и Get-CimInstance командлеты …

  Get-CimInstance -Class 'Win32_ComputerSystem' -ComputerName $ nameOrIp -  Свойство 'Name'  

… которое значительно упрощает работу с WMI. В общем, я бы рекомендовал использовать WMI , поскольку его довольно легко использовать из C # и PowerShell как для локальных, так и для удаленных запросов, и он существует именно для этой цели — получения сведений о системе без необходимости знать об основных вызовах API или представлении данных.

Обратите внимание, что при использовании командлетов Invoke-Command или Get-CimInstance , служба WinRM должна быть запущена на удаленном компьютере и должно быть включено соответствующее правило брандмауэра (например, WINRM-HTTP-In-TCP-NoScope ). Кроме того, при передаче IP-адреса в параметр -ComputerName любого из этих командлетов этот адрес должен совпадать со значением WSMan: localhost Client TrustedHosts код>. Если вам нужно просканировать всю сеть по IP-адресу, я проверил и обнаружил, что TrustedHosts принимает подстановочный знак * , но не принимает маски подсети, нотацию CIDR или ? подстановочный знак.

Оцените статью
logicle.ru
Добавить комментарий