How to Set Up FTP Server with IIS on Windows Server 2022
IIS on Windows Server 2022 includes a fully featured FTP server that supports both plain FTP and FTP over TLS (FTPS). The IIS FTP server integrates with Windows authentication, IIS authorization rules, and the WebAdministration PowerShell module, making it straightforward to manage via either the GUI or scripts. This guide walks through installation, site creation, authentication, TLS configuration, passive mode firewall rules, user isolation, logging, and PowerShell management.
Installing the FTP Server Feature
The FTP Server feature is part of the Web Server (IIS) role but is not installed by default. Install it with PowerShell:
Install-WindowsFeature -Name Web-Ftp-Server -IncludeAllSubFeature -IncludeManagementTools
This installs both the FTP Service (Web-Ftp-Service) and FTP Extensibility (Web-Ftp-Ext), which allows you to use custom FTP authentication and authorization providers. Verify with:
Get-WindowsFeature Web-Ftp-Server, Web-Ftp-Service, Web-Ftp-Ext
Creating an FTP Site in IIS
First, create the directory that will serve as the FTP root. A common practice is to place it under C:inetpub:
New-Item -Path "C:inetpubftproot" -ItemType Directory
In IIS Manager, right-click Sites and choose Add FTP Site. Provide a name, physical path, binding, and authentication settings. Alternatively, use PowerShell:
Import-Module WebAdministration
New-WebFtpSite -Name "MyFTPSite" -Port 21 -PhysicalPath "C:inetpubftproot"
This creates the FTP site with a binding on all IP addresses, port 21, with no hostname. Check the site was created:
Get-WebSite -Name "MyFTPSite"
FTP Site Bindings
An FTP binding specifies the IP address, port, and optional hostname the FTP site listens on. Port 21 is the standard control port. You can bind FTP to a specific IP address if the server has multiple network interfaces and you want to separate FTP traffic:
New-WebBinding -Name "MyFTPSite" -Protocol "ftp" -Port 21 -IPAddress "192.168.1.10"
For FTPS (FTP over TLS), the binding uses the same port 21 but the SSL policy is configured separately. FTPS on port 990 (implicit TLS) is also supported and configured by adding a binding on port 990 with SSL required.
Ensure Windows Firewall allows port 21:
New-NetFirewallRule -DisplayName "FTP Control (21)" -Direction Inbound -Protocol TCP -LocalPort 21 -Action Allow
FTP Authentication: Anonymous vs Basic
IIS FTP supports Anonymous Authentication and Basic Authentication. Anonymous authentication allows anyone to connect using the username anonymous (or ftp) with no real password — typically just an email address by convention. Basic authentication requires a valid local Windows user account or domain account.
Configure authentication via PowerShell:
# Enable Basic Authentication
Set-WebConfigurationProperty -Filter "system.ftpServer/security/authentication/basicAuthentication" `
-PSPath "IIS:SitesMyFTPSite" -Name "enabled" -Value $true
# Disable Anonymous Authentication (force real credentials)
Set-WebConfigurationProperty -Filter "system.ftpServer/security/authentication/anonymousAuthentication" `
-PSPath "IIS:SitesMyFTPSite" -Name "enabled" -Value $false
Create a local Windows user account for FTP access:
New-LocalUser -Name "ftpuser1" -Password (ConvertTo-SecureString "Str0ngP@ssword!" -AsPlainText -Force) `
-FullName "FTP User One" -PasswordNeverExpires $true -UserMayNotChangePassword $false
FTP Authorization Rules
Authentication tells IIS who the user is. Authorization rules determine what they can do. FTP authorization rules control read and write access for specific users, roles, or all users.
Add a rule that grants ftpuser1 read and write access:
Add-WebConfiguration -Filter "system.ftpServer/security/authorization" `
-PSPath "IIS:SitesMyFTPSite" `
-Value @{accessType="Allow"; users="ftpuser1"; permissions="Read, Write"}
Grant all authenticated users read access only:
Add-WebConfiguration -Filter "system.ftpServer/security/authorization" `
-PSPath "IIS:SitesMyFTPSite" `
-Value @{accessType="Allow"; users="?"; permissions="Read"}
The ? character means all authenticated users. The * character means all users including anonymous. These rules work in conjunction with NTFS permissions — both must allow access for the operation to succeed.
Set NTFS permissions on the FTP root for the user:
icacls "C:inetpubftproot" /grant "ftpuser1:(OI)(CI)M"
Configuring FTPS (FTP over TLS)
FTPS encrypts both the control connection and data transfers using TLS. IIS supports both Explicit FTPS (where the client issues an AUTH TLS command after connecting on port 21) and Implicit FTPS (where TLS is negotiated immediately on port 990).
First, you need an SSL certificate. Create a self-signed certificate for testing:
$cert = New-SelfSignedCertificate -DnsName "ftp.example.com" `
-CertStoreLocation "Cert:LocalMachineMy" `
-FriendlyName "FTP TLS Certificate"
$thumbprint = $cert.Thumbprint
Write-Host "Certificate Thumbprint: $thumbprint"
For production, use a certificate from a trusted CA. Import it with:
Import-PfxCertificate -FilePath "C:certsftp-cert.pfx" `
-CertStoreLocation "Cert:LocalMachineMy" `
-Password (ConvertTo-SecureString "CertPassword" -AsPlainText -Force)
Apply the certificate to the FTP site and configure SSL policy:
# Set the certificate thumbprint on the FTP site
Set-WebConfigurationProperty -Filter "system.ftpServer/security/ssl" `
-PSPath "IIS:SitesMyFTPSite" `
-Name "serverCertHash" -Value $thumbprint
# Require SSL for control and data connections
Set-WebConfigurationProperty -Filter "system.ftpServer/security/ssl" `
-PSPath "IIS:SitesMyFTPSite" `
-Name "controlChannelPolicy" -Value "SslRequire"
Set-WebConfigurationProperty -Filter "system.ftpServer/security/ssl" `
-PSPath "IIS:SitesMyFTPSite" `
-Name "dataChannelPolicy" -Value "SslRequire"
To allow SSL but not require it (for compatibility with legacy clients that cannot use TLS):
Set-WebConfigurationProperty -Filter "system.ftpServer/security/ssl" `
-PSPath "IIS:SitesMyFTPSite" `
-Name "controlChannelPolicy" -Value "SslAllow"
Passive FTP Port Range and Firewall Rules
FTP has two data transfer modes: active mode and passive mode. In passive mode (PASV), the server opens a data port and the client connects to it. Firewalls typically block active mode data connections because they originate from the server, so passive mode is almost always used with modern FTP clients.
IIS FTP lets you define the port range for passive data connections. Choose a range like 60000-60100 for passive mode:
Set-WebConfigurationProperty -Filter "system.ftpServer/firewallSupport" `
-PSPath "IIS:" `
-Name "lowDataChannelPort" -Value 60000
Set-WebConfigurationProperty -Filter "system.ftpServer/firewallSupport" `
-PSPath "IIS:" `
-Name "highDataChannelPort" -Value 60100
If the IIS FTP server is behind a NAT, you must also configure the external IP address that the server will return in PASV responses. Otherwise, clients will try to connect to the server’s internal IP, which is not routable from outside:
Set-WebConfigurationProperty -Filter "system.ftpServer/firewallSupport" `
-PSPath "IIS:" `
-Name "externalIp4Address" -Value "203.0.113.10"
Open the passive port range in Windows Firewall:
New-NetFirewallRule -DisplayName "FTP Passive Data (60000-60100)" `
-Direction Inbound -Protocol TCP -LocalPort 60000-60100 -Action Allow
FTP User Isolation
User isolation is a security feature that confines each FTP user to their own home directory, preventing them from navigating to other users’ files. IIS FTP supports three isolation modes.
In FTP Root Directory isolation, all users are locked to the FTP site root and cannot navigate above it. In FTP Home Directory isolation, each user is placed in a home directory named after their username under the FTP root. In Active Directory isolation, home directories are configured in Active Directory user properties.
Configure FTP Home Directory isolation via PowerShell:
Set-WebConfigurationProperty -Filter "system.ftpServer/userIsolation" `
-PSPath "IIS:SitesMyFTPSite" `
-Name "mode" -Value "IsolateRootDirectoryOnly"
Create per-user directories under the FTP root. For Basic Authentication users, IIS FTP looks for a directory at LocalUser:
New-Item -Path "C:inetpubftprootLocalUserftpuser1" -ItemType Directory
icacls "C:inetpubftprootLocalUserftpuser1" /grant "ftpuser1:(OI)(CI)M"
When ftpuser1 logs in, they will be placed directly in their isolated directory and cannot navigate to other users’ folders.
FTP Logging
IIS FTP logs all control channel activity including login attempts, commands issued, responses, and data transfer details. Logs are stored in C:inetpublogsLogFiles by default and use the W3C format.
Change the FTP log directory:
Set-WebConfigurationProperty -Filter "system.applicationHost/sites/site[@name='MyFTPSite']/ftpServer/logFile" `
-Name "directory" -Value "D:FTPLogs"
Enable additional logging fields, such as logging the full command sequence:
Set-WebConfigurationProperty -Filter "system.applicationHost/sites/site[@name='MyFTPSite']/ftpServer/logFile" `
-Name "logExtFileFlags" -Value "Date,Time,ClientIP,UserName,ServerIP,Method,UriStem,FtpStatus,Win32Status,BytesSent,BytesRecv,TimeTaken"
Managing FTP with the WebAdministration PowerShell Module
The WebAdministration module provides a PSDrive at IIS: that lets you manage FTP sites as file system objects. List all FTP sites:
Import-Module WebAdministration
Get-WebSite | Where-Object { $_.Bindings.Collection.protocol -eq "ftp" }
Start, stop, and restart an FTP site:
Stop-WebSite -Name "MyFTPSite"
Start-WebSite -Name "MyFTPSite"
Get the physical path of an FTP site:
(Get-WebSite -Name "MyFTPSite").PhysicalPath
List all authorization rules for a site:
Get-WebConfiguration -Filter "system.ftpServer/security/authorization" -PSPath "IIS:SitesMyFTPSite"
Remove an authorization rule by index:
Remove-WebConfigurationProperty -Filter "system.ftpServer/security/authorization" `
-PSPath "IIS:SitesMyFTPSite" -Name "." -AtIndex 0
Test the FTP connection from the server itself using the Windows FTP client (ftp.exe) for a quick sanity check:
ftp localhost
Or use curl to test FTPS from a remote machine:
curl --ftp-ssl ftp://ftpuser1:[email protected]/ --insecure
Setting up IIS FTP on Windows Server 2022 gives you a fully integrated, manageable FTP service that leverages existing Windows user accounts, NTFS permissions, and IIS infrastructure. Enabling FTPS with TLS, configuring passive mode port ranges for firewall compatibility, and enforcing user isolation are the three most important steps for a secure and functional production FTP server.