Sunday, November 24, 2019

Script to move On-Premise users mailboxes to Office 365 (Exchange Online) Automated

Migrating mailboxes to Office 365 was a quite challenging Project, primarily due third party software that we use as MDM and the customization of tools and access. Once  we completed our planned migration tasks by 500 mailbox each (this was the recommended number by Microsoft) we decided to keep one On-Prem Exchange 2016 server for some shared mailboxes used by Service accounts applications that are not compatible with Office 365. Also, because our Hybrid environment and our mailbox provision process, we decided to create new users mailboxes on-Prem and move them to Office 365 on daily basis. 
For we I develop a Script that makes the Job, just schedule it in  MS Orchestrator or Tasks Scheduler and that it, a report with the users to migrate will be delivered to the specified admin mailbox or DL.

Hope this script helps you make your life easier, please send me comments or questions.


##################################
<#PSScriptInfo

.VERSION 1.0

.AUTHOR "ralbertomx@gmail.com"

#>

<#

.DESCRIPTION
Script to move On-Premise users mailboxes to Office 365. The script can be run interactive or schedule in regulat basis to move new mailboxes.
The following 5 variables are the only ones you need to modify.
Place the "format4.css" (provided as example) and "creds\EOPCreds.txt" in the same folder, or modify paths if not.

#>


# variables to modify
$adminmail = "admin@emaildomain.com"  # Modify the recipient of the report
$frommail = "Office365@maildomain.com"  # Modify the sender of the report
$smtphost = "smtp.maildomain.com"  # Modify your SMTP host
$UPNsufix = "maildomain.com"  # Modify your UPN sufix in case is different from DNS AD domain, without the "@" character
$TenantDomain = "Company123.mail.onmicrosoft.com" # Modify your Tenant Domain, without the "@" character


#-------Migration Script, define Job name and CSS format
$JName = "DailyMigrationJob"
$head = Get-Content ".\format4.css"


# Specifu the file to be used as input for the migration
$txtfile = ".\mails.csv"
Set-Content $txtfile "EmailAddress"

# Connect to you Exchange on Prem
$exchangeser = "EXCHANGECAS01"  #Specify CAS server
$session = New-PSSession -ConfigurationName Microsoft.Exchange -ConnectionURI http://$exchangeser/powershell/ -Authentication kerberos
import-PSSession $session -AllowClobber

#Connect to AD module
Import-Module ActiveDirectory

# Get User mailboxes and identify its location 
$table = Get-ADUser -Filter {Enabled -eq "True"} -Properties distinguishedName,samaccountname,mail,userprincipalname,employeeType,msExchRecipientTypeDetails `
| where {($_.msExchRecipientTypeDetails)} `
| select @{Label="Location";Expression={
    If ($_.msExchRecipientTypeDetails -eq "1") {"On-Prem"}
    ElseIf ($_.msExchRecipientTypeDetails -eq "4") {"On-Prem"}
    ElseIf ($_.msExchRecipientTypeDetails -eq "2147483648") {"Office365"}
    ElseIf ($_.msExchRecipientTypeDetails -eq "34359738368") {"Office365"}
    Else {"OtherLocation"}
    }},samaccountname,mail,userprincipalname,employeeType

# Filter the users mailboxes that are On-Prem only
$csvData = $table | where {$_.Location -eq "On-Prem" }


