foreach is not processing multiple items individually, instead concatenating al

I am building a script to pull the mac addresses of a computer, and convert them to GUIDs that are then queried to AD to find a match and retrieve the hostname associate with that guid.

Everything I’ve read about “Foreach” suggests that the code I am using “SHOULD” work.

import-module ActiveDirectory | Out-Null

$username = "ad\SvcUsername"
$hash = Get-Content \\server\source$\Scripts\readme.txt
$secureString = ConvertTo-SecureString -String $hash
$sessionKey = New-Object System.Management.Automation.PSCredential($username,$secureString)

#$tsenv = New-Object -COMObject Microsoft.SMS.TSEnvironment
#$TSComputerName = $tsenv.value("OSDComputerName")

$NIC = Get-WMIObject Win32_NetworkAdapterConfiguration | select MacAddress
$NICMacs = $NIC.MacAddress

Foreach ($NICMac in $NICMacs)
{

$MacString = $NICMacs -replace ":", ""
$MactoGUID = "00000000000000000000" + $MacString
$MactoGUID = $MactoGUID -replace " ", ''
$NBG = [GUID]$MactoGUID
$CompDetails = Get-ADComputer -Filter 'netbootGUID -like $NBG' -Properties netBootGUID -Server our.AD.server.ca -Credential $sessionKey

If($CompDetails)
{
Write-Host $CompDetails.Name
$TSComputerName = $CompDetails.Name
$tsenv.Value("OSDComputerName") = $TSComputerName

}

}

$ComputerName = $tsenv.Value("OSDComputerName")

If(!$ComputerName)
{

$CSProd = Get-WmiObject -Class Win32_ComputerSystemProduct -Property UUID
$UUID = [GUID]$CSProd.UUID
$CompDetailsUUID = Get-ADComputer -Filter 'netbootGUID -eq $UUID' -Properties netBootGUID -Server our.AD.server.ca -Credential $sessionKey
$TSComputerName = $CompDetailsUUID.Name
$tsenv.Value("OSDComputerName") = $TSComputerName
#Write-Host $CompDetailsUUID.Name

}

<p class=“lang-bsh prettyprint prettyprinted”>

This should process each mac address found, stripping away the : characters and prepending 20 ‘0s’ then convert to GUID format and query AD for a match. Instead, it takes all the mac addresses found, concatenates them to one line and tries to process with all those numbers. Of course AD rejects it as an incorrect GUID. If I use the same code with only 1 mac address, it is correctly formatted.

Output of $NICMacs shows 9 lines with 1 MAC address on each line

Error at $NBG = [GUID]$MactoGUID is Cannot convert value “00000000000000000000+all the mac addresses together” to type “System.Guid”. Error: “Guid should contain 32 digits with 4
dashes (xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx).”

Thank you for any assistance! Our Tier I support staff will love making their job less hands on :smiley:

 

$NICMac instead of $NICMacs.

$MacString = $NICMac -replace ":", ""

It’s for this exact reason I always recommend being very careful to distinguish your variables in a foreach. foreach ($Thing in $Things) {} is very easy to accidentally mess up, both in your own mind and also just with an accidental keystroke.

Instead, something like foreach ($Thing in $ThingList) {} or similar is a lot easier to distinguish visually and in your own head, as well as being significantly harder to accidently use by a mistaken keystroke.

If you don’t wanna have the external variable have the longer name, you can still apply this principle, for example: foreach ($SingleThing in $Things) {}

!. Send your object that you believe you have to | Measure-Object. If it only counts 1 object you have 1 long string and foreach won’t be able to process that

  1. have you heard of the arp command line tool? This is like the DNS database for MAC Addresses in the ARP cache of your local machine. If you could resolve the IPs to a name it may accomplish your goal.
arp -a | ConvertFrom-String  | Select-Object -ExpandProperty P2 | Where-Object {$_ -notlike "Internet"} | Foreach-Object {ping -a $_}
  1. $NICMac | Measure-Object

if measure-object does not return a count greater than 1 your objects are being processed as one long string and not individual rows or objects