Capture multiline, multi-group to Powershell variables

前端 未结 4 1624
忘了有多久
忘了有多久 2021-01-20 07:27

Ideally, I would like to create an object from ipconfig that allows us to drilldown to each adapter\'s attributes like this: $ip.$lan.$mac for the lan adapter\'s mac address

相关标签:
4条回答
  • 2021-01-20 07:42

    Looking at the output of IPCONFIG /ALL, it looks like there are 3 different types of data being returned - the header section at the beginning and the an arbitrary number of sections for active and inactive adapters, each with a different format and set of data returned.

    Here is a set of regular expressions that can be used to parse each one, and capture the values presented:

    $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) 
    

    chew on that a bit, and let me know if that's making any sense.

    0 讨论(0)
  • 2021-01-20 07:54

    If you want to pull data out of strings (with regexes) and assign to variables, I think what you are looking for are named capture groups, which you can use in a manner similar to the following:

    (?<word1>\w+)
    

    Then you can pull these out of the $matches hashtable by name, for example:

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

    You can have multiple named capture groups in the same regex, but each one will need to have distinct names. Armed with this you should be able to match the various bits of text you want and give them names to be picked up easily afterwards.

    The following blog talks about this concept a little more:

    • http://tasteofpowershell.blogspot.co.uk/2012/01/named-groups-in-regular-expressions.html
    0 讨论(0)
  • 2021-01-20 08:03

    Another approach, if you want (1) an object and (2) something that should work in older versions of PowerShell, is to pull the network information using WMI:

    $adapters = Get-WmiObject -Class Win32_NetworkAdapterConfiguration
    
    $adapters | Format-Table Description,IPAddress,MACAddress
    
    $enabled = $adapters | Where-Object{$_.IPEnabled -eq $true}
    

    You can use the following to explore the full set of data that you get per adapter:

    $enabled | Format-List *
    
    0 讨论(0)
  • 2021-01-20 08:06

    I know this doesn't directly answer your question. But rather than parsing the output of ipconfig with Regex. You could instead use Get-NetIPConfiguration to get a powershell object that is easier to deal with.

    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    :
    

    Thus you can do the following to get the values you are looking to acquire.

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

    To get the MAC the address you can use the Get-NetAdapter cmdlet.

    $adapter = Get-NetAdapter
    $adapter.MacAddress
    

    You can correlate the two pieces of information using the InterfaceIndex. Then return a hashtable that makes each accessible. The following creates an array of these combined objects.

    $combined = Get-NetIPConfiguration | ForEach-Object {
        $adapter = Get-NetAdapter -InterfaceIndex $_.InterfaceIndex
        @{ IP = $_; Adapter = $adapter }
    }
    
    0 讨论(0)
提交回复
热议问题