Import MAC-IP reservation vào DHCP server

# trước khi chạy: kiểm tra csv dạng UTF-8, check duplicate MAC
# ghi đè lên các bản ghi đã có nếu trùng MAC
# Xóa các reserve có trên DHCP nhưng không có trong file. Không xóa các bản ghi DHCP bình thường
# Ghi log ra file CSV kèm thời gian, action
# ================= CONFIG =================
$ScopeId = "x.x.x.x"
$CsvPath = "C:\bat\Reserve-MAC-IP.csv"
$LogPath = "C:\bat\Dhcp-Reserve-Log.csv"

$rawCsv = Import-Csv -Path $CsvPath -Encoding UTF8

# ================= FUNCTION =================

# Format MAC về aa-bb-cc-dd-ee-ff
function Format-Mac($mac) {
    $mac = $mac -replace "[:-]", ""
    return ($mac.ToLower() -split '(.{2})' | Where-Object { $_ }) -join "-"
}

function Write-Log($mac, $ip, $desc, $action) {

    $time = Get-Date -Format "yyyy-MM-dd HH:mm:ss"

    $logObj = [PSCustomObject]@{
        "MAC"         = $mac
        "IP"          = $ip
        "Description" = $desc
        "Action"      = $action
        "Time"        = $time
    }

    Write-Host ("[{0}] {1} | {2} | {3} | {4}" -f $time, $action, $mac, $ip, $desc)

    if (!(Test-Path $LogPath)) {
        $logObj | Export-Csv -Path $LogPath -NoTypeInformation -Encoding UTF8
    } else {
        $logObj | Export-Csv -Path $LogPath -NoTypeInformation -Append -Encoding UTF8
    }
}

# ================= NORMALIZE CSV =================
$csvData = $rawCsv | ForEach-Object {
    [PSCustomObject]@{
        MAC         = (Format-Mac $_.'MAC validate')
        IP          = $_.'IP Reserve'
        Description = $_.Description
    }
}

# ================= CHECK DUPLICATE MAC =================
$dupMac = $csvData | Group-Object MAC | Where-Object { $_.Count -gt 1 }

foreach ($d in $dupMac) {
    Write-Host ("WARNING: DUPLICATE MAC {0} ({1} records) -> giữ dòng cuối" -f $d.Name, $d.Count) -ForegroundColor Yellow
}

# ================= REMOVE DUPLICATE (GIỮ DÒNG CUỐI) =================
$csvData = $csvData |
    Group-Object MAC |
    ForEach-Object { $_.Group[-1] }

# ================= GET EXISTING =================
$existingReservations = Get-DhcpServerv4Reservation -ScopeId $ScopeId

$existingByMac = @{}
foreach ($res in $existingReservations) {
    $existingByMac[$res.ClientId.ToLower()] = $res
}

$csvMacSet = @{}

# ================= ADD / OVERWRITE =================
foreach ($row in $csvData) {

    $mac  = $row.MAC
    $ip   = $row.IP
    $desc = $row.Description

    $csvMacSet[$mac.ToLower()] = $true

    if ($existingByMac.ContainsKey($mac.ToLower())) {

        try {
            Remove-DhcpServerv4Reservation -ScopeId $ScopeId -ClientId $mac -Confirm:$false -ErrorAction Stop
            Add-DhcpServerv4Reservation -ScopeId $ScopeId -IPAddress $ip -ClientId $mac -Description $desc -ErrorAction Stop

            Write-Log $mac $ip $desc "Overwrite"
        } catch {
            Write-Host "ERROR Overwrite: $mac" -ForegroundColor Red
        }

    } else {

        try {
            Add-DhcpServerv4Reservation -ScopeId $ScopeId -IPAddress $ip -ClientId $mac -Description $desc -ErrorAction Stop

            Write-Log $mac $ip $desc "Add"
        } catch {
            Write-Host "ERROR Add: $mac" -ForegroundColor Red
        }
    }
}

# ================= DELETE =================
foreach ($res in $existingReservations) {

    $mac = $res.ClientId.ToLower()

    if (-not $csvMacSet.ContainsKey($mac)) {
        try {
            Remove-DhcpServerv4Reservation -ScopeId $ScopeId -ClientId $res.ClientId -Confirm:$false -ErrorAction Stop

            Write-Log $res.ClientId $res.IPAddress $res.Description "Delete"
        } catch {
            Write-Host "ERROR Delete: $mac" -ForegroundColor Red
        }
    }
}

No comments:

Post a Comment

Import MAC-IP reservation vào DHCP server

# trước khi chạy: kiểm tra csv dạng UTF-8, check duplicate MAC # ghi đè lên các bản ghi đã có nếu trùng MAC # Xóa các reserve có trên DHCP n...