PowerShell-script scanner nettverket og finner alle enheter med IP og MAC-adresse

🔍 Finn alle enheter på nettverket med PowerShell – inkludert MAC-adresse og produsent

Vet du egentlig hvilke enheter som er koblet til bedriftsnettverket ditt? En ukjent enhet på nettverket kan være en sikkerhetsrisiko – og å ha oversikt er første steg mot god IT-kontroll.

Med dette PowerShell-scriptet kan du scanne hele nettverket, finne alle aktive enheter og få ut IP-adresse, hostname, MAC-adresse og produsent – og eksportere resultatet til CSV for enkel oversikt i Excel.

⚙️ Hva gjør scriptet?

  1. Finner automatisk hvilket subnett PC-en er på
  2. Lar deg velge nettverkskort hvis du har flere
  3. Scanner alle 254 adresser i subnettet
  4. Slår opp hostname for hver aktive enhet via DNS
  5. Henter MAC-adresse fra ARP-tabellen
  6. Slår opp produsent basert på MAC-adresse via åpent API
  7. Viser responstid i millisekunder
  8. Eksporterer resultatet til CSV hvis du ønsker det

📄 Fullt script

					# =============================================================================
# Script by Logje Data AS
# Scan-Network.ps1
# Scanner nettverket og lister opp alle aktive enheter med MAC-adresse
# =============================================================================

# ----- Finn nettverksadaptere ----
Write-Host "=== Nettverksskanner ===" -ForegroundColor Cyan

$adapters = Get-NetIPAddress -AddressFamily IPv4 |
    Where-Object { $_.IPAddress -notmatch "^127\." -and $_.PrefixOrigin -ne "WellKnown" }

if ($adapters.Count -eq 0) {
    Write-Error "Ingen aktive nettverksadaptere funnet."
    exit 1
}

# ----- Velg adapter hvis flere ----
if ($adapters.Count -eq 1) {
    $localIP = $adapters[0].IPAddress
    $adapter = $adapters[0].InterfaceAlias
} else {
    Write-Host "`nFlere nettverksadaptere funnet:" -ForegroundColor Cyan
    for ($i = 0; $i -lt $adapters.Count; $i++) {
        Write-Host "  [$($i + 1)] $($adapters[$i].IPAddress) – $($adapters[$i].InterfaceAlias)"
    }
    do {
        $adapterChoice = Read-Host "`nVelg adapter (nummer)"
        $adapterInt = $adapterChoice -as [int]
    } while ($adapterInt -lt 1 -or $adapterInt -gt $adapters.Count)

    $localIP = $adapters[$adapterInt - 1].IPAddress
    $adapter = $adapters[$adapterInt - 1].InterfaceAlias
}

$subnet = ($localIP -split "\.")[0..2] -join "."

Write-Host "`nLokal IP  : $localIP" -ForegroundColor Green
Write-Host "Adapter   : $adapter" -ForegroundColor Green
Write-Host "Subnett   : $subnet.0/24" -ForegroundColor Green
Write-Host "`nStarter scanning – dette kan ta litt tid...`n" -ForegroundColor Cyan

# ----- Scanner nettverket ----
$results = @()
$counter = 0

1..254 | ForEach-Object {
    $ip = "$subnet.$_"
    $counter++

    Write-Progress -Activity "Scanner nettverket" `
                   -Status "Sjekker $ip ($counter av 254)" `
                   -PercentComplete (($counter / 254) * 100)

    $ping = Test-Connection -ComputerName $ip -Count 1 -ErrorAction SilentlyContinue

    if ($ping) {
        try {
            $hostname = [System.Net.Dns]::GetHostEntry($ip).HostName
        } catch {
            $hostname = "Ukjent"
        }

        $responseTime = $ping.ResponseTime

        Write-Host "  ✔ $ip".PadRight(20) -ForegroundColor Green -NoNewline
        Write-Host " $hostname".PadRight(45) -NoNewline
        Write-Host " ${responseTime}ms" -ForegroundColor DarkGray

        $results += [PSCustomObject]@{
            IP         = $ip
            Hostname   = $hostname
            Responstid = "${responseTime}ms"
            MAC        = "Henter..."
            Produsent  = "Henter..."
            Tidspunkt  = (Get-Date -Format "yyyy-MM-dd HH:mm:ss")
        }
    }
}

Write-Progress -Activity "Scanner nettverket" -Completed

# ----- Hent ARP-tabell og berik resultater med MAC-adresse ----
Write-Host "`nHenter MAC-adresser fra ARP-tabell..." -ForegroundColor Cyan

