Я думал, что это может быть доступно в System.Net.NetworkInformation
пространстве имен , но, очевидно, нет. Я просмотрел несколько низкоуровневых Windows сетевых API , думая конечно он должен существовать где-то там, но такой удачи не было. После запуска dumpbin
на netsh.exe
, чтобы увидеть, какие виды библиотек / функций он потребляет, у меня появилась идея посмотреть еще одно место: реестр.
Как это происходит , если вы загляните в реестр под ключом HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\Tcpip\Parameters\Interfaces\
, вы увидите ключ для каждого сетевого интерфейса с именем в формате GUID. В ключе интерфейса вы найдете два значения: DhcpNameServer
и NameServer
. В моей клиентской системе, где DNS-сервер установлен по DHCP, DhcpNameServer
содержит IP-адрес этого DNS-сервера, а NameServer
содержит пустой [String]
. Если я вручную задаю DNS-сервер, сохраняя автоматически назначенный адрес для самого интерфейса, NameServer
затем содержит этот заданный вручную адрес DNS-сервера, тогда как DhcpNameServer
все еще содержит тот же DNS-сервер, указанный DHCP.
На основании этих наблюдений может показаться, что ...
- Значение
DhcpNameServer
всегда содержит DNS-сервер (ы), заданный DHCP. - Значение
NameServer
всегда содержит DNS-сервер (ы), указанные вручную. - Когда вы запрашиваете у системы его серверы имен (например, через свойство
Win32_NetworkAdapterConfiguration.DNSServerSearchOrder
), результат будет содержать значение NameServer
, если оно предоставлено, в противном случае значение DhcpNameServer
, если предусмотрено. Другими словами, система сообщает вам, какие DNS-серверы в настоящее время используются, но не то, как были указаны их адреса. - Чтобы определить, имеет ли интерфейс назначенные вручную DNS-серверы, проверьте,
NameServer
имеет непустое значение.
Таким образом, имея интерфейс с идентификатором $interfaceID
, вы можете построить путь к его ключу реестра следующим образом ...
$interfaceKeyPath = "HKLM:\SYSTEM\CurrentControlSet\Services\Tcpip\Parameters\Interfaces\$interfaceID"
... и затем получить динамически назначенные и назначенные вручную значения сервера имен, как это ...
Get-ItemProperty -Path $interfaceKeyPath -Name 'DhcpNameServer', 'NameServer'
Это просто оставляет вопрос о том, откуда вы получаете значение для $interfaceID
, и существует множество источников, хотя хитрость будет исключать нежелательные интерфейсы (например, в моей системе Windows 10 у меня есть адаптер обратной связи с захватом пакетов и адаптер гипервизора, который я бы хотел исключить из такого запроса). Наиболее совместимым способом (начиная с. NET 2.0) будет свойство Id
класса NetworkInterface
...
[System.Net.NetworkInformation.NetworkInterface]::GetAllNetworkInterfaces() `
| Select-Object -ExpandProperty 'Id'
... хотя единственными полезными свойствами для фильтрации являются Name
и NetworkInterfaceType
.
On Windows Vista и выше Win32_NetworkAdapter
класс предоставляет свойство GUID
...
Get-WmiObject -Class 'Win32_NetworkAdapter' -Property 'GUID' -Filter 'PhysicalAdapter = true'
... хотя даже при фильтрации на PhysicalAdapter
он по-прежнему возвращает loopback и гипервизор адаптеры, и я не вижу каких-либо определенных свойств или отношений классов, которые можно использовать для выбора только аппаратных адаптеров.
Win32_NetworkAdapterConfiguration
класс во многом такой же ...
Get-WmiObject -Class 'Win32_NetworkAdapterConfiguration' -Property 'SettingID'
... без свойств для фильтрации не аппаратных или даже нефизических адаптеров.
Вкл (я думаю) Windows 8 и выше есть Get-NetConnectionProfile
cmdlet ...
Get-NetConnectionProfile | Select-Object -ExpandProperty 'InstanceID'
, который задокументирован для получения "профиля соединения, связанного с одним или несколькими физическими сетевыми адаптерами", и в моей системе он возвращает только мой p физический адаптер.
Существует также командлет Get-NetAdapter
...
Get-NetAdapter -Physical `
| Where-Object -Property 'EndPointInterface' -NE -Value $true `
| Select-Object -ExpandProperty 'InterfaceGuid'
Я обнаружил, что передача параметра -Physical
исключает адаптер гипервизора, но не адаптер обратной связи, поэтому для устранения этого необходимо было отфильтровать, где EndPointInterface
равно $true
. Свойства HardwareInterface
и Virtual
также могут представлять интерес.
Другой вариант - вызвать Get-NetAdapterHardwareInfo
командлет , который, похоже, знает, как отличить guish настоящие аппаратные адаптеры, и пусть они определяют, какие адаптеры извлекаются с помощью Get-NetAdapter
...
Get-NetAdapterHardwareInfo `
| Get-NetAdapter `
| Select-Object -ExpandProperty 'InterfaceGuid'
Приведенные выше командлеты Get-Net*
возвращают экземпляры CIM, поэтому, например, вместо Get-NetAdapter -Physical
вы может использовать что-то вроде ...
Get-WmiObject -Namespace 'Root\StandardCimv2' -Class 'MSFT_NetAdapter' `
-Property 'InterfaceGuid' -Filter 'HardwareInterface = true AND EndPointInterface = false'
для получения экземпляров MSFT_NetAdapter
точно так же. Я не совсем уверен, что руководство по использованию одного против другого. Казалось бы, нужно отдавать предпочтение командлетам, и все же, в отличие от WMI / CIM, они предлагают ограниченные параметры / нет параметров для эффективной фильтрации выходных данных или указания желаемых свойств, так что вы должны сделать это в конвейере. Я думаю, что примечательно, что я не смог найти никакой текущей документации для этих MSFT_*
классов; все они говорят, что больше не обновляются, за исключением класса MSFT_NetConnectionProfile
, для которого я вообще не смог найти страницу документации. Это говорит мне о том, что Microsoft не хочет, чтобы вы полагались на какую-то определенную структуру этих классов, и все же, если командлеты просто передают эти экземпляры классов ... Я не уверен, как вы можете полноценно и надежно взаимодействовать с ними, если ничего не происходит. задокументировано.
Кроме того, имейте в виду, что вы захотите отдать предпочтение Get-CimInstance
и его значение над Get-WmiObject
, где это возможно. Я не думаю, что я когда-либо встречал случай, когда это было более сложным, чем изменение Get-WmiObject
на Get-CimInstance
, хотя есть больше различий (не обязательно плохих), чем имя.