Nac Getting in Control of Your Mab Enabled Clients
It has been a while since I wrote a paper about the implementation of NAC. Now almost a year later it is finally in progress of implementation. One of the most time consuming processes and error sensitive ones is the adding of MAC addresses to the Active Directory of devices which doesn’t support Dot1X. Unfortunately there are a lot of devices which don’t speak Dot1X or having troubles with it. So if you want to do it right (IMO) you put these devices in different categories (and subnets) so you can put ACL’s on it (MAC spoofing can be easily done). At this moment we have three different categories within MAB authentication, which may grow in the near future; Thin clients, Printers and temporarily devices. To keep an clean view of all these MAC addresses in the AD I categories these MAC address in different OU’s, so I have three different OU’s which represent the different devices. We use Microsoft NPS server as Radius server and unfortunately you can’t (at least I didn’t find it) use the OU as a hit for a rule. So you also need to make three groups in which you place the MAC addresses (these are user objects in the AD). You also want to delete the “Domain User” group from the MAC address. Otherwise people would be able to login with MAC address on you domain members. So there you have already three different steps to just add one MAC address.
- Add the MAC address to the right OU.
- Add the MAC address to the right group.
- Delete the group Domain Users (to accomplish this, set the other group as primary.)
This isn’t a problem, but if you have to add MAC addresses regularly, this is quiet annoying and you easily forget one of those steps. Another thing you might consider is that most of the time MAC addresses are added by other persons, it would be nice if you give them a tool which makes it easier for them and less faulty. To accomplish this I wrote a Powershell script (actual my first one, so be nice :-) ). This scripts draws a simple menu where a user simply can add or delete a MAC address. Since we in the same project move the printers to DHCP (reservations) I also added this option.
Below you find the powershell script, make sure the users have rights to the right OU in the AD, in the example it is “Network Access” and also give them rights on the User folder in the AD, otherwise the “Domain Users” group can’t be deleted (Took me almost an hour). If you also want to use the DHCP functionality, make sure they have rights there too. The script makes use of Quest “ ActiveRoles Management Shelf”, so this one needs to be installed. I tried to translate all the Dutch comment, to English and I also filled the variables with fictional values. If you have any comments or improvements, please let me know. Since it is my first powershell script, I’m sure there are.
# =============================================================
# NAAM: nac_menu.ps1
# AUTEUR: Rob Maas
# DATUM: 21-03-2011
# COMMENT: Adding/deleting MAC addresses to the AD for MAB.
# =============================================================
#[ GENERAL ]
# DHCP Settings
$dhcpServer = "DHCPSERVER1"
$dhcpScopePrinters = "192.168.1.0"
# Apparaat specifieke eigenschappen
$printer = @{"Name" = "Printer"; `
"OU" = "ou=Printers,ou=MAC,ou=Network Access,ou=corporation,dc=domain,dc=com"; `
"GRP" = "NA_Printers"}
$thinclient = @{"Name" = "Thin Client"; `
"OU" = "ou=Thin Client,ou=MAC,ou=Network Access,ou=corporation,dc=domain,dc=com"; `
"GRP" = "NA_Thinclient"}
$temporary = @{"Name" = "Temporarily device"; `
"OU" = "ou=Temporarily,ou=MAC,ou=Network Access,ou=corporation,dc=domain,dc=com"; `
"GRP" = "NA_Temporarily"}
#[ MENU Declaration ]
# MAINMENU
$mnuMainTitle = "NAC Menu" #Title
# Name
$mnuMainItems = @((0..4),(0..4)) #Dummy values
$mnuMainItems[0][0] = "Add MAC address"
$mnuMainItems[0][1] = "Delete MAC address"
$mnuMainItems[0][2] = "Add printer to DHCP "
$mnuMainItems[0][3] = "Delete printer from DHCP"
$mnuMainItems[0][4] = "Exit"
# Corresponding functions
$mnuMainItems[1][0] = {ShowAddMacMenu}
$mnuMainItems[1][1] = {DelMAC}
$mnuMainItems[1][2] = {AddPrinterToDHCP}
$mnuMainItems[1][3] = {DelPrinterFromDHCP}
$mnuMainItems[1][4] = {Exit}
#ADDMAC MENU
$mnuAddMacTitle = "Add MAC address"
$mnuAddMAC = @((0..3),(0..3))
#Name
$mnuAddMac[0][0] = "Add Thinclient"
$mnuAddMac[0][1] = "Add printer"
$mnuAddMac[0][2] = "Add temporarily device"
$mnuAddMac[0][3] = "Main menu"
#Corresponding
$mnuAddMac[1][0] = {AddMac $thinclient}
$mnuAddMac[1][1] = {AddMac $printer}
$mnuAddMac[1][2] = {AddMac $temporarily}
$mnuAddMac[1][3] = {ShowMainMenu}
#[ -- SCRIPT -- ]
#Methods in alphabeticall order
function AddMac{
param($device)
$address = GetMac;
#New device
Write-Host "Give in the" $device["Name"] "name: " -NoNewline
$name = $Host.UI.ReadLine()
New-QADUser -Name $address -UserPassword $address `
-DisplayName $address `
-LastName $address `
-FirstName $address `
-UserPrincipalName $address `
-Description $name `
-SamAccountName $address `
-ParentContainer $device["OU"]
#Unable to change password
Set-QADUser -Identity $address -PasswordNeverExpires $true | Out-Null
#Add to right group and delete "domain users" group
Add-QADGroupMember -Identity $device["GRP"] -Member $address | Out-Null
Set-QADUser -Identity $address -ObjectAttributes @{PrimaryGroupID=(Get-QADGroup -Identity $device["GRP"]).PrimaryGroupToken } #| Out-Null
Remove-QADGroupMember -Identity "Domain Users" -Member $address #| Out-Null
Write-Host "Account is created !!!" -ForegroundColor Yellow
#If it is a printer, add to DHCP?
if ($device -eq $printer){
$dhcp = Read-Host "Add the printer to DHCP? (Y|N) ?"
if ($dhcp -eq "y") {AddPrinterToDHCP $name $address}
}
if (Again) {AddMac $device} else {ShowMainMenu}
}
function Again{
$again = Read-Host "Again (Y|N) ? "
switch ($again){
"Y" {return $true}
default {return $false}
}
}
#Add printer to DHCP
function AddPrinterToDHCP{
param($name, $address)
if (($address -eq $null) -or ($name -eq $null)){
$name = Read-Host "Printer name: "
$address = GetMac $false
}
$ip = Read-Host "The IP address of the printer (192.168.1.0)?"
Write-Host "Printer: `t $name"
Write-Host "IP: `t`t $ip"
Write-Host "MAC: `t`t $address"
$ok = Read-Host "Are the above details correct (Y|N|X = Menu) ?"
switch ($ok){
"y" {
Invoke-Expression -Command "netsh dhcp server $dhcpServer scope $dhcpScopePrinters add reservedip $ip $address $name" | Out-Null
Invoke-Expression -Command "netsh dhcp server $dhcpserver scope $dhcpScopePrinters set reservedoptionvalue $ip 012 STRING $name"
if (Again) {AddPrinterToDHCP} else {ShowMainMenu}
break}
"n" {$name = $null
$address = $null
AddPrinterToDHCP
break}
"x" {ShowMainMenu
break}
}
$name = $null
$address = $null
if (Again) {AddPrinterToDHCP} else {ShowMainMenu}
}
function DelMaC{
$address = GetMac $false $true
$delete = Read-Host "Are you sure, you want to delete $address (Y|N) ? "
switch ($delete){
"y" {Remove-QADObject -Force -Identity $address | Out-Null
Write-Host "$address verwijderd!" -ForegroundColor Yellow
if (Again) {DelMac} else {ShowMainMenu}
break}
default {ShowMainMenu
break}
}
}
function DelPrinterFromDHCP{
$address = GetMac $false $true
$ip = Read-Host "The IP address of the printer (192.168.1.0)?"
Write-Host "MAC Adres: `t $address"
Write-Host "IP Adres: `t $ip"
$ok = Read-Host "Are the above details correc (Y|N|X = Menu) ?"
switch ($ok){
"y" {
Invoke-Expression -Command "netsh dhcp server $dhcpServer scope $dhcpScopePrinters delete reservedip $ip $address"
if (Again) {DelPrinterFromDHCP} else {ShowMainMenu}
ShowMainMenu
break}
"n" {$address = $Null
DelPrinterFromDHCP
break}
"x" {ShowMainMenu
break}
}
}
function DrawMenu{
param($menuItems, $menuTitle, $menuPosition)
$fgColor = $Host.UI.RawUI.ForegroundColor
$bgColor = $Host.UI.RawUI.BackgroundColor
cls
$l = $menuItems[0].Length - 1;
$menuWidth = $menuTitle.Length + 8
Write-Host "`t" -NoNewline
Write-Host ("*" * $menuWidth) -ForegroundColor $fgColor -BackgroundColor $bgColor
Write-Host "`t" -NoNewline
Write-Host "* $menuTitle *" -ForegroundColor $fgColor -BackgroundColor $bgColor
Write-Host "`t" -NoNewline
Write-Host ("*" * $menuWidth) -ForegroundColor $fgColor -BackgroundColor $bgColor
Write-Host ""
Write-Debug "L: $l MenuItems: $menuItems MenuPosition: $menuPosition"
for ($i = 0; $i -le $l; $i++){
Write-Host "`t" -NoNewline
if ($i -eq $menuPosition){
Write-Host " $($menuItems[0][$i])" -ForegroundColor $bgcolor -BackgroundColor $fgColor
} else {
Write-Host " $($menuItems[0][$i])" -ForegroundColor $fgcolor -BackgroundColor $bgColor
}
}
Write-Host
}
function Exit{
Invoke-Expression -Command "exit"
}
#Check if the given MAC address is valid.
function GetMAC{
param([bool]$new = $true, #Has to be new in the AD
[bool]$exist = $false) #Must exist in the AD
$mac = Read-Host "Give in the MAC address in lowercase and withouth punctuations: "
#Check if the address has a length of 12
If ($mac.length -ne 12){
Write-Host "Invalid address!" -ForegroundColor Red
if (Again) {GetMac $new $exist; return} else {ShowMainMenu; return}
}
If (($new) -and (Get-QADUser -Name $mac)){
# Already exist
Write-Host "Address already exist!" -ForegroundColor Red
if (Again) {GetMAC $new $exist; return} else {ShowMainMenu; return}
}
if ((-not $new) -and ($exist) -and (-not (Get-QADUser -Name $mac))){
#Address not found
Write-Host "Address not found! " -ForegroundColor Red
if (Again) {GetMAC $new $exist; return} else {ShowMainMenu; return}
}
return $mac
}
function Menu{
param($menuItems, $menuTitle)
$vkeyCode = 0
$menuPosition = 0
DrawMenu $menuItems $menuTitle $menuPosition
While ($vkeycode -ne 13){
$press = $Host.UI.RawUI.ReadKey("NoEcho,IncludeKeyDown")
$vkeyCode = $press.virtualkeycode
Write-Host "$($press.character)" -NoNewLine
If ($vkeyCode -eq 38) {$menuPosition--} #Down
If ($vkeyCode -eq 40) {$menuPosition++} #Up
If ($menuPosition -lt 0) {$menuPosition = $menuItems[0].Length - 1}
If ($menuPosition -ge $menuItems[0].Length) {$menuPosition = 0}
DrawMenu $menuItems $menuTitle $menuPosition
}
$($menuItems[1][$menuPosition]).Invoke()
}
function ShowAddMACMenu{
Menu $mnuAddMac $mnuAddMacTitle
}
function ShowMainMenu{
Menu $mnuMainItems $mnuMainTitle
}
ShowMainMenu