$arpOutput = arp -a
$arpTable  = @{}

foreach ($line in $arpOutput) {
    if ($line -match "(\d{1,3}(\.\d{1,3}){3})\s+(([0-9a-f]{2}-){5}[0-9a-f]{2})") {
        $arpIP  = $matches[1]
        $arpMAC = $matches[3].ToUpper()
        $arpTable[$arpIP] = $arpMAC
    }
}

# ----- Slå opp produsent fra MAC-adresse via API ----
function Get-MacVendor {
    param ([string]$mac)
    try {
        $cleanMac = $mac -replace "-", ""
        $response = Invoke-RestMethod -Uri "https://api.macvendors.com/$cleanMac" `
                                      -ErrorAction SilentlyContinue `
                                      -TimeoutSec 3
        return $response
    } catch {
        return "Ukjent"
    }
}

# ----- Berik hvert resultat med MAC og produsent ----
Write-Host "Slår opp produsentnavn – dette tar litt tid...`n" -ForegroundColor Cyan

for ($i = 0; $i -lt $results.Count; $i++) {
    $ip  = $results[$i].IP
    $mac = $arpTable[$ip]

    if ($mac) {
        $results[$i].MAC = $mac
        $vendor = Get-MacVendor -mac $mac
        $results[$i].Produsent = $vendor
        Start-Sleep -Milliseconds 500
    } else {
        $results[$i].MAC       = "Ikke funnet"
        $results[$i].Produsent = "Ikke funnet"
    }
}

# ----- Oppsummering ----
Write-Host "`n=======================================" -ForegroundColor Cyan
Write-Host "Scanning fullført!" -ForegroundColor Green
Write-Host "Aktive enheter funnet: $($results.Count)" -ForegroundColor Green
Write-Host "Subnett scannet      : $subnet.0/24" -ForegroundColor Green
Write-Host "=======================================" -ForegroundColor Cyan

# ----- Vis tabell ----
if ($results.Count -gt 0) {
    Write-Host "`nResultat:" -ForegroundColor Cyan
    $results | Format-Table IP, Hostname, MAC, Produsent, Responstid -AutoSize
}

# ----- Eksporter til CSV ----
$exportCSV = Read-Host "`nVil du eksportere resultatet til CSV? (j/n)"

if ($exportCSV -eq "j") {
    $csvFileName = "nettverksscan_$(Get-Date -Format 'yyyy-MM-dd_HH-mm').csv"

    do {
        $csvFolder = Read-Host "Hvor skal CSV lagres? (standard: C:\temp)"
        if ($csvFolder -eq "") { $csvFolder = "C:\temp" }
    } while ($csvFolder -eq "")

    if (-not (Test-Path $csvFolder)) {
        New-Item -ItemType Directory -Path $csvFolder | Out-Null
    }

    $csvPath = "$csvFolder\$csvFileName"

    try {
        $results | Select-Object IP, Hostname, MAC, Produsent, Responstid, Tidspunkt |
            Export-Csv -Path $csvPath -NoTypeInformation -Encoding UTF8
        Write-Host "`nCSV eksportert til: $csvPath" -ForegroundColor Green
    } catch {
        Write-Error "Kunne ikke eksportere CSV: $_"
    }
}

Write-Host "`nFerdig." -ForegroundColor Green
exit 0
				

🔍 Steg-for-steg forklaring

📌 Del 1 – Finn nettverksadaptere automatisk
					$adapters = Get-NetIPAddress -AddressFamily IPv4 |
    Where-Object { $_.IPAddress -notmatch "^127\." -and $_.PrefixOrigin -ne "WellKnown" }
				

Get-NetIPAddress henter alle nettverksadaptere. -AddressFamily IPv4 filtrerer bort IPv6. Where-Object fjerner loopback-adressen (127.x.x.x) og virtuelle adaptere som Hyper-V og VPN. Har maskinen bare ett nettverkskort velges det automatisk. Har den flere får du opp en liste og velger selv.

📊 Del 2 – Fremdriftsvisning med Write-Progress
					Write-Progress -Activity "Scanner nettverket" `
               -Status "Sjekker $ip ($counter av 254)" `
               -PercentComplete (($counter / 254) * 100)
				

Write-Progress viser en fremdriftslinje øverst i PowerShell-vinduet med prosentandel og hvilken IP som sjekkes akkurat nå. Mye mer oversiktlig enn å vente i blinde mens scriptet kjører.

🖥️ Del 3 – Hostname-oppslag via DNS
					try {
    $hostname = [System.Net.Dns]::GetHostEntry($ip).HostName
} catch {
    $hostname = "Ukjent"
}
				

