我正试图通过静态的WMI(由用户放置)的网络接口的DNS服务器。我有这个脚本,当然除了静态部分:
Get-WmiObject Win32_NetworkAdapterConfiguration | Where-Object {$_.DNSServerSearchOrder -ne $null} | Select DnsServerSearchOrder,Index,InterfaceIndex
这将导致如下输出:
DnsServerSearchOrder Index InterfaceIndex
-------------------- ----- --------------
{192.168.122.1} 1 6
{1.1.1.1} 2 10
192.168.122.1
的接口将其DNS设置为DHCP,因此该值对我来说不好。如何过滤掉dns不是静态的接口?有什么想法吗netsh interface ip show config
:
Configuration for interface "Ethernet"
DHCP enabled: Yes
IP Address: 192.168.122.130
Subnet Prefix: 192.168.122.0/24 (mask 255.255.255.0)
Default Gateway: 192.168.122.1
Gateway Metric: 0
InterfaceMetric: 35
DNS servers configured through DHCP: 192.168.122.1
Register with which suffix: Primary only
WINS servers configured through DHCP: None
Configuration for interface "Ethernet 2"
DHCP enabled: Yes
IP Address: 10.0.0.17
Subnet Prefix: 10.0.0.0/24 (mask 255.255.255.0)
Default Gateway: 10.0.0.1
Gateway Metric: 0
InterfaceMetric: 35
Statically Configured DNS Servers: 1.1.1.1
Register with which suffix: Primary only
WINS servers configured through DHCP: None
注意Statically Configured DNS Servers
和DNS servers configured through DHCP
之间的术语差异。我想我可能会解析这个输出,但我不确定如果windows语言/区域设置改变了,我是否可以依赖这个文本,如果可能的话,我宁愿使用WMI接口。
3条答案
按热度按时间y4ekin9u1#
我认为这可能在
System.Net.NetworkInformation
namespace中可用,但显然不是。我查看了一些较低级别的Windows networking APIs,心想 * 肯定 * 它一定存在于其中的某个地方,但没有这样的运气。在netsh.exe
上运行dumpbin
以查看它使用了哪些类型的库/函数之后,我确实想到了另一个可以查看的地方:登记处。如果您在
HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\Tcpip\Parameters\Interfaces\
项下查看注册表,您将看到每个网络接口的一个项,其名称为GUID格式。在接口的键中,您会发现两个感兴趣的值:DhcpNameServer
和NameServer
。在我的客户端系统中,DNS服务器由DHCP设置,DhcpNameServer
包含该DNS服务器的IP地址,NameServer
包含空的[String]
。如果我手动设置DNS服务器,同时保留接口本身的自动分配地址,则NameServer
包含手动设置的DNS服务器地址,而DhcpNameServer
仍然包含DHCP指定的相同DNS服务器。基于这些观察,似乎…
DhcpNameServer
值始终包含DHCP指定的DNS服务器。NameServer
值始终包含手动指定的DNS服务器。Win32_NetworkAdapterConfiguration.DNSServerSearchOrder
属性),如果提供,则结果将包含NameServer
的值,否则如果提供,则结果将包含DhcpNameServer
的值。换句话说,系统会告诉你哪些DNS服务器 * 当前 * 正在使用,但不会告诉你它们的地址是如何指定的。NameServer
是否具有非空值。因此,给定一个ID为
$interfaceID
的接口,您可以像这样构建其注册表项的路径......然后像这样检索动态分配和手动分配的nameserver值...
这就剩下从哪里获取
$interfaceID
的值的问题了,有很多来源,尽管技巧是排除不需要的接口(例如,在我的Windows 10系统上,我有一个数据包捕获环回适配器和一个管理程序适配器,我希望从这样的查询中排除)。最兼容的方式(可以追溯到.NET 2.0)是NetworkInterface
class的Id
property。...尽管要过滤的唯一有用属性是
Name
和NetworkInterfaceType
。在Windows Vista及更高版本上,
Win32_NetworkAdapter
class提供GUID
属性......虽然即使在
PhysicalAdapter
上进行过滤时,它仍然返回loopback和hypervisor适配器,并且我没有看到任何可用于仅选择硬件适配器的明确属性或类关系。Win32_NetworkAdapterConfiguration
class是一样的。...没有属性来过滤掉非硬件甚至非物理适配器。
在(我认为)Windows 8及以上版本中有
Get-NetConnectionProfile
cmdlet...它被记录为获取“与一个或多个物理网络适配器相关联的连接配置文件”,并且在我的系统上,它确实只返回我的物理适配器。
另外还有
Get-NetAdapter
cmdlet…我发现传递
-Physical
参数排除了hypervisor适配器,但没有排除loopback适配器,因此有必要过滤掉EndPointInterface
是$true
的地方。HardwareInterface
和Virtual
属性也可能会引起兴趣。另一个选择是调用
Get-NetAdapterHardwareInfo
cmdlet,它似乎知道如何区分真正的硬件适配器,并让它确定Get-NetAdapter
检索哪些适配器…上面的
Get-Net*
cmdlet返回CIM示例,因此,例如,您可以使用类似...的内容来代替Get-NetAdapter -Physical
。同样检索
MSFT_NetAdapter
示例。我真的不知道使用一个与另一个的指导是什么。看起来人们应该更喜欢cmdlet,但是,与WMI/CIM不同,它们提供有限的/没有参数来有效地过滤输出或指定所需的属性,因此您必须在管道中执行此操作。不过,我认为值得注意的是,我找不到这些MSFT_*
类的任何 * 当前 * 文档;他们都说他们不再更新了,除了MSFT_NetConnectionProfile
类,我根本找不到任何文档页面。对我来说,微软不希望你依赖于这些类的任何明确的结构,但是如果cmdlet只是沿着这些类示例......我不确定如果没有任何文档,你如何能够有意义地和可靠地与它们交互。另外,请记住,在可能的情况下,您将want to prefer
Get-CimInstance
和its ilk超过Get-WmiObject
。我认为我还没有遇到过比将Get-WmiObject
更改为Get-CimInstance
更复杂的示例,尽管有比名称更多的差异(不一定是坏的)。luaexgnf2#
经过足够的抨击,我找到了一个解决方案,但我不是100%肯定是正确的道路。在所有DHCP DNS服务器上,DNS值都包含一个IP地址,并且该IP地址等于
Default Gateway
值。当这些值匹配时,我们正在处理一个DHCP DNS服务器,而不是静态配置的。h43kikqp3#
既然netsh知道这一切,为什么不走这条路呢?喜欢