2016-02-26 6 views
1

В идеале я хотел бы создать объект из ipconfig, который позволяет нам развернуть атрибуты каждого адаптера, такие как: $ ip. $ Lan. $ Mac для MAC-адреса адаптера lan.Capture multiline, multi-group to Powershell variables

Для начала, я хотел бы разработать способ захватить эти 3 группы (тип адаптера, имя адаптера, атрибуты адаптера) за матч адаптера в переменные Powershell (объекты являются предпочтительными): https://regex101.com/r/wZ3sV1/1

Вот некоторые идеи захватить три части секции адаптера Ethernet, но они только захват «адаптера Ethernet Подключение по локальной сети:»:

$ip = ipconfig /all 

$ip_lan = $ip | Select-String -pattern "(Ethernet [^a]*adapter) (Local[^:]+):\s*(([^\n]+\n)*)" -AllMatches | Foreach {$_.Matches} | ForEach-Object {$_.Value} 

$regex_lan = [regex]"(Ethernet [^a]*adapter) (Local[^:]+):\n*((+[^\n]+\n)*)" 
$regex_lan.Matches($ip) 
$regex_lan.Matches($ip).value 

кроме того, есть ли способ, чтобы захватить имя извлечения группы, как это ?:

Description . . . . . . . . . . . : Realtek PCIe GBE Family Controller 

становится Описание = Realtek PCIe GBE Family Controller

+0

Мне нравится это, но третья группа не захватывает: [regex] :: Match ($ ip, "(Ethernet [^ a] * adapter) (Local [^:] +): \ n * ((+ [^ \ n] + \ n) *) "). captures.groups [1] .value $ regex_lan = [regex] :: Match ($ ip," (Ethernet [^ a] * адаптер) (Local [ ^:] +): \ n * ((+ [^ \ n] + \ n) *) ") – landen99

+0

$ ip создается: $ ip = ipconfig/all – landen99

+0

Можете ли вы привести пример того, что вы как объекты, созданные из захваченных данных, чтобы выглядеть? – mjolinor

ответ

2

Я знаю, что это не прямо ответить на ваш вопрос. Но вместо разбора вывода ipconfig с регулярным выражением. Вместо этого вы можете использовать Get-NetIPConfiguration, чтобы получить объект powershell, с которым легче справиться.

PS> $ip = Get-NetIPConfiguration 
PS> $ip 

InterfaceAlias  : Ethernet 
InterfaceIndex  : 12 
InterfaceDescription : Intel(R) Ethernet Connection I217-LM 
NetProfile.Name  : xyz.com 
IPv4Address   : 10.20.102.162 
IPv6DefaultGateway : 
IPv4DefaultGateway : 10.20.102.1 
DNSServer   : 10.20.100.9 
         10.20.100.11 
         10.20.100.13 

PS> $ip.IPv4Address 

IPAddress   : 10.20.102.162 
InterfaceIndex : 12 
InterfaceAlias : Ethernet 
AddressFamily  : IPv4 
Type    : Unicast 
PrefixLength  : 23 
PrefixOrigin  : Dhcp 
SuffixOrigin  : Dhcp 
AddressState  : Preferred 
ValidLifetime  : 05:16:53 
PreferredLifetime : 05:16:53 
SkipAsSource  : False 
PolicyStore  : ActiveStore 
PSComputerName : 

Таким образом, вы можете сделать следующее, чтобы получить значения, которые вы хотите приобрести.

$ip.InterfaceAlias 
$ip.InterfaceDescription 
$ip.IPv4Address.IPAddress 

Чтобы получить MAC адрес, который вы можете использовать Get-NetAdapter командлет.

$adapter = Get-NetAdapter 
$adapter.MacAddress 

Вы можете сопоставить две части информации с помощью InterfaceIndex. Затем верните хеш-таблицу, которая сделает каждый доступным. Ниже создается массив этих комбинированных объектов.

$combined = Get-NetIPConfiguration | ForEach-Object { 
    $adapter = Get-NetAdapter -InterfaceIndex $_.InterfaceIndex 
    @{ IP = $_; Adapter = $adapter } 
} 
+0

Хороший ответ, но требует V3 и Windows 8 или выше - многие корпоративные среды по-прежнему являются Windows 7 и V2 ... – kuujinbo

+1

Я не вижу там макроса. Однако он работал на Win7. Он имеет DeviceID, хотя не уверен, что это такое, и не уверен, как получить к нему доступ. – landen99

+0

Обновленный ответ на включение адреса mac. – Cobster

0

Если вы хотите вывести данные из строк (с регулярными выражениями) и присвоить переменные, я думаю, что вы ищете являются именованных захват групп, которые вы можете использовать в манере, аналогичной следующий :

(?<word1>\w+) 

Тогда вы можете вытащить их из $matches Hashtable по имени, например:

PS> "hello world!" -match '(?<word1>\w+)' 
True 

PS> $matches["word1"] 
hello 

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

Следующие переговоры блога об этой концепции немного больше:

+0