For hver aktive IP prøver scriptet å slå opp hostname via DNS. Lykkes det får du f.eks. KONTOR-PC01.logje.local i stedet for bare en IP-adresse. Mislykkes oppslaget vises Ukjent – scriptet stopper ikke.

🔌 Del 4 – MAC-adresse fra ARP-tabellen
					$arpOutput = arp -a
$arpTable  = @{}

foreach ($line in $arpOutput) {
    if ($line -match "(\d{1,3}(\.\d{1,3}){3})\s+(([0-9a-f]{2}-){5}[0-9a-f]{2})") {
        $arpIP  = $matches[1]
        $arpMAC = $matches[3].ToUpper()
        $arpTable[$arpIP] = $arpMAC
    }
}
				

Etter at ping-scanningen er ferdig kjøres arp -a og outputen parses med regex. ARP-tabellen inneholder MAC-adresser for alle enheter PC-en har kommunisert med nylig. Resultatet lagres i en hashtabell med IP som nøkkel og MAC-adresse som verdi – og slås opp mot hvert resultat fra ping-scanningen.

🏭 Del 5 – Produsent-oppslag via MAC-adresse API
					function Get-MacVendor {
    param ([string]$mac)
    try {
        $cleanMac = $mac -replace "-", ""
        $response = Invoke-RestMethod -Uri "https://api.macvendors.com/$cleanMac" `
                                      -ErrorAction SilentlyContinue `
                                      -TimeoutSec 3
        return $response
    } catch {
        return "Ukjent"
    }
}
				

De første tre oktettene av en MAC-adresse identifiserer produsenten – dette kalles OUI (Organizationally Unique Identifier). Funksjonen Get-MacVendor sender MAC-adressen til det gratis og åpne APIet api.macvendors.com som returnerer produsentnavnet. Det er lagt inn 500ms pause mellom hvert oppslag for å unngå rate-limiting. Mislykkes oppslaget vises Ukjent.

Eksempel på hva du kan se:

IPHostnameMACProdusentResponstid
192.168.1.1router.localA4-91-B1-XX-XX-XXASUS1ms
192.168.1.10KONTOR-PC0100-1A-2B-XX-XX-XXDell Inc2ms
192.168.1.20Resepsjon_Skriver00-80-77-XX-XX-XXBrother Industries4ms
192.168.1.45iPhone-KariF8-4D-89-XX-XX-XXApple Inc22ms
📋 Del 6 – CSV-eksport med alle kolonner
					$results | Select-Object IP, Hostname, MAC, Produsent, Responstid, Tidspunkt |
    Export-Csv -Path $csvPath -NoTypeInformation -Encoding UTF8
				

CSV-filen inneholder seks kolonner: IP, Hostname, MAC, Produsent, Responstid og Tidspunkt. Filnavnet inneholder dato og tidspunkt automatisk – f.eks. nettverksscan_2026-04-08_14-30.csv – slik at du alltid vet når scanningen ble gjort. Filen kan åpnes direkte i Excel.

💡 Tips og triks

Skann går sakte? En full skann av 254 adresser tar gjerne 2–5 minutter. Du kan begrense skannen til et mindre område:

					# Scan kun de første 50 adressene
1..50 | ForEach-Object { ... }
				

Ukjente enheter i listen? Se på produsent-kolonnen i CSV-filen. En enhet fra en produsent du ikke kjenner igjen kan være verdt å undersøke nærmere. Er det en gammel enhet som ble glemt? En privat mobil på bedriftsnettverket? En ukjent ruter?

Lagre scan som fast rutine? Legg scriptet inn i Windows Oppgaveplanlegger og la det kjøre automatisk én gang i uken. Da har du alltid en fersk oversikt over nettverket i CSV-format – og kan enkelt sammenligne hvem som har dukket opp eller forsvunnet.

⚠️ Advarsel

Nettverksscanning bør kun gjøres på nettverk du har lov til å scanne. Bruk dette scriptet kun på eget bedriftsnettverk. Produsent-oppslag krever internettilgang og kan feile hvis APIet er utilgjengelig – scriptet fortsetter uansett og viser «Ukjent».

📞 Trenger du hjelp?

Vil du ha full oversikt over nettverket ditt – eller hjelp til å rydde opp i ukjente enheter? Ta kontakt med Logje Data AS – vi hjelper bedrifter i Troms og Finnmark med nettverk, IT-sikkerhet og automatisering. ✅ Én leverandør. Én kontakt. Full kontroll.