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:
Capture the mac address of the specific IP address that I have problem with:
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.
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
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:
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:
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?
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.
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
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.
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
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.