Search code examples
xmlpowershellipmac-address

Powershell: get local IP, MAC and Name of network card


I have been writing some powershell code, that's supposed to collect and store information about the computer in XML. But I can't seem to get IP, MAC and Name of network cards.

Here's a example of some code I wrote(working code):

#OSInfo
$newosinfo = (@($xml.computer.software.osinfo)[0])
Get-WmiObject -computer $compname Win32_OperatingSystem | 
ForEach-Object {
        $newosinfo = $newosinfo.clone() 
        $newosinfo.caption = $_.caption
        $newosinfo.serialnumber = [string]$_.serialnumber
        $newosinfo.OSArchitecture = $_.OSArchitecture
        $newosinfo.manufacturer = $_.manufacturer
        #Time $newosinfo.installdate;
        $xml.computer.software.AppendChild($newosinfo) > $null
}
$xml.computer.software.osinfo | where-object {$_.caption -eq ""} | foreach-object {$xml.computer.software.RemoveChild($_)}

And here is the code I tried tried to write(not working code):

$newnetwork = (@($xml.computer.software.network)[0])
Get-WmiObject -computer $compname Win32_NetworkAdapter -Filter 'NetConnectionStatus=2' | 
ForEach-Object {
        $newnetwork = $newnetwork.clone()
        $newnetwork = 1 | Select-Object Name, MAC, IP 
        $newnetwork.Name = $_.Name
        $newnetwork.MAC = $_.MacAddress
        $IP = $_.GetRelated('Win32_NetworkAdapterConfiguration')
        $newnetwork.IP = $IP | Select-Object -expand IPAddress
        $xml.computer.software.AppendChild($newnetwork) > $null
}
$xml.computer.software.network | where-object {$_.Name -eq ""} | foreach-object {$xml.computer.software.RemoveChild($_)}

This code, gives this error:

Cannot convert argument "0", with value: "@{Name=Intel(R) 82579V Gigabit Network Connect
ion; MAC=F4:6D:04:40:DB:6F; IP=10.0.0.12}", for "AppendChild" to type "System.Xml.XmlNod
e": "Cannot convert the "@{Name=Intel(R) 82579V Gigabit Network Connection; MAC=F4:6D:04
:40:DB:6F; IP=10.0.0.12}" value of type "Selected.System.Int32" to type "System.Xml.XmlN
ode"."
At A:\Dropbox\Bachelorprosjekt\Kode\Fungerende Script+kode\infoGatherer.ps1:177 char:43
+         $xml.computer.software.AppendChild <<<< ($newnetwork) > $null
    + CategoryInfo          : NotSpecified: (:) [], MethodException
    + FullyQualifiedErrorId : MethodArgumentConversionInvalidCastArgument

So my question is, are there anybody that knows or can write code like the above, that works? And by the way: is it smarter to collect information only about "activated" cards?


Solution

  • First, I am not sure why you are wrapping your XmlNode in an array, and then unwrapping it - as far as I can tell the following two lines are equivalent:

    $a = (@($xml.computer.software.network)[0])
    $b = $xml.computer.software.network
    

    The second thing I spotted, you have this weird 1 | Select Name, MAC, IP which I guess you are using to try and populate those properties on your XmlNode? What you are actually doing is changing the $newnetwork object you had previously cloned from an XmlNode to a PSCustomObject class - which later is going to break when you try to pass it in as an argument to the appendChild() method.

    Here is some working PowerShell code that might do what you are looking for. I am making some assumptions about your XML structure so you may need to adapt it to fit your exact needs:

    # setup sample XML
    $xml = [xml]"
      <computer><software><network>
        <Name />
        <MAC />
        <IP />
      </network></software></computer>"
    
    # duplicate network XmlNode and grab necessary info through WMI
    # note: there may be more than one IP Address bound
    #       on a given adapter. Use just the first one.
    $info = $xml.computer.software.network.clone()
    $nic = Get-WmiObject Win32_NetworkAdapter | select -first 1
    $ip = $nic.GetRelated("Win32_NetworkAdapterConfiguration") | 
        select -expand IPAddress -first 1
    
    # populate children with correct values
    $info.Name = $nic.Name
    $info.MAC = $nic.MACAddress
    $info.IP = [string]($ip)
    
    # finally append new XmlNode to software node
    $xml.computer.software.appendChild($info)