OTRS is an exceptionally flexible ITIL compliant ticketing/helpdesk solution, which runs beautifully on almost any LAMP (Linux, Apache, MySQL, Perl (yes, I know it’s PHP really;-)) server, but what happens when you work in a Windows-only environment? OTRS does have a Windows installer, but it is somewhat clunky and requires almost as much work to configure as manually installing. Installing as components allows you to upgrade portions of the system and have more granular control over the setup.
I’ve recently installed OTRS on a Windows Server 2008 R2 (64-bit) server, including experimenting with various combinations of IIS/Apache, MSSQL2008/MySQL, ActiveState Perl 32-bit/64-bit, different configurations and setups - these are my findings:
None of these combinations came close to the performance of OTRS running on a native Linux server, my 64-bit Ubuntu server absolutely flew, with less processor and RAM than the Windows box. In short, if you have the skills, use the Linux option. Yes, yes I do feel a little dirty now, sorry Mr Gates.
So, the final setup I have opted for is:
Make sure you don’t have IIS running (eye-roll), and then click through the wizard…
![]()
![]()
Configure the network and server details
![]()
![]()
Do a custom installation and ensure that you install it to D:\Apache\
![]()
![]()
![]()
![]()
![]()
Apache should now be running on the local machine, navigate to
Installing MySQL is again a very simple click-through process, once you’ve downloaded it from
![]()
![]()
![]()
![]()
![]()
![]()
Stop the MySQL service and edit c:\Program Files\MySQL\MySQL Server 5.5\my.ini in your favourite text editor– you will need to run it as an Administrator.
Change the default data directory (you wouldn’t leave a MSSQL DB on the System drive would you?!) – create a folder on the data drive (I use D:\MySQL\Data).
Go to c:\ProgramData\MySQL\MySQL 5.5\data\ and move all the files and folders there to the folder you specified for datadir.
For performance, it’s also recommended that you change the query_cache_size to “32M”
You can now start the MySQL service again.
You can download the 32-bit version of ActiveState Perl here:
Run through the installation, accepting the defaults apart from changing the location of the installation to D:\Perl:
![]()
![]()
![]()
At this point, we will download and extract the OTRS installation from
Once that’s done, we can begin joining up the dots.
Run a command prompt as administrator and navigate to the OTRS installation directory (for me, d:\OTRS).
![]()
You can then use the Perl Package Manager to install the missing required packages, and some of the options:
(this one requires that you point it to the correct Apache modules folder, for me d:\Apache\modules)
If you re-run the otrs.CheckModules.pl script it should now pass all modules.
The main Apache configuration file is installed at d:\Apache\conf\httpd.conf, open it in Notepad and add the following lines at the end of the config file:
Also modify the DirectoryIndex directive to be index.pl rather than index.pl.
Configuring OTRS is initially a case of changing paths referenced in the configuration files to the Windows paths that match your environments.
<td valign="top">
<strong>…to this</strong>
</td>
<td valign="top">
ScriptAlias /otrs/ "D:/otrs/bin/cgi-bin/"
</td>
<td valign="top">
Alias /otrs-web/ "D:/otrs/var/httpd/htdocs/"
</td>
<td valign="top">
Perlrequire D:/otrs/scripts/apache2-perl-startup.pl
</td>
<td valign="top">
<Directory "D:/otrs/bin/cgi-bin/">
</td>
<td valign="top">
<Directory "D:/otrs/var/httpd/htdocs/">
</td>
<td valign="top">
<Directory "D:/otrs/var/httpd/htdocs/skins/*/*/css-cache">
</td>
<td valign="top">
<Directory "D:/otrs/var/httpd/htdocs/js/js-cache">
</td>
I performed a search/replace for “/opt” with “D:”, and checked through after.
<td valign="top">
<strong>…to this</strong>
</td>
<td valign="top">
use lib "D:/otrs/";
</td>
<td valign="top">
use lib "D:/otrs/Kernel/cpan-lib";
</td>
<td valign="top">
use lib "D:/otrs/Custom";
</td>
Rename D:\OTRS\kernel\Config.pm.dist to Config.pm, and open Config.pm in your text editor.
<td valign="top">
<strong>…to this</strong>
</td>
<td valign="top">
$Self->{Home} = 'D:/otrs';
</td>
Add the following lines to configure logging:
Run
![]()
![]()
Enter the MySQL root user and password you created earlier, and test the settings
![]()
Next configure a user, password, database name and create the database. you don’t have to change the default names, but if you don’t change the password from the default “hot” to something complex, you deserve to get hacked!
![]()
Configure the general system, FQDN, admin email address and logging
![]()
Configure incoming and outbound email
![]()
And finish!
![]()
You can now log in to your OTRS installation – but we’re not finished yet!
![]()
The MSI installer uses Cron4Win, but in my experience it was barely working, clunky and not at all suitable for a production service. Since the jobs are just .pl scripts, it’s better to run them from the Scheduled Tasks.
Open up the Task Scheduler and run the Create Task action (not Create Basic Task). Name the task and configure the user you want to run under. Ensure that you select to run whether the user is logged in or not, and run with elevated privileges. I have used a specific account with locked down privileges.
![]()
Move on to the “Triggers” panel and create a schedule for the task (see the table below for my config)
![]()
Move to the “Actions” panel and create an action to start a program and pass the script as an argument (again, see the table below for my config).
![]()
You can accept the default settings for the rest of the panes.
<td valign="top" width="177">
<strong>Triggers</strong>
</td>
<td valign="top" width="380">
<strong>Program/Arguments</strong>
</td>
<td valign="top" width="177">
<span style="font-size: x-small;">At 00:00 Every day – After triggered, repeat every 00:01:00 indefinitely.</span>
</td>
<td valign="top" width="380">
<span style="font-size: x-small;">d:\Perl\bin\perl.exe d:\OTRS\bin\otrs.PostMaster.pl</span>
</td>
<td valign="top" width="177">
<span style="font-size: x-small;">At 00:00 Every day – After triggered, repeat every 10 minutes indefinitely.</span>
</td>
<td valign="top" width="380">
<span style="font-size: x-small;">d:\Perl\bin\perl.exe d:\OTRS\bin\otrs.GenericAgent.pl -c db</span>
</td>
<td valign="top" width="177">
<span style="font-size: x-small;">At 00:00 Every day – After triggered, repeat every 15 minutes indefinitely.</span>
</td>
<td valign="top" width="380">
<span style="font-size: x-small;">d:\Perl\bin\perl.exe d:\OTRS\bin\otrs.GenericAgent.pl </span>
</td>
<td valign="top" width="177">
<span style="font-size: x-small;">At 00:00 Every day – After triggered, repeat every 02:00:00 indefinitely.</span>
</td>
<td valign="top" width="380">
<span style="font-size: x-small;">d:\Perl\bin\perl.exe d:\OTRS\bin\otrs.PendingJobs.pl<br /> d:\Perl\bin\perl.exe d:\OTRS\bin\otrs.DeleteSessionIDs.pl -expired</span>
</td>
<td valign="top" width="177">
<span style="font-size: x-small;">At 00:05 every day</span>
</td>
<td valign="top" width="380">
<span style="font-size: x-small;">d:\Perl\bin\perl.exe d:\OTRS\bin\otrs.CleanUp.pl<br /> </span><span style="font-size: x-small;">d:\Perl\bin\perl.exe d:\OTRS\bin\otrs.RebuildTicketIndex.pl</span>
</td>
<td valign="top" width="177">
At 00:15 on 13/07/2011 – After triggered, repeat every 1 hour indefinitely.
</td>
<td valign="top" width="380">
<span style="font-size: x-small;">d:\Perl\bin\perl.exe d:\OTRS\bin\otrs.UnlockTickets.pl -timeout</span>
</td>
<td valign="top" width="177">
At 11:00 every Sunday of every week
</td>
<td valign="top" width="380">
<span style="font-size: x-small;">d:\Perl\bin\perl.exe d:/OTRS/bin/otrs.DeleteCache.pl<br /> </span><span style="font-size: x-small;">d:\Perl\bin\perl.exe d:/OTRS/bin/otrs.LoaderCache.pl -o delete</span>
</td>
Run each of the jobs manually to ensure that they process OK, without any errors. I have exported my jobs as XML files, which are available here to download and import (assuming you’ve put all the files in the same place as me!)
![]()
That’s it, OTRS is ready for you to configure, which is way beyond the scope of this post!