# Notify about mailbox migration
If ($csvData) {
    ## Connect to EOP
    If ($session2.state -ne "Opened") { 
        Write-Host "Opennig EOP Session.." -ForegroundColor Cyan
        <# Use this session to input your credentials manually
        #$session = New-PSSession -ConfigurationName Microsoft.Exchange -ConnectionUri https://ps.outlook.com/powershell -Authentication Basic -AllowRedirection -Credential $(Get-Credential)
        #Import-PSSession $session
        #>
        # Use this section to save the credential password inside a file named ".\creds\EOPCreds.txt" and automate the Job, 
        $AdminName = "upn@ad-domain.local" 
        $Pass = Get-Content ".\creds\EOPCreds.txt" | ConvertTo-SecureString
        $cred = new-object -typename System.Management.Automation.PSCredential -argumentlist $AdminName, $Pass
        $Session2 = New-PSSession -ConfigurationName Microsoft.Exchange -ConnectionUri https://outlook.office365.com/powershell-liveid/ -Credential $cred -Authentication Basic -AllowRedirection
        Import-PSSession $Session2
    }
    Else {
        Write-Host "Session to EOP is opened.." -ForegroundColor Green
    }

 # removing previous mig job
    $MigJob = Get-MigrationBatch -Identity $JName -ErrorAction SilentlyContinue

    If ($MigJob) {
        If ($MigJob.Status.Value -like "*Completed*") {  # Removing a previous Job if completed or completed with errors
            Write-Host "Job Exists and completed, removing" -ForegroundColor Green
            Remove-MigrationBatch -Identity $JName -Confirm:$false
            Start-Sleep -Seconds 360
        }
        ElseIf ($MigJob.Status.Value -eq "Syncing") {  # If job is Syncing, exit the script
            Write-Host "Exists but not completed, exiting script" -ForegroundColor Magenta 
            Exit 
        }
    }
    Else {Write-Host "Job Doesnt exist, continue creating job" -ForegroundColor Yellow}
    Write-Host "Script continues.." -ForegroundColor Green

    $count = $csvData.Count
    $strBody = $csvData |  ConvertTo-Html -Title "Office 365 DailyMigrationJob" -head $head -PreContent "The listed mailboxes will be scheduled to be migrated:"
    Send-MailMessage -To $adminmail -From $frommail -Subject "Office 365 DailyMigrationJob, Total: $count mailboxes" `
    -SmtpServer $smtphost -BodyAsHtml -Body "$strBody"

    # Add Onmicrosoft email address
    foreach ($mbx in $csvData){
        $pri = $mbx.mail
        $newaddress = ($mbx.mail -split "@")[0] + "@" + $TenantDomain
        If ($mbx.EmailAddresses -like "*$TenantDomain*") { #--TargetAddress--
            #Write-Host "`t $usr Email contains herbalife663.mail.onmicrosoft.com" -ForegroundColor Green
            #Write-Host $mbx.EmailAddresses
        }
        Else {
            Write-Host "`t Mail.OnMicrosoft.com address missing for user $pri, adding: $newaddress" -ForegroundColor Yellow
            Set-Mailbox $pri -EmailAddresses @{add=$newaddress}
        }


    # UPN correction
        $newUPN = ($mbx.userPrincipalName -split "@")[0] + "@" + $UPNsufix
        If ($user.userPrincipalName -like "*$UPNsufix") {
            #Write-Host "`t $($user.samAccountName) UPN is herbalife.com" -ForegroundColor Green
        }
        Else {
            Write-Host "`t UPN is not correct for user $($mbx.samAccountName), setting: $newUPN" -ForegroundColor Yellow
            Set-aduser $mbx.samAccountName -userPrincipalName $newUPN
        }
    }
$currtime = Get-date
    Write-host "$currtime - Waiting 45 minutes for ADConnect sync.." -foregroundcolor gray  
    Start-Sleep -Seconds 2700  # If your ADSync schedule is different, you can change this value in seconds
    
    Write-host "Continuing with Job.." -foregroundcolor gray

    ##CSV file population
    $csvdata | foreach {
        $mails = $_.mail
        Add-Content $txtfile $mails
    }

    # Move Mailbox
    $csvfile=[System.IO.File]::ReadAllBytes($txtfile)
    New-MigrationBatch -CSVData $csvfile -Timezone "Pacific Standard Time" -Name "$JName" `
    -SourceEndpoint amer-owa.hrbl.com -TargetDeliveryDomain $TenantDomain `
    -AutoStart -AutoComplete -BadItemLimit 100 -NotificationEmails $adminmail -confirm:$false
}

#########################################

C.R.

Monday, August 12, 2013

Open Source Load Balancer for Exchange 2010

On many installations of Exchange 2010, we decided to use DNS Round Robin as our Load Balancer method for the CAS services. This works well until one of the CAS server fails or is taked offline. DNS Round robin doesn't check service status so it keeps returning the failed server IP address even if its offline. So clients will receive a connection error until the Browser cookie expires or DNS TTL expires on the client OS. This is a big head-each because some clients are working OK (the ones that are using the online CAS) and some are not.

