October 12, 2025 ITHU

Secure PHP on IIS: Install Under “Program Files” the Right Way

Running PHP on IIS can be fast, stable, and secure—if it’s installed with the same discipline as any other Windows Server component. This post walks through a structured installation that places PHP under Program Files instead of the default C:\inetpub path or C:\php directory, giving you stricter NTFS permissions, a cleaner separation between runtime and site content, and a stronger baseline for production.

What Is PHP and Why Use It on Internal Servers?

PHP (Hypertext Preprocessor) is one of the most widely used server-side scripting languages for building dynamic web applications. It powers everything from lightweight dashboards to full-featured platforms like WordPress, Joomla, and Drupal.

  • In a corporate environment, PHP often supports internal tools, such as:
  • Intranet portals and employee dashboards
  • Ticketing and helpdesk systems
  • Knowledge bases or documentation sites
  • Self-hosted WordPress instances for internal communications or departments

Running PHP on internal IIS servers allows organizations to host these apps securely within the Windows ecosystem—integrating easily with Active Directory, Windows authentication, and centralized logging—while maintaining control over updates, access, and data privacy.

Installing PHP

At the time of writing, the latest version of PHP was 8.4.13.
To begin, visit the official Windows PHP download page:
👉 https://windows.php.net/download/

Download the Non-Thread Safe (NTS) ZIP package for your architecture — in most cases, x64 for modern Windows Server installations.

Why Non-Thread Safe?
The Non-Thread Safe build is the recommended option for IIS because it’s designed for use with FastCGI. IIS manages PHP processes safely and efficiently through FastCGI, so the extra thread-safety checks in the Thread Safe build are unnecessary and can reduce performance.

When selecting the PHP package, check the “VS” version number in the filename (for example, VS17 or VS16).
This indicates which Visual C++ Redistributable for Visual Studio you’ll need to install. You can find the matching redistributable linked in the left-hand panel of the same download page.

For example, since we’re installing on Windows Server 2025 x64, you’ll also need to download and install the x64 Visual C++ Redistributable that matches your PHP build before proceeding.

Copy both the VC_redist.x64.exe installer and the extracted php-8.4.13-nts-Win32-vs17-x64 folder to the server’s desktop. Then, run the Visual C++ Redistributable installer on the server to ensure the required runtime components are in place before configuring PHP.

Prepping the PHP Folder

Before moving PHP into Program Files, take a moment to prepare the directory.

First, rename the extracted folder from its versioned name to simply php — for example:

php-8.4.13-nts-Win32-vs17-x64 → php

This keeps the path clean and makes future upgrades easier.

Next, open the renamed php folder and create a new subfolder called logs.
This folder will store PHP’s error logs separately from IIS logs, helping keep runtime data organized.

and rename the file php.ini-development to php.ini


Editing the php.ini File

Next, we need to configure the php.ini file — this controls how PHP behaves on the server, including performance, error handling, and security settings.
It’s critical to review and adjust these options carefully, as misconfigured values can unintentionally introduce vulnerabilities or expose sensitive system details.

In this step, we’ll apply secure defaults for an internal IIS installation — locking down file access, tightening session handling, and limiting what PHP can execute or upload. These changes help ensure that even if a web application is compromised, PHP itself remains protected and isolated from the rest of the system.

As you edit the file, you’ll notice many lines begin with a semicolon (;).
These are comments — they’re ignored by PHP but serve as notes or examples.
To activate a setting, simply uncomment it by removing the leading ;.
For example:

;extension=mysqli ; commented out (disabled)
extension=mysqli ; uncommented (enabled)

php.ini settings

; ============================================
; PHP.INI - Secure Baseline for IIS (Internal)
; ============================================

; ---- Extensions ----
extension=curl
extension=fileinfo
extension=gd
extension=mbstring
extension=mysqli
extension=openssl
extension=ldap ; required for internal domain authentication

; ---- Timezone ----
date.timezone = "Australia/Melbourne"

; ---- CGI / FastCGI Settings ----
cgi.force_redirect = 0
cgi.fix_pathinfo = 0

; ---- Hide Version Information ----
expose_php = Off

; ---- Error Handling ----
log_errors = On
display_errors = Off
error_reporting = E_ALL & ~E_DEPRECATED & ~E_STRICT
error_log = "C:\\Program Files\\php\\logs\\php_errors.log"

; ---- File Uploads ----
file_uploads = On
upload_tmp_dir = "C:\\ProgramData\\php\\temp"
upload_max_filesize = 20M
post_max_size = 25M
max_file_uploads = 10

; ---- Execution & Memory ----
max_execution_time = 60
max_input_time = 90
memory_limit = 256M

; ---- Session Security ----
session.save_path = "C:\\ProgramData\\php\\sessions"
session.cookie_httponly = On
session.cookie_secure = On
session.use_strict_mode = 1
session.gc_maxlifetime = 1440
session.use_only_cookies = 1

; ---- File & URL Handling ----
allow_url_fopen = Off
allow_url_include = Off

; ---- Paths ----
extension_dir = "C:\\Program Files\\php\\ext"

; ---- Logging & Diagnostics ----
; keep logs separate from IIS logs for easier troubleshooting
html_errors = Off
ignore_repeated_errors = On
ignore_repeated_source = On

; ---- Security: Disable Dangerous Functions ----
disable_functions = exec,passthru,shell_exec,system,proc_open,popen,show_source

