> For the complete documentation index, see [llms.txt](https://docs.plenit.com/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.plenit.com/docs-en/support/tutorials/windows/how-to-set-up-an-ftp-server-with-powershell.md).

# How to install and configure an FTP server in Windows using PowerShell

If you want to know **how to install and configure an FTP server in Windows using PowerShell** join us throughout this brief tutorial where we will do it in simple steps.

This tutorial complements the one we already did through the graphical interface and titled [How to install and configure an FTP server in Windows (IIS)](https://jotelulu.com/soporte/tutoriales/como-instalar-y-configurar-un-servidor-ftp-en-windows-iis/){target="\_blank" rel="noopener"}.

**NOTE:** *A hash sign (#) has been added in front of all the lines for security reasons, since if one of these lines is copied by mistake it will not be executed (the hash is used to comment code, so it becomes non-executable). To execute it, the "#" character must be removed from all the lines.*

### **How to install and configure an FTP server in Windows using PowerShell?**

### **Prerequisites or pre-configuration.**

To successfully complete this tutorial and be able to **install and configure an FTP server in Windows using PowerShell** you will need:

* On the one hand, be registered on the Plenit Platform with an organization and be registered in it after doing [Log in](https://admin.jotelulu.com/){target="\_blank" rel="noopener"}.
* On the other hand, [having set up a Servers subscription](https://jotelulu.com/soporte/tutoriales/como-desplegar-servidor){target="\_blank" rel="noopener"}
* Have a running Windows server within the subscription.

&#x20;

#### **Step 1. Install and configure an FTP server in Windows using PowerShell**

The first thing we will do will be **install the FTP server feature**, for which you will need to open the **PowerShell console**, **or the PowerShell ISE**. As I have been saying lately, the most desirable option would be to use ISE (Microsoft's IDE, so to speak), since it allows us to do tests, see where it fails, etc.

Once in the PowerShell console (or ISE), you will need to **run the "Install-WindowsFeature" commands** (1).

*# Install-WindowsFeature Web-FTP-Server -IncludeAllSubFeature*

*# Install-WindowsFeature Web-Server -IncludeAllSubFeature -IncludeManagementTools*

*# Import-Module WebAdministration*

Where:

* The command **"Install-WindowsFeature" installs the** Windows feature we pass as a parameter.
* The switch **"-IncludeAllSubFeature" installs all the options** that the Windows feature has.
* The switch **"-IncludeManagementTools" installs the** **administrative tools** for that feature.

![Paso 1. Hacemos el despliegue del servicio de FTP mediante
PowerShell](https://jotelulu.com/wp-content/uploads/2023/09/Paso-1.-Hacemos-el-despliegue-del-servicio-de-FTP-mediante-PowerShell.jpg)\\

Step 1. We deploy the FTP service using PowerShell

Once this is done, **we continue the installation** by importing the FTP administration module using **the command** **"Import-Module"** (2).

![Paso 1. Importamos el módulo de administración del FTP mediante
PowerShell](https://jotelulu.com/wp-content/uploads/2023/09/Paso-1.-Importamos-el-modulo-de-administracion-del-FTP-mediante-PowerShell.jpg)\\

Step 1. We import the FTP administration module using PowerShell

Next, **the new FTP site is configured** to provide service.

This will have a series of features that must be configured, and you can directly run a command like the following:

\*# New-WebFtpSite -Name \ -Port\n-PhysicalPath \*

Where:

* The command **"New-WebFtpSite" deploys the new FTP site.** .
* **"-Name "** describes **the name** we will give to the FTP site.
* **"-Port "** is a number that indicates **which port the FTP listens on** .
* **"-PhysicalPath "** is the **server path** where the FTP data is stored.

This way, it could look like this:

*# New-WebFtpSite -Name 'FTP Site Nacho' -Port '21' -PhysicalPath 'C:\datos\ftproot'*

We could plug it in directly there and the configuration would be done, but this is a bit of a hack, so variables are usually used to improve reuse in the future.

To keep everything more organized, **we will create some variables**, as we mentioned, which will be the following:

* **"-Name "** describes the **name we will give to the site** of FTP, with the variable "$Name".
* **"-Port "** is a number that indicates which **port listens** the FTP, with the variable "$Port".
* **"-PhysicalPath "** is the server path **where the data** of the FTP are, with the variable "$Root".

Taking this into account, everything is configured and completed **by running the following commands** (3):

*# $Name = 'FTP Site Nacho'*

*# $Root = 'C:\datos\ftproot'*

*# $Port = 21*

*# New-WebFtpSite -Name $Name -Port $Port -PhysicalPath $Root*

![Paso 1. Configuramos el site de FTP para el
servicio](https://jotelulu.com/wp-content/uploads/2023/09/Paso-1.-Configuramos-el-site-de-FTP-para-el-servicio.jpg)\\

Step 1. We configure the FTP site for the service

At this point the FTP server itself has already been installed, and it will remain **to configure, add users, repositories, secure it**, etc.

At this point, for me, the first thing would be to create a user (and its associated group) in order to test that we can make the connection and not just a simple one. That way, if we later secure it by closing ports or configuring certificates, we will be sure that this part was working.

In this case, we first create a group for the users with the ability to connect to the FTP, since it is better to create a group that they can be added to later.

For **create the FTP group** (4) we use:

*# $FTPUserGroupName = «FTP Users»*

*# $ADSI = \[ADSI]»WinNT://$env:ComputerName»*

*# $FTPUserGroup = $ADSI.Create(«Group», «$FTPUserGroupName»)*

*# $FTPUserGroup.SetInfo()*

*# $FTPUserGroup.Description = «The members of this group can connect to the FTP»*

*# $FTPUserGroup.SetInfo()*

![Paso 1. Creamos el grupo de FTP para el
servicio](https://jotelulu.com/wp-content/uploads/2023/09/Paso-1.-Creamos-el-grupo-de-FTP-para-el-servicio.jpg)\\

Step 1. We create an FTP group for the service

In this case, we will make use of ADSI commands to deploy the group, always using certain variables to make the configuration easier.

The next thing would be **to create the user with which the FTP connections will be made** (5).

*# $FTPUserName = «ftpnacho»*

*# $FTPPassword = 'Contrasenya123!'*

*# $CreateUserFTPUser = $ADSI.Create(«User», «$FTPUserName»)*

*# $CreateUserFTPUser.SetInfo()*

*# $CreateUserFTPUser.SetPassword(«$FTPPassword»)*

*# $CreateUserFTPUser.SetInfo()*

![Paso 1. Creamos un usuario para las conexiones de
FTP](https://jotelulu.com/wp-content/uploads/2023/09/Paso-1.-Creamos-un-usuario-para-las-conexiones-de-FTP.jpg)\\

Step 1. We create a user for FTP connections

Once this is done, you must **add to the system FTP group** (6), executing for this:

*# $UserAccount = New-Object System.Security.Principal.NTAccount(«$FTPUserName»)*

*# $SID = $UserAccount.Translate(\[System.Security.Principal.SecurityIdentifier])*

*# $Group = \[ADSI]»WinNT://$env:ComputerName/$FTPUserGroupName,Group»*

*# $User = \[ADSI]»WinNT://$SID»*

*# $Group.Add($User.Path)*

![Paso 1. Añadimos el usuario de FTP al grupo de FTP del
sistema](https://jotelulu.com/wp-content/uploads/2023/09/Paso-1.-Anadimos-el-usuario-de-FTP-al-grupo-de-FTP-del-sistema.jpg)\\

Step 1. We add the FTP user to the system FTP group

At this point you must **enable basic authentication of the FTP site** and then **authorize the Windows group** (7) that contains the FTP user so that it can have access to the FTP site and therefore make use of the service.

To do this, execute the following commands:

*\[# $FTPSitePath]\[ = ]\[«IIS:\Sites\\]\[$FTPSiteName]\[«]*

*\[# $BasicAuth]\[ = ]\['ftpServer.security.authentication.basicAuthentication.enabled']*

*\[\[# ]Set-ItemProperty]\[ -Path ]\[$FTPSitePath]\[ -Name ]\[$BasicAuth]\[ -Value ]\[$True]*

*\[# $Param]\[ = @]\[{]*

*\[\[# ]Filter]\[ = ]\[«/system.ftpServer/security/authorization»]*

*\[ \[# ]Value = @]\[{]*

*\[ \[# ]accessType = ]\[«Allow»]*

*\[ \[# ]roles = ]\[«]\[$FTPUserGroupName]\[«]*

*\[ \[# ]permissions = ]\[1]*

*\[\[# ]}]*

*\[ \[# ]PSPath = 'IIS:\\']*

*\[ \[# ]Location = ]\[$FTPSiteName]*

*\[\[# ]}]*

*\[\[# ]Add-WebConfiguration]\[ @]\[param]*

![Paso 1. Configuramos la autenticación básica para nuestro sitio de
FTP](https://jotelulu.com/wp-content/uploads/2023/09/Paso-1.-Configuramos-la-autenticacion-basica-para-nuestro-sitio-de-FTP.jpg)\\

Step 1. We configure basic authentication for our FTP site

The next step is **change the SSL policy and file permissions (NTFS) in the folder** **FTP server root** (8), that is, where all files uploaded by service users are stored.

To do this, we execute the following commands:

*#* *$SSLPolicy = @(*

*#  'ftpServer.security.ssl.controlChannelPolicy',*

*#   'ftpServer.security.ssl.dataChannelPolicy'*

*# )*

*# Set-ItemProperty -Path $FTPSitePath -Name $SSLPolicy\[0] -Value $false*

*# Set-ItemProperty -Path $FTPSitePath -Name $SSLPolicy\[1] -Value $false*

![Paso 1. Cambiamos la política de SSL y los permisos de ficheros en la
carpeta raíz del servidor
FTP](https://jotelulu.com/wp-content/uploads/2023/09/Paso-1.-Cambiamos-la-politica-de-SSL-y-los-permisos-de-ficheros-en-la-carpeta-raiz-del-servidor-FTP.jpg)\\

Step 1. We change the SSL policy and file permissions in the root folder of the FTP server

The next step to take is to run the following commands to configure the NTFS permissions in the root folder and thus allow users belonging to the FTP group to access and work on this folder.

*# $UserAccount = New-Object System.Security.Principal.NTAccount(«$FTPUserGroupName»)*

*# $AccessRule = \[System.Security.AccessControl.FileSystemAccessRule]::new($UserAccount,*

*#     'ReadAndExecute',*

*#     'ContainerInherit,ObjectInherit',*

*#     'None',*

*#     'Allow'*

*# )*

*# $ACL = Get-Acl -Path $FTPRootDir*

*# $ACL.SetAccessRule($AccessRule)*

*# $ACL | Set-Acl -Path $FTPRootDir*

Finally, for all changes to take effect **the FTP instance must be restarted** (9), to do this you must run:

\# Restart-WebItem «IIS:\Sites\\$Name» -Verbose

![Paso 1. Reiniciamos el servicio de FTP desde consola de
PowerShell](https://jotelulu.com/wp-content/uploads/2023/09/Paso-1.-Reiniciamos-el-servicio-de-FTP-desde-consola-de-PowerShell.jpg)\\

Step 1. We restart the FTP service from the PowerShell console

With this, the FTP configuration process has been completed.

&#x20;

### **Conclusions and next steps:**

Throughout this tutorial we have seen how to carry out the \*\*installation and configuration of an FTP server in Windows using PowerShell\*\* within one of the Windows servers hosted in Plenit.

If what you have read so far has been interesting to you, you can delve deeper into some related services; the following tutorials may interest you:

* [How to deploy a new server in Plenit](https://jotelulu.com/soporte/tutoriales/como-desplegar-servidor){target="\_blank" rel="noopener"}.
* [How to create a site-to-site VPN tunnel in Plenit](https://jotelulu.com/soporte/tutoriales/crear-tunel-vpn-site-to-site){target="\_blank" rel="noopener"}.
* [How to create templates on a server to reuse them in Remote Desktop](https://jotelulu.com/soporte/tutoriales/crear-plantillas-servidor-para-reutilizarlas-escritorio-remoto){target="\_blank" rel="noopener"}.
* [How to create a VPC and associate a TIER in Plenit](https://jotelulu.com/soporte/tutoriales/como-crear-vpc-asociar-tier){target="\_blank" rel="noopener"}.

We hope that with this small guide you will have no problems configuring your FTP server quickly and functionally, but if you do, do not hesitate to contact us so we can give you a hand.

**Thank you for your trust.**


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## Querying This Documentation
If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter, and the optional `goal` query parameter:

```
GET https://docs.plenit.com/docs-en/support/tutorials/windows/how-to-set-up-an-ftp-server-with-powershell.md?ask=<question>&goal=<endgoal>
```

`ask` is the immediate question: it should be specific, self-contained, and written in natural language.
`goal` is optional and describes the broader end goal you are ultimately trying to accomplish on behalf of the user. GitBook uses it to tailor the answer towards what is most useful for that goal.

The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
