How to Set Up an FTP Server on Windows Server 2012 R2
The File Transfer Protocol (FTP) has been a cornerstone of file exchange for decades. While modern alternatives like SFTP and HTTPS uploads exist, FTP remains common in many environments — particularly for web content deployment, legacy application integration, and transfer to network appliances. IIS 8.5 on Windows Server 2012 R2 includes a full-featured FTP service that supports user isolation, virtual directories, SSL/TLS encryption (FTPS), logging, and fine-grained access control through both local accounts and Active Directory.
This guide covers installing the FTP service, creating FTP sites with user isolation, configuring FTPS for encrypted transfers, setting up anonymous and authenticated access, and hardening the FTP service for production use.
Prerequisites
- IIS 8.5 already installed (see the IIS guide). The FTP service is a separate component.
- Static IP address on the server.
- TCP port 21 (control) and a passive port range open in Windows Firewall.
- An SSL certificate if you intend to enable FTPS.
- AD users or local users created for FTP authentication.
Step 1: Install the FTP Server Feature
# Install FTP service and management tools
Install-WindowsFeature -Name Web-Ftp-Server, Web-Ftp-Service, Web-Ftp-Extensibility -IncludeManagementTools
# Confirm the Microsoft FTP Service is installed
Get-WindowsFeature -Name Web-Ftp* | Select-Object Name, InstallState
# Check the FTP service state
Get-Service -Name ftpsvc | Select-Object Name, Status, StartType
# Start and set to automatic if not already
Set-Service -Name ftpsvc -StartupType Automatic
Start-Service -Name ftpsvc
Step 2: Create the FTP Site Directory Structure
For user isolation, each FTP user needs their own directory under the FTP root in the format LocalUserusername. This prevents users from browsing other users’ files.
# Create the FTP root directory
New-Item -Path "D:FTPRoot" -ItemType Directory
# Create subdirectories for user isolation
New-Item -Path "D:FTPRootLocalUserjsmith" -ItemType Directory
New-Item -Path "D:FTPRootLocalUserbwilliams" -ItemType Directory
# Create a directory for anonymous access (public)
New-Item -Path "D:FTPRootLocalUserPublic" -ItemType Directory
# Set NTFS permissions on each user's folder
$acl = Get-Acl "D:FTPRootLocalUserjsmith"
$rule = New-Object System.Security.AccessControl.FileSystemAccessRule(
"CORPjsmith","Modify","ContainerInherit,ObjectInherit","None","Allow")
$acl.SetAccessRule($rule)
Set-Acl "D:FTPRootLocalUserjsmith" $acl
Step 3: Create the FTP Site
# Import the WebAdministration module
Import-Module WebAdministration
# Create the FTP site on port 21, binding to all IPs
New-WebFtpSite `
-Name "Corporate FTP" `
-Port 21 `
-PhysicalPath "D:FTPRoot"
# Alternatively, create from scratch using IIS config paths:
New-Item "IIS:SitesCorporate FTP" -Bindings @{
protocol="ftp"
bindingInformation="*:21:"
} -PhysicalPath "D:FTPRoot"
# Start the FTP site
Start-WebItem -PSPath "IIS:SitesCorporate FTP"
# Verify
Get-Website | Where-Object { $_.serverAutoStart -eq $true } |
Select-Object Name, State, Bindings
Step 4: Configure User Isolation
User isolation confines each authenticated user to their own directory and prevents them from navigating upward to see other users’ folders.
# Enable user isolation on the FTP site
Set-ItemProperty "IIS:SitesCorporate FTP" -Name ftpServer.userIsolation.mode -Value 3
# Mode values:
# 0 = No isolation (all users share root)
# 1 = Isolate users (users confined to home dirs, no AD lookups)
# 2 = Isolate users using Active Directory
# 3 = User name directory (uses LocalUserusername structure)
# Configure FTP authentication — enable basic authentication
Set-ItemProperty "IIS:SitesCorporate FTP" `
-Name ftpServer.security.authentication.basicAuthentication.enabled -Value $true
# Disable anonymous authentication
Set-ItemProperty "IIS:SitesCorporate FTP" `
-Name ftpServer.security.authentication.anonymousAuthentication.enabled -Value $false
# Set authorisation rules: allow authenticated users read/write
Add-WebConfiguration -Filter "system.ftpServer/security/authorization" `
-PSPath "IIS:SitesCorporate FTP" `
-Value @{
accessType="Allow"
users="*"
roles=""
permissions="Read,Write"
}
Step 5: Configure FTPS (FTP over SSL/TLS)
Plain FTP transmits credentials in cleartext. Always enable SSL/TLS (FTPS) in production environments where any sensitive data is transferred.
# Create a self-signed certificate for FTP (or use an existing one)
$cert = New-SelfSignedCertificate `
-DnsName "ftp.corp.example.com" `
-CertStoreLocation "cert:LocalMachineMy" `
-KeyLength 2048
$certThumb = $cert.Thumbprint
# Enable SSL on the FTP site and require it for data channel
Set-ItemProperty "IIS:SitesCorporate FTP" `
-Name ftpServer.security.ssl.controlChannelPolicy -Value 1
# 0=Allow SSL, 1=Require SSL
Set-ItemProperty "IIS:SitesCorporate FTP" `
-Name ftpServer.security.ssl.dataChannelPolicy -Value 1
# Assign the certificate to the FTP site
Set-ItemProperty "IIS:SitesCorporate FTP" `
-Name ftpServer.security.ssl.serverCertHash -Value $certThumb
Set-ItemProperty "IIS:SitesCorporate FTP" `
-Name ftpServer.security.ssl.serverCertStoreName -Value "MY"
Step 6: Configure Passive Mode and Firewall Rules
Passive mode FTP is required when clients are behind NAT. You must define a passive port range and open those ports in the firewall.
# Set the passive port range (5000-5100)
Set-ItemProperty "IIS:SitesCorporate FTP" `
-Name ftpServer.firewallSupport.pasvMaxPort -Value 5100
Set-ItemProperty "IIS:SitesCorporate FTP" `
-Name ftpServer.firewallSupport.pasvMinPort -Value 5000
# Set the external IP address for PASV mode (your public or NAT IP)
Set-ItemProperty "IIS:SitesCorporate FTP" `
-Name ftpServer.firewallSupport.externalIp4Address -Value "203.0.113.50"
# Open the FTP control port and passive range in Windows Firewall
New-NetFirewallRule -DisplayName "FTP Control (21)" `
-Direction Inbound -Protocol TCP -LocalPort 21 -Action Allow
New-NetFirewallRule -DisplayName "FTP Passive Range" `
-Direction Inbound -Protocol TCP -LocalPort "5000-5100" -Action Allow
# Restart FTP service after changes
Restart-Service -Name ftpsvc
Step 7: Enable FTP Logging and Monitoring
# Configure FTP logging
Set-ItemProperty "IIS:SitesCorporate FTP" `
-Name ftpServer.logFile.directory -Value "D:LogsFTP"
Set-ItemProperty "IIS:SitesCorporate FTP" `
-Name ftpServer.logFile.logExtFileFlags -Value 131023
# View FTP log entries
Get-Content "D:LogsFTPMSFTPSVC1*.log" -Tail 30
# List active FTP sessions (requires FTP Management console)
# Via IIS Manager: FTP Sites -> Current Sessions
# Monitor FTP connections via netstat
netstat -ano | findstr :21
Summary
Setting up FTP on Windows Server 2012 R2 using the IIS FTP service gives you a fully integrated, manageable FTP platform. The critical configuration steps are: install the FTP role services, create the correct directory structure for user isolation, enable basic authentication and disable anonymous access (unless a public share is required), configure FTPS with SSL/TLS to protect credentials and data in transit, set up a passive port range and corresponding firewall rules, and direct logs to a dedicated volume. Never deploy plain FTP (without SSL) on any server accessible from the internet or from untrusted networks, as usernames and passwords are transmitted in cleartext and can be intercepted trivially.