; ---- Miscellaneous ----
short_open_tag = Off
enable_dl = Off

; ---- Recommended Limits ----
max_input_vars = 1000
default_socket_timeout = 60

; ---- Default Character Set ----
default_charset = "UTF-8"

; ---- Upload / Temp Directory Permissions ----
; C:\ProgramData\php\temp and C:\ProgramData\php\sessions
; must have Modify rights for IIS_IUSRS or the site’s AppPool identity.

; ---- End of File ----

Moving PHP to Program Files

Now that PHP is configured and ready, we can move it into its final, secure location.

  • Copy or move the entire php folder into C:\Program Files\.
  • You’ll need local administrator rights to complete this step.

Once the folder is in place, we’ll apply the correct permissions to ensure IIS can run PHP and access essential subfolders like logs, while still keeping the directory protected from modification.

PowerShell CMD

# --- Secure PHP Runtime Directory ---
# Removes inherited permissions and applies secure ACLs for Program Files\php

icacls "C:\Program Files\php" /inheritance:r
icacls "C:\Program Files\php" /grant:r `
"SYSTEM:(OI)(CI)F" `
"Administrators:(OI)(CI)F" `
"IIS_IUSRS:(OI)(CI)RX"

What this does:

  • /inheritance:r removes inherited permissions from Program Files

Grants:

  • SYSTEM → Full Control
  • Administrators → Full Control
  • IIS_IUSRS → Read & Execute only

This ensures IIS can run PHP but not modify its files or configuration.

🔍 Verify PHP Folder Permissions with PowerShell

Run this command:

icacls "C:\Program Files\php"

You should see output similar to:

C:\Program Files\php SYSTEM:(OI)(CI)(F)
Administrators:(OI)(CI)(F)
IIS_IUSRS:(OI)(CI)(RX)

🛠️ Creating PHP Data Folders and Applying Secure Permissions

The easiest and most reliable way to create the required PHP data folders — and apply the correct permissions — is with PowerShell.
These folders store temporary and session data generated by PHP, so they must exist outside Program Files (which is read-only) and have the proper Modify access for IIS.

Running the following commands will automatically create the folders under C:\ProgramData\php\ and apply secure, least-privilege permissions so PHP can write to them safely without compromising the system.

PowerShell CMD

# --- Create PHP Data Folders ---
mkdir "C:\ProgramData\php" -Force
mkdir "C:\ProgramData\php\temp" -Force
mkdir "C:\ProgramData\php\sessions" -Force

# --- Apply Secure NTFS Permissions ---
# Remove inherited permissions and apply minimal required rights
icacls "C:\ProgramData\php" /inheritance:r
icacls "C:\ProgramData\php" /grant:r `
"SYSTEM:(OI)(CI)F" `
"Administrators:(OI)(CI)F" `
"IIS_IUSRS:(OI)(CI)M"

🔍 What This Does

Creates the temp and sessions folders used by PHP.

Removes inherited permissions from ProgramData to avoid unintended access.

Grants:

  • SYSTEM → Full Control
  • Administrators → Full Control
  • IIS_IUSRS → Modify (allows PHP to write and delete temporary files, but not change ACLs or binaries)

This ensures PHP has only the access it needs — nothing more — while keeping the system secure and compliant with Windows best practices.

Preparing IIS to run PHP

Prerequisites:
Building a Secure IIS Baseline: Preparing for PHP, .NET, and Beyond in an Active Directory Environment

Open Server Manager

Click Manage → Add Roles and Features.

Click through to the “Server Roles” section.

Expand: “Web Server (IIS) → Web Server → Application Development“.

Tick the following options:

  • ✅ CGI (required for FastCGI and PHP)
  • ✅ ISAPI Extensions
  • ✅ ISAPI Filters

Click “Next” to the end of the wizard to finish the installation.

⚙️ Configuring IIS for PHP

Open IIS Manager, select your server name from the left-hand Connections panel, and then open Handler Mappings. This is where we’ll link PHP files to the FastCGI handler, allowing IIS to correctly process .php requests.

In the Actions panel on the right, click “Add Module Mapping“.

Fill in the fields as follows:

  • Request path: *.php
  • Module: FastCgiModule
  • Executable (optional): “C:\Program Files\php\php-cgi.exe”
  • Name: PHP

Click “Request Restrictions“.

  • Under Mapping, make sure File is selected.
  • Under Verbs, leave it as All verbs.
  • Under Access, choose Script.
  • Click OK.

Click OK again to save the module mapping.

When prompted to allow the FastCGI executable, click Yes.

This completes the core IIS-to-PHP integration.

🧩 Create a PHP Info Test Page

Navigate to your IIS default web root: C:\inetpub\wwwroot

Create a new file called: phpinfo.php

Open it in Notepad and paste this:

<?php
phpinfo();
?>

Save the file, then open a browser on the server and visit: “http://localhost/phpinfo.php” you will now see that php is now working.

Summary

This setup establishes a secure and stable PHP environment on IIS by installing PHP under C:\Program Files\php with protected NTFS permissions and placing writable data in C:\ProgramData\php. The configuration uses FastCGI for efficient, isolated execution and applies hardened php.ini settings to reduce attack surface—disabling risky functions, hiding version details, and enforcing strict session and upload handling. IIS is configured with a dedicated handler mapping for .php files, ensuring all PHP requests are processed safely. The result is a clean, maintainable, and security-focused foundation ready for internal applications within an Active Directory environment.