Select-string issue

Hello there,
I just started to work on Powrshell scripting. I did lot of scripting in Linux and trying to translate the pseudo code from my Linux script to powershell. The part of the code is to capture a specific mac address from arp -a to see if there is any conflict. Performed following:

  1. Capture the mac address of the specific IP address that I have problem with:

$myip=“192.168.1.91”
$myarp = arp -a | select-string $myip | Where{$_ -notlike “interface:*”} | ConvertFrom-String | select p3 | ft -HideTableHeaders | Out-String

The above works perfectly well and output the mac address xx-8a-ae-9e-d9-xx. The next step is to use the $myarp string (that has the mac address) to search again in the arp cache to find any conflict. here I am having problem. I tried following but it returns nothing.

arp -a | select-string $myarp

Hope you can help me out!!

In Powershell most of the time it’s better to avoid command line tools if there’s a native Powershell cmdlet providing the same or at least similar information. Did you try to use Get-NetNeighbor? It might give the information you are looking for in a “pure” Powershell way. It is more reliable when you use the object oriented approach instead of working with strings.

Thanks for the response Olaf. I will look into Get-NetNeighbor, but at this time I am more interested to get the script fixed. Any idea why it doesn’t return the output?
arp -a | select-string $myarp

If I do following:

$myarp=“xx-8a-ae-9e-d9-xx”
arp -a | select-string $myarp

then It would grep all the matching strings from arp -a but doesn’t do it with the actual script below.
$myarp = arp -a | select-string $myip | Where{$_ -notlike “interface:*”} | ConvertFrom-String | select p3 | ft -HideTableHeaders | Out-String

I am more interested to get the script fixed.
Why? If another approach does what you need ...
Any idea why it doesn't return the output?
Of course not. ;-) I don't know how your arp table looks like. You might post a part of the relevant data here (formatted as code please). You use a format cmdlet "inside" your pipeline. Usually that's just wrong. A format cmdlet should be the very last in a pipeline and it's almost always only suitalble for output to humans - never for the next cmdlet or for the next step in a script. BTW: You could make our lives easier by formatting your code as code here in the forum. ;-)

I don’t know any other way of greping (unix term) a specific string in powershell; by using ft, I was able to grep the mac address perfectly well. Trying my best to help you visualize it:

arp -a would produce following:

Inter5ace: 192.168.x.11x — xx3
Internet Address Physical Address Type
192.168.81.x 55-55-55-55-55-55 static
224.x.x.2 x1-xx-5e-xx-xx-x2 static
224.x.x.22 x1-xx-5e-xx-xx-16 static
224.x.x.251 x1-xx-5e-xx-xx-5b static
224.x.x.252 x1-xx-5e-xx-xx-5c static
239.x.x.25x x1-xx-5e-75-55-5a static

Inter5ace: 192.168.x.xxx – xxe
Internet Address Physical Address Type
192.168.1.91 34-8a-ae-5e-e9-9x dynamic
192.168.1.1x7 bc-51-5e-8x-e5-46 dynamic
192.168.1.11x 5x-b5-97-87-e4-dd dynamic
192.168.1.12x xx-9x-a9-ed-35-a7 dynamic
192.168.1.2xx xx-21-cc-b5-ec-78 dynamic
192.168.1.x 55-55-55-55-55-55 static
224.x.x.2 x1-xx-5e-xx-xx-x2 static
224.x.x.22 x1-xx-5e-xx-xx-16 static
224.x.x.251 x1-xx-5e-xx-xx-5b static
224.x.x.252 x1-xx-5e-xx-xx-5c static
239.x.x.25x x1-xx-5e-75-55-5a static
x.x.x.x 55-55-55-55-55-55 static

Inter5ace: 192.168.126.1 — xx14
Internet Address Physical Address Type
192.168.126.254 xx-5x-56-57-13-35 dynamic
192.168.126.x 55-55-55-55-55-55 static
224.x.x.2 x1-xx-5e-xx-xx-x2 static
224.x.x.22 x1-xx-5e-xx-xx-16 static
224.x.x.251 x1-xx-5e-xx-xx-5b static
224.x.x.252 x1-xx-5e-xx-xx-5c static
239.x.x.25x x1-xx-5e-75-55-5a static

selected on ip (to keep it simple, not using as a parameter) e.g.
$myip = 192.168.1.12x

Ran following script:
$arpsearch = arp -a | Select-String $myip | Where{$_ -notlike “interface:*”}

output: 192.168.1.12x xx-9x-a9-ed-35-a7 dynamic

Now I need to grep the mac address:

$myarp = arp -a | select-string $myip | Where{$_ -notlike “interface:*”} | ConvertFrom-String | select p3 | ft -HideTableHeaders | Out-String

Output: xx-9x-a9-ed-35-a7

Now I will need to search the arp table again by using the above mac address to see the conflict. if there is a conflict, it would report multiple IP addresses with the same mac address; otherwise, only 1 - means no conflict.
$conflict = arp -a | select-string $myarp
But $conflict output nothing.

You can try the scripts in your machine by using your own arp table.

I did some work with arp & PowerShell the other week, I am using arp to get the MAC addresses of non Windows based medical devices & such & then comparing the MAC address vs. the known format for three different devices to report back what sort of device is assigned to that IP.

Something you might want to consider to help narrow your results, use arp -a a.b.c.x -N a.b.c.y as -N specifies the interface to use so if you have multiples NICs or use Virtual Box or something you can exclude all those results up front.