Следующая команда не производит true/false или любые соответствия: PS C: \ WINDOWS \ system32> $ ip -match "(? Ethernet-адаптер) (? Local [^:] +): \ n * + ( ([^ \ n] + \ n) *) " Следующие результаты не дают результатов: PS C: \ WINDOWS \ system32> $ matches [" lan_msg "] PS C: \ WINDOWS \ system32> $ ip – landen99

+0

Я заменил «\ n» на «\ r \ n» и удалил «+», чтобы получить: PS C: \ WINDOWS \ system32> $ ip -match "(? Ethernet-адаптер) (? Local [^:] +): (\ r \ n) * (? ([^ \ r \ n] + \ r \ n) *) " Ethernet-адаптер Подключение по локальной сети: .. по-прежнему нет результатов для: $ matches.lan_name – landen99

+0

I не видите true или false из: $ ip -match "\ r" ИЛИ $ ip -match "\ n" Я думаю, что новые коды строк являются проблемой, но я не могу понять, какой код использовать. regex101 доволен \ n, но Powershell этого не делает. – landen99

0

Другой подход, если вы хотите (1) объект и (2) то, что должно работать в более ранних версиях из PowerShell, чтобы извлечь информацию о сети с помощью WMI:

$adapters = Get-WmiObject -Class Win32_NetworkAdapterConfiguration 

$adapters | Format-Table Description,IPAddress,MACAddress 

$enabled = $adapters | Where-Object{$_.IPEnabled -eq $true} 

Вы можете использовать следующие исследовать полный набор данных что вы получите на один адаптер:

$enabled | Format-List * 
0

Глядя на выходе IPCONFIG/ALL, это выглядит как есть 3 различных типов данных, возвращаемые - секция заголовка в начале и произвольное количество секций для активных и неактивные адаптеры, каждый из которых имеет другой формат и набор возвращаемых данных.

Вот набор регулярных выражений, которые могут быть использованы для анализа каждого из них, а также захватить ценности, представленные:

$Header_Regex = 
@' 
(?m)Windows IP Configuration 

    Host Name . . . . . . . . . . . . : (.*) 
    Primary Dns Suffix . . . . . . . : (.*) 
    Node Type . . . . . . . . . . . . : (.*) 
    IP Routing Enabled. . . . . . . . : (.*) 
    WINS Proxy Enabled. . . . . . . . : (.*) 

'@ 


$Active_Adapter_Regex = 
@' 
(?m)(.+? adapter .+): 

    Connection-specific DNS Suffix . : (.*) 
    Description . . . . . . . . . . . : (.*) 
    Physical Address. . . . . . . . . : (.*) 
    DHCP Enabled. . . . . . . . . . . : (.*) 
    Autoconfiguration Enabled . . . . : (.*) 
    Link-local IPv6 Address . . . . . : (.*) 
    IPv4 Address. . . . . . . . . . . : (.*) 
    Subnet Mask . . . . . . . . . . . : (.*) 
    Lease Obtained. . . . . . . . . . : (.*) 
    Lease Expires . . . . . . . . . . : (.*) 
    Default Gateway . . . . . . . . . : (.*) 
    DHCP Server . . . . . . . . . . . : (.*) 
    DHCPv6 IAID . . . . . . . . . . . : (.*) 
    DHCPv6 Client DUID. . . . . . . . : (.*) 
    DNS Servers . . . . . . . . . . . : ((?:.|\n)*) 
    NetBIOS over Tcpip. . . . . . . . : (.*) 
'@ 

$Inactive_Adapter_Regex = 
@' 
(?m)(.+? adapter .+): 

    Media State . . . . . . . . . . . : (.*) 
    Connection-specific DNS Suffix . : (.*) 
    Description . . . . . . . . . . . : (.*) 
    Physical Address. . . . . . . . . : (.*) 
    DHCP Enabled. . . . . . . . . . . : (.*) 
    Autoconfiguration Enabled . . . . : (.*) 

'@ 

$Cmd_Output = (ipconfig /all | out-string) 

$header = 
if ($Cmd_Output -match $Header_Regex) 
    {$matches} 

$Inactive_Adapters = 
[regex]::Matches($Cmd_Output,$Inactive_Adapter_Regex) 

$Active_Adapters = 
[regex]::Matches($Cmd_Output,$Active_Adapter_Regex) 

жевать, что немного, и дайте мне знать, если это делает какой-то смысл.

+0

Отличный код, отличная идея с внешней строкой и множество вопросов: 1) Почему регулярное выражение начинается на следующей строке без использования '' 'и что делает' @ ''? 2) Я вижу, что '.GetType' возвращает Name: MatchCollection, но почему' .count' возвращает 1? Есть ли только один матч и как я могу получить доступ к другим матчам? 3) Я вижу parathensis, создавая неименованные группы захвата в регулярном выражении. Есть ли способ их использовать? 4) Какова цель '(?:. | \ N) *' в разделе DNS-серверов? 5) Зачем использовать инструкцию if для заголовков вместо совпадений для адаптеров? [подробнее ...] – landen99

+0

... 6) Является ли '[regex]' указанием, что результатом совпадений является регулярное выражение? Как работают матчи? – landen99

+0

Прочтите get-help about_quoting_rules для объяснения строки здесь (@ '...' @). См. Get-help about_automatic_variables для объяснения $ совпадений. – mjolinor