MAC Address matching

Hi

I’ve been working on a PSH script to rename client workstations after sysprep imaging.

I need assistance with matching the captured MAC address of the client with the known MAC Address and mapping it to a host name…

#borrowed this code from the WWW to get the MAC Address…

function Get-MACAddress {
param ($strComputer)

$colItems = get-wmiobject -class "Win32_NetworkAdapterConfiguration" -computername $strComputer |Where{$_.IpEnabled -Match "True"} 

foreach ($objItem in $colItems) { 

    #$objItem |select Description,MACAddress 
    $objItem | select MACAddress 
}

}

$MAC = Get-MACAddress localhost | ft -hide

#Then, match the MAC Address with known value and set the host name…

Switch ($MAC)

{
    B8:CA:3C:CD:AE:35 { $newComputerName = "pc01" ; break }
    B8:CA:3D:CE:AE:10 { $newComputerName = "pc02" ; break }
    F3:B7:E2:6B:07:DF { $newComputerName = "pc03" ; break }
    default {"MAC Address not defined."}
}

#Then there is code to rename the computer, etc…

{…}

The $MAC does not appear to be matched, hence my constant result is MAC Address not defined.

Any assistance is welcome.

Thanks

–samuel

Does your input for the MAC Address require dashes perhaps instead of colons? I know certain methods use it one way, and certain ones use it the other.

Check out this Convert-MacAddress function:

The problem is this:

$objItem | select MACAddress

You’re outputting an object that has a MACAddress property; that’s not the same as outputting just the MAC address as a simple string. But, in your comparison, you’re assuming the MAC address is a string.

$objItem | select -expand MACAddress

The next problem is this:

$MAC = Get-MACAddress localhost | ft -hide

That’s converting the output to a table format, and storing it in $MAC. PowerShell doesn’t output text; you’re making the assumption that the output of Get-MACAddress is a text table, and you’re trying to use Format-Table to hide the table headers. In reality, Get-MACAddress wasn’t creating those table headers. They were only appearing when the output was formatted for the screen. By explicitly formatting the output as you’re doing, you’re rendering it useless for any further operations. Change to:

$MAC = Get-MACAddress localhost

The final problem is that all computers have more than one MAC address, and Get-MACAddress is going to return them all. You can’t compare a collection of things to a string. In other words, you can’t say, “get me the color of every car in this parking lot. Is the color blue?” It’s nonsensical. As written, you’ll need to enumerate the MAC addresses and compare them one at a time:

for each ($address in $mac) {
 Switch ($address)
 {
  B8:CA:3C:CD:AE:35 { $newComputerName = "pc01" ; break }
  B8:CA:3D:CE:AE:10 { $newComputerName = "pc02" ; break }
  F3:B7:E2:6B:07:DF { $newComputerName = "pc03" ; break } 
  default {"MAC Address $address not defined."}
 }
}

Those values in the switch block (your MAC addresses) should probably go into quotes, too. Every computer is expected to generate a lot of “not defined” statements, because it’s going to have a lot of different MAC addresses due to all the virtual network adapters Windows has.

Hope that gets you going.

I’ll point out that, because $MAC contains more than one string (once you’ve made my modifications above), a Switch construct might not be the best approach. Consider:

if ($mac -contains "B8:CA:3C:CD:AE:35") {
  $newComputerName = 'pc01'
} elseif ($mac -contains 'next-one') {
 $newComputerName = 'pc02'
}

Using If/ElseIf/Else, you can use the -contains operator. That lets you check just the MAC address you care about to see if it’s in $MAC. You won’t have to have a lot of unnecessary “not defined” messages this way, and you don’t have to use a ForEach to go through each MAC address one at a time.

Hi All

Thank you for taking the time to reply with the solutions - appreciated!

Sean Quinlan from the Powershell.com forum provided the following solution that worked for me…

Change
$MAC = Get-MACAddress localhost | ft -hide

To
$MAC = (Get-MACAddress localhost).MACAddress

Sean’s reasoning:
You are piping the output of the Get-MACAddress function into Format-Table [ft -hide]. This changes $MAC into something that can only be ouptut to the screen and cannot be compared later on.

best regards,
–samuel

Don, the Get-MACAddress function actually grabs only the “enabled IP” network card. In my environment, that will always be only one NIC that will have an IP address - and this suits my usage of the function.

You are correct though, that PCs with multiple NICs and Virtual NICs will be report all their MAC addresses if the NICs have IP addresses associated with them.

With the one liner solution that I posted below, the switch statement works exceptionally well, without me having to type in a host name after sysprep. The function grabs the enabled IP NIC and the switch statement defines the host name and the computer can be renamed.

Regards
–samuel

Thanks Will
The function provides a colon notation of the MAC address.

Regards
–samuel

Sean’s approach is pretty much the same that I recommended, just a bit more programmer-y.