I use the code below to extract just the MAC address, note the out-string & trim is there as you will otherwise end up with additional blank characters/spaces and that might throw of your results and could be the source of your problem:

((((arp -a $IPAddress -N $InterfaceIP | Findstr /i $MIP) -Split $MIP) -Split "Dynamic") | Out-String).Trim()

I tried running your script with my IP and got nothing but then added the trim and got results:

$myip = "192.168.x.y"
$myarp = (arp -a | select-string $myip | Where{$_ -notlike "interface:*"} | ConvertFrom-String | select p3 | ft -HideTableHeaders | Out-String).Trim()
arp -a | select-string $myarp

It took me a little bit to figure it out, I think I ultimately figured it out by making the actual MAC address a variable and did an -eq the MAC as a variable like you are doing and they didn’t equal each other, then wrote the value encapsulated in " " and saw there was additional spaces. Welcome to the club? :slight_smile:

One other thing you might be able to use, I didn’t really explore it that much but if your put the arp results to a variable it is in effect an array and each line is an element and can be referenced by $arp[0] $arp[1] etc.

I never had to deal with arp tables yet but if I got you right you’re looking for something like this:

$myip = ‘192.168.1.91’
Get-NetNeighbor -IPAddress $myip |
ForEach-Object{
Get-NetNeighbor -LinkLayerAddress $.LinkLayerAddress
}

Or, if you want to get the complete set of information Get-NetNeighbor provides you simply do
$myip = ‘192.168.1.91’
Get-NetNeighbor -IPAddress $myip |
ForEach-Object{
Get-NetNeighbor -LinkLayerAddress $
.LinkLayerAddress | Select-Object -Property *
}

This is probably what you want. Before you were getting extra blank lines in $myarp. You usually don’t need to use out-string or store format-table into a variable.

$myarp = arp -a | select-string $myip | Where { $_ -notlike 'interface:*' } | ConvertFrom-String | 
  select -expand p3

Or like unix ‘cut’:

$myarp = arp -a | select-string $myip | foreach { -split $_ | select -index 1 }

Or

$myarp = Get-NetNeighbor $myip | select -expand linklayeraddress

:wink: :smiley:

Get-NetNeighbor is likely the better option as mentioned, but if you want to parse the command output like you are trying you have to consider that Select-String is using RegEx. You can use Capture Groups in RegEx to get the MAC on the same line as the IP your are looking for.

Ex.

$arp = @'
Inter5ace: 192.168.x.11x — xx3
Internet Address Physical Address Type
192.168.81.x 55-55-55-55-55-55 static
224.x.x.2 x1-xx-5e-xx-xx-x2 static
224.x.x.22 x1-xx-5e-xx-xx-16 static
224.x.x.251 x1-xx-5e-xx-xx-5b static
224.x.x.252 x1-xx-5e-xx-xx-5c static
239.x.x.25x x1-xx-5e-75-55-5a static

Inter5ace: 192.168.x.xxx — xxe
Internet Address Physical Address Type
192.168.1.91 34-8a-ae-5e-e9-9x dynamic
192.168.1.1×7 bc-51-5e-8x-e5-46 dynamic
192.168.1.11x 5x-b5-97-87-e4-dd dynamic
192.168.1.12x xx-9x-a9-ed-35-a7 dynamic
192.168.1.2xx xx-21-cc-b5-ec-78 dynamic
192.168.1.x 55-55-55-55-55-55 static
224.x.x.2 x1-xx-5e-xx-xx-x2 static
224.x.x.22 x1-xx-5e-xx-xx-16 static
224.x.x.251 x1-xx-5e-xx-xx-5b static
224.x.x.252 x1-xx-5e-xx-xx-5c static
239.x.x.25x x1-xx-5e-75-55-5a static
x.x.x.x 55-55-55-55-55-55 static

Inter5ace: 192.168.126.1 — xx14
Internet Address Physical Address Type
192.168.126.254 xx-5x-56-57-13-35 dynamic
192.168.126.x 55-55-55-55-55-55 static
224.x.x.2 x1-xx-5e-xx-xx-x2 static
224.x.x.22 x1-xx-5e-xx-xx-16 static
224.x.x.251 x1-xx-5e-xx-xx-5b static
224.x.x.252 x1-xx-5e-xx-xx-5c static
239.x.x.25x x1-xx-5e-75-55-5a static
'@ -split "`r`n"


$myip = "192.168.1.12x (.*?) "
($arp | Select-String -Pattern $myip).Matches.Groups[1].Value

Results

xx-9x-a9-ed-35-a7

Note that technically the RegEx pattern it not literally matching the 192.168.1.12x IP since period is a wildcard in RegEx. If you want to match literal period, you have to escape the dot 192.168.1.12x

Thank Olaf; I tried it; it is a really great tool. I am going to give it a shot in my next script. Thanks again for giving the idea.

Thanks James. It worked!! Now, working on a couple of more things. e.g. how to get exact string match of the IP. 192.x.x.10 would match .110, .210, 101 etc. so if I am searching the IP 192.x.x.10, it is matching with 192.x.x.110. I tried to use some regular expression and also select-string -simplematch $ip, nothing seem to work.

Thanks James, Olaf, Js, Curtis, I have tried all of you suggestion and it worked like charm!! thank you for the responses. You all are so great !!