Another solution its to use Windows Network Load Balance (WNLB), a windows built-in Feature that works, but not very well, specially in  virtualized environments. It generates a high amount of traffic and... Exchange 2010 with WNLB is not supported by Microsoft :( .

There are out there many commercial solutions like F5, BigIP or Cisco CSS, but they are expensive and cost is high for only one service needed for these products. Digging into Open Source solutions, I found relayd (previously hoststated). Relayd looks very good, but seems that his power is to interact with OpenBSD PF which I like too, but for doing only Load Balancing, I thing its too much (I will try it in the future).

The Load Balancing tool of my choice is haproxy. This tools is very cool, its latest stable version 1.4 was released on 2013/06/17 meaning that its an active project and continues in development (v1.5-dev19). This tool is used by other network products as load balancer or high availavility module. Its supported by Linux, Solaris, FreeBSD and OpenBSD. I will use FreeBSD as Operating System for the  HAProxy. This might not be the best recommended option but we are not an ISP needed hundreds of thousand of connections, only need some thousand. If you need very high speeds like 10Gbps kinks, read the haproxy supported platforms documentation, they recommend using haproxy on Linux kernel 2.6.32 and above for a better performance and high speed bandwidths (above 10Gbps).  


For my scenario, i used VirtualBox 4.2.16 as my virtualization platform. I created the following vm's:

  • lb1.- HAProxy Box. FreeBSD 9.1 x86, 2 NIC's
  • ex1.- Exchange 2010 sp2 Box, Windows 2008R2, CAS, HT and Mailbox Roles.
  • ex2.- Exchange 2010 sp2 Box, Windows 2008R2, CAS, HT and Mailbox Roles.
This is the Layout for the lab:



I divided this blog in three sections:
  1. Install the Loab Balancer OS and HAProxy package
  2. Configure Exchange CAS services 
  3. Configure HAProxy


1.- I created the virtual machine with two NIC's, one for the Load Balancer and other for Administration.First let start with the OS installation. I will use VirtualBox for the lab demostration. Download the FreeBSD 9.1 ISO image from the FreeBSD FTP site. Install FreeBSD using the default options, it will take you 10-15 mins only. 

After OS finishes, first thing its to install the Virtual Box Addtions:


# cd /usr/ports/emulators/virtualbox-ose-additions/

# make install clean BATCH=yes

===>  License GPLv2 accepted by the user
===>  Extracting for virtualbox-ose-additions-4.1.22
=> SHA256 Checksum mismatch for VirtualBox-4.1.22.tar.bz2.
===>  Refetch for 1 more times files: VirtualBox-4.1.22.tar.bz2
===>  License GPLv2 accepted by the user
=> VirtualBox-4.1.22.tar.bz2 doesn't seem to exist in /usr/ports/distfiles/.
=> Attempting to fetch http://download.virtualbox.org/virtualbox/4.1.22/VirtualBox-4.1.22.tar.bz2
fetch: http://download.virtualbox.org/virtualbox/4.1.22/VirtualBox-4.1.22.tar.bz2: Moved Temporarily
=> Attempting to fetch http://tmp.chruetertee.ch/VirtualBox-4.1.22.tar.bz2

VirtualBox-4.1.22.tar.bz2                       0% of   69 MB   44 kBps 27m53s

After guest addtions, we install the HAProxy package from the ports:

# cd /usr/ports/net/haproxy
# make install clean
===> Installing rc.d startup script(s)

*************************************************
*  Congratulations!  Haproxy is now installed.  *
*************************************************

Check the following directories for further info:
  documentation:  '/usr/local/share/doc/haproxy'
  examples:       '/usr/local/share/examples/haproxy'

rc.conf variables listing can be found in:

  '/usr/local/etc/rc.d/haproxy'


Modify the file /etc/rc.conf and add the following lines

haproxy_enable=""YES
haproxy_config="/usr/local/etc/haproxy.cfg"

The previos lines will start haproxy at bootup.


2.- For the Exchange server side, we need to set the TCP ports the RPC Client Access service and the Address Book Service. Why?..  Because this two services use MAPI which uses RCP connections. RPC uses TCP random ports, we would need to load balance across all thid 65K ports.. so we fix this to only two ports (59532 and 59533).

To do this for the RPC service, on each CAS open regedit.exe and Navigate to

HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\services\MSExchangeRPC\

Create the key named "ParametersSystem" and create a REG_DWORD setting named "TCP/IP Port" with value of 59532 (decimal):



Now for the AB service, navigate to 

HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\services\MSExchangeAB

Create the key named "Parameters" and create the REG_SZ setting named "RpcTcpPort" with the value of  59533.




Restart the so the changes be reflected.

To verify that the settings have applied, open an elevated command prompt window and type 'netstat -an | findstr "5953*"':



Both ports should be listening now.



3.- Now lets configure our Load Balncer. Create the file haproxy.cfg:

# vi /usr/local/etc/haproxy.cfg


You can copy and paste the following to the file and will explain later:

#### Begin File ####

global
        #uid 99
        #gid 99
        daemon
        stats socket /var/run/haproxy.stat mode 600 level admin
        maxconn 40000
        ulimit-n 81000
        pidfile /var/run/haproxy.pid

defaults
        mode    http
        contimeout      4000
        clitimeout      3600000
        srvtimeout      3600000
        balance roundrobin

listen  Exchange2010 192.168.100.20:80
        bind 192.168.100.20:25
        bind 192.168.100.20:110,192.168.100.20:135
        bind 192.168.100.20:139,192.168.100.20:443
        bind 192.168.100.20:59532,192.168.100.20:59533
        bind 192.168.100.20:6001-6004
        bind 192.168.100.20:993-995
        mode    tcp
        option  persist
        balance roundrobin
        stick-table type ip size 10240k expire 30m
        stick on src
        server CAS1 192.168.100.11 weight 1 check port 80 inter 5000 rise 2 fall 3
        server CAS2 192.168.100.12 weight 1 check port 80 inter 5000 rise 2 fall 3
        option redispatch
        option abortonclose
        maxconn 40000

listen  stats :7000
        stats   enable
        stats   uri /
        option  httpclose

        stats   auth admin01:Pa$$w0rd

####End File ####


The Global section which sets process-wide information and OS-specific. They are generally set once for all and do not need being changed once correct. Some of them have command-line equivalents. See the man file for more options.


Proxy configuration can be located in a set of sections:
 - defaults 
 - frontend 
 - backend  
 - listen   

The Defaults section sets default parameters for all other sections following
its declaration. 


A "frontend" section describes a set of listening sockets accepting client
connections.

A "backend" section describes a set of servers to which the proxy will connect
to forward incoming connections.

A "listen" section defines a complete proxy with its frontend and backend
parts combined in one section. It is generally useful for TCP-only traffic.


For our Load Balancer the "listen" section is where we configure the settings for Exchange. We name the section "Exchange2010" and here is where we bind each service that our balancer will be handling:


135 - RPC 
80/443 - OWA/ActiveSync/OutlookAnywhere
110 : POP
139 : Netbios
60000/60001 - These are the ones we just set on exchange server (For Mail and Address book) 
993-995: SSL POP/IMAP
6001 - 6004 : Exchange Information Store

After binding, the proxy will use Round Robin and peristance of 30 minutes. The affinity will be source IP. The master of the things... Will use port 80 to check the availability of the service. The option 'redispatch' tells to look another sever is check fails.

Last 'listen' section are the stats, in these section HAProxy listens on port 7000 (http) autenticating using the user and password provided. 

This is a big difference with NLB, we can monitor the Balancer status and see connections, response times, etc.




Don't forget to update your DNS records (owa, async, autodiscover,ews,CasArray,OAnywhere) to point to the VIP of the balancer.

Now if you have MS-NLB.. you have just realized that you are wasting resources and efforts maintaining a useless service..  Change to HAPROXY and give me your thoughts.

Hope this helps you.

Thursday, July 11, 2013

Get Exchange Roll up script

One of the tasks that I do as Exchange Admin is to patch and upgrade Exchange to the latest version. I cross with the issue about getting the Exchange Roll up version of my 63 Exchange Servers. There are many scripts out there but none satisfied to me.  So I created this power shell script that displays the Roll up version from Exchange 2007 to 2013. You must run it from Exchange Management Shell and of course need to have permissions to execute the 'Get-ExchangeServer' cmdlet. The results are send to console, but you can modify to export the results to a .csv file.

Here is an output of the results:



Well, hope that this script saves you many hours of work like it did it for me.

######################################

## GetExchanegRollUp.ps1 ##
## Creted By: Carlos Ramirez ##

Clear-Host
$ErrorActionPreference = "SilentlyContinue"
$tmpFilePath="c:\temp\E2k.csv"


#Get-ExchangeServer | where {$_.ServerRole -ne "Edge" -and $_.AdminDisplayVersion -like "Version 14*"} |  select-object  @{Name="svrName";Expression={$_.name}},@{Name="exDataPath";Expression={$_.DataPath}} | export-csv $tmpFilePath -notype -force

Get-ExchangeServer | Sort-Object $_.name | select-object  @{Name="svrName";Expression={$_.name}},@{Name="exDataPath";Expression={$_.DataPath}},@{Name="EXVersion";Expression={$_.AdminDisplayVersion}} | export-csv $tmpFilePath -notype -force


$Filecsv = import-csv $tmpFilePath
$BuildPath = $null
foreach($File in $Filecsv)
  {
   $ServerName = $File.svrName
   $MailboxPath = $File.exDataPath
   #echo $ServerName $MailboxPath
   $arrMailboxPath = $MailboxPath.split("\")
   $strBuildPath = $null
   for($i=0;$i-le $arrMailboxPath.length-2;$i++)
      {
  $strBuildPath=$strBuildPath + $arrMailboxPath[$i] + "\"
 } #End for
   
   $fixBuildPath = $strBuildPath.replace(":","$")
   $BuildPath = "\\" + $ServerName + "\" + $fixBuildPath + "Bin\ExSetup.exe"
   
   $ExBuildFile = get-item $BuildPath
   $ExBuildVersion = $ExBuildFile.VersionInfo.ProductVersion
   
   switch($ExBuildVersion)
      { "14.00.0639.021" {write-host $ServerName "-> Microsoft Exchange Server 2010 RTM" -foregroundcolor "green"}
"14.00.0682.001" {write-host $ServerName "-> Update Rollup 1 for Exchange Server 2010" -foregroundcolor "green"}
"14.00.0689.000" {write-host $ServerName "-> Update Rollup 2 for Exchange Server 2010" -foregroundcolor "green"}
"14.00.0694.000" {write-host $ServerName "-> Update Rollup 3 for Exchange Server 2010" -foregroundcolor "green"}
"14.00.0702.001" {write-host $ServerName "-> Update Rollup 4 for Exchange Server 2010" -foregroundcolor "green"}
"14.00.0726.000" {write-host $ServerName "-> Update Rollup 5 for Exchange Server 2010" -foregroundcolor "green"}
"14.01.0218.015" {write-host $ServerName "-> Microsoft Exchange Server 2010 SP1" -foregroundcolor "green"}
"14.01.0255.002" {write-host $ServerName "-> Update Rollup 1 for Exchange Server 2010 SP1" -foregroundcolor "green"}
"14.01.0270.001" {write-host $ServerName "-> Update Rollup 2 for Exchange Server 2010 SP1" -foregroundcolor "green"}
"14.01.0289.003" {write-host $ServerName "-> Update Rollup 3 for Exchange Server 2010 SP1" -foregroundcolor "green"}
"14.01.0289.007" {write-host $ServerName "-> Update Rollup 3-v3 for Exchange Server 2010 SP1" -foregroundcolor "green"}
"14.01.0323.001" {write-host $ServerName "-> Update Rollup 4 for Exchange Server 2010 SP1" -foregroundcolor "green"}
"14.01.0323.006" {write-host $ServerName "-> Update Rollup 4-v2 for Exchange Server 2010 SP1" -foregroundcolor "green"}
"14.01.0339.001" {write-host $ServerName "-> Update Rollup 5 for Exchange Server 2010 SP1" -foregroundcolor "green"}
"14.01.0355.002" {write-host $ServerName "-> Update Rollup 6 for Exchange Server 2010 SP1" -foregroundcolor "green"}
"14.01.0421.000" {write-host $ServerName "-> Update Rollup 7 for Exchange Server 2010 SP1" -foregroundcolor "green"}
"14.01.0421.002" {write-host $ServerName "-> Update Rollup 7-v2 for Exchange Server 2010 SP1" -foregroundcolor "green"}
"14.01.0421.003" {write-host $ServerName "-> Update Rollup 7-v3 for Exchange Server 2010 SP1" -foregroundcolor "green"}
"14.01.0438.000" {write-host $ServerName "-> Update Rollup 8 for Exchange Server 2010 SP1" -foregroundcolor "green"}
    "14.02.0247.005" {write-host $ServerName "-> Microsoft Exchange Server 2010 SP2"  -foregroundcolor "green"}
"14.02.0283.003" {write-host $ServerName "-> Update Rollup 1 for Exchange Server 2010 SP2"   -foregroundcolor "green"}
"14.02.0298.004" {write-host $ServerName "-> Update Rollup 2 for Exchange Server 2010 SP2"  -foregroundcolor "green"}
"14.02.0309.002" {write-host $ServerName "-> Update Rollup 3 for Exchange Server 2010 SP2"  -foregroundcolor "green"}
"14.02.0318.002" {write-host $ServerName "-> Update Rollup 4 for Exchange Server 2010 SP2"  -foregroundcolor "green"}
"14.02.0318.004" {write-host $ServerName "-> Update Rollup 4-v2 for Exchange Server 2010 SP2"  -foregroundcolor "green"}
"14.02.0328.005" {write-host $ServerName "-> Update Rollup 5 for Exchange Server 2010 SP2"  -foregroundcolor "green"}
"14.02.0328.010" {write-host $ServerName "-> Update Rollup 5-v2 for Exchange Server 2010 SP2"  -foregroundcolor "green"}
"14.02.0342.003" {write-host $ServerName "-> Update Rollup 6 for Exchange Server 2010 SP2"  -foregroundcolor "green"}
"14.03.0123.004" {write-host $ServerName "-> Microsoft Exchange Server 2010 SP3" -foregroundcolor "green"}
"14.03.0146.000" {write-host $ServerName "-> Update Rollup 1 for Exchange Server 2010 SP3" -foregroundcolor "green"}

default {write-host $ServerName "-> Undetermined version"  -foregroundcolor "red"}
 } #End switch

   } #End foreach
   

########################################

C.R.

Sunday, August 26, 2012

Network device management and graphs for the busy Admin

If you are a busy admin and want to setup a SNMP based monitoring system quickly and easy, try JFFNMS. Its licensed under the GNU GPL model so there is no charge for using or modifying the tool. I will install JFF in a VMWare virtual machine using FreeBSD 9.0 as OS. I just created a new virtual machine with a 50GB hard disk to have many months of historical data.. also we can have years of information for reference and behavior. I just installed FreeBSD with the default options and making sure to set up the correct time-zone and assigned an IP address. After reboot,  logged on to the JFF box and verify network connection.

First step in every new OS installation are patches. I used the following command to patch the new FreeBSD installation:

jff# freebsd-update fetch


Once patches are downloaded, we need to install them:

jff# freebsd-update install


Once my OS is patched I need the newest FreeBSD ports collection using the built-in tool portsnap.

jff# portsnap fetch


Now its time to extract the downloaded ports file; go and grab a cup of coffee and work on your pending tasks, it could take a while.

jff# portsnap extract


Now we are ready to install applications. The first we need its our Apache web server. Any version newer that 2.2 works. We are going to install the newest Apache version from the ports collection. Again, go to lunch or finish your pending tasks and go back in 20 mins.

jff# cd /usr/ports/www/apache22
jff# make config
jff# make install clean BATCH=YES



It's time to test our web server. Add the following line to the /etc/rc.conf and start the web server.

jff# echo 'apache22_enable="YES"' >> /etc/rc.conf
jff# apachectl start


Browse to the JFF box IP address and you should receive the default page.







JFF use PHP languaje so we need to install it. 

jff# cd /usr/ports/lang/php5

Very important once in the  /usr/ports/lang/php5 directory, tell php to work with apache and then install it.

jff# make config













jff# make install clean BATCH=YES



JFF needs some PHP modules so let go ahead and install them. Select the GD, SNMP, SOCKETS and MYSQL modules from the 'make config' screen.

jff# cd /usr/ports/lang/php5-extensions/
jff# make config














jff# make install clean BATCH=YES


Modify the php.ini file after copiyng from the defaults

jff# cp /usr/local/etc/php.ini-production /usr/local/etc/php.ini

jff# vi /usr/local/etc/php.ini


    error_reporting  =  E_ALL & ~E_NOTICE
    allow_url_fopen = On
    short_open_tag = On
    date.timezone = "America/Mexico_City"

Save the php.ini file after setting the previous values.


JFF uses MySQL for store of all configuration and data grabbed from devices. So lets proceed the installation.

jff# cd /usr/ports/databases/mysql55-server/
jff# make install clean BATCH=YES


Now that MySQL is installed we need to initialize the grant tables

jff# mysql_install_db --user=mysql


We will start MySQL for the first time

jff# mysqld_safe --user=mysql &


Modify the /etc/rc.conf file to start MySQL at boot and start MySQL as daemon.

jff# echo 'mysql_enable="YES"' >> /etc/rc.conf
jff# /usr/local/etc/rc.d/mysql-server start


Lets change the mysql root account password

jff# mysql
mysql> UPDATE mysql.user SET Password = PASSWORD('newpwd') WHERE User = 'root';

mysql> FLUSH PRIVILEGES;
mysql> exit;


There are another pre-requisites that we need to install, they are nmap, rrdtool, fping, diffutils.

jff# cd /usr/ports/security/nmap && make install clean BATCH=YES

jff# cd /usr/ports/databases/rrdtool && make install clean BATCH=YES


jff# cd /usr/ports/net/fping  && make install clean BATCH=YES

jff# cd /usr/ports/textproc/diffutils  && make install clean BATCH=YES

jff# cd /usr/ports/graphics/graphviz  && make install clean BATCH=YES



After all the packages are installed, we will need to create the groups and users used by JFF.

jff# pw groupadd jffnms

jff# pw useradd jffnms -c 'JFFNMS User' -d /usr/local/etc/jffnms -s /nologin -g jffnms

jff# pw groupmod jffnms -m www


Its time to download the JFF software, unpack it and assign the required permissions. Download the package from http://sourceforge.net/projects/jffnms/files/ and store it in the /usr/local/etc directory.

jff# cd /usr/local/etc

jff# tar xvzf jffnms-0.9.3.tgz


jff# chown -R jffnms:jffnms /usr/local/etc/jffnms-0.9.3

jff# chmod 770 /usr/local/etc/jffnms-0.9.3


jff# chmod -R ug+rw /usr/local/etc/jffnms-0.9.3

jff# ln -s /usr/local/etc/jffnms-0.9.3 /usr/local/etc/jffnms


Import the crontab file to schedule the pollers and modify the crontab file to match the values of our installation.

jff# crontab -u jffnms /usr/local/etc/jffnms/docs/unix/crontab

jff# crontab -e -u jffnms














 The next its to change the permissions of some folders and files.


jff# chmod +s /usr/local/bin/nmap

jff# chmod a+x /usr/local/bin/nmap


jff# chmod +s /usr/local/sbin/fping

jff# chmod a+x /usr/local/sbin/fping


We are almost done.. Lets create and configure our MySQL database.


jff# mysql -u root -p

mysql> CREATE DATABASE jffnms;

mysql> GRANT ALL PRIVILEGES ON jffnms.* TO jffnms@localhost IDENTIFIED BY 'jffnms';

mysql> FLUSH PRIVILEGES;

mysql> quit

jff# mysql -u jffnms -pjffnms jffnms < /usr/local/etc/jffnms/docs/install/jffnms-0.9.3.mysql

We have created the JFF tables and required records.


Next step its to setup apache for the JFF management web page. I preffer to set the jffnms directory as the Root Document  because in this case its a dedicated box. If the Apache web server will host another virtual directories or virtual servers, set it up accordingly.

jff# vi /usr/local/etc/apache22/httpd.conf


Add/modify the following values: 

SetHandler application/x-httpd-php
SetHandler application/x-httpd-php-source

RewriteEngine On
RewriteRule (.*\.php)s$ $1 [H=application/x-httpd-php-source]

ServerAdmin admin@domain.local
ServerName jff.domain.local:80


#DocumentRoot "/usr/local/www/apache22/data"
DocumentRoot "/usr/local/etc/jffnms/htdocs"

AllowOverride None
Order deny,allow
Allow from all

DirectoryIndex index.php index.html


Options Indexes FollowSymLinks Multiviews
AllowOverride All
Order allow,deny
Allow from all


Restart Apache web server

jff# apachectl restart


We are almost done..point your browser to the IP Address of your JFF Box  and will redirect you to the Setup page






























Replace the correct values on the ERROR fields and save the configuration

WE ARE DONE!!!  Go to the main screen and browse a little to be familiar with the tool. Next step its to add the network devices and servers. You will need to know the read_only snmo community and allow to read snmp information.





In another article I will show you how to add hosts and obtain graphics like the following




See you in another post..