2
0
Files
PowershellScripts/Services/Install-SFTP-Server.ps1
2024-09-25 14:56:13 +00:00

210 lines
9.0 KiB
PowerShell

<#
.SYNOPSIS
Installs and configures OpenSSH Server on a Windows system, creates a local group and user account, and sets up SFTP access with a custom port and root folder.
.DESCRIPTION
This script automates the process of installing and configuring OpenSSH Server on a Windows system, creating a local group and user account,
and setting up SFTP access with a custom port and root folder. It also configures the firewall rules, sets up the SFTP root folder,
and updates the sshd_config file accordingly.
.PARAMETER Force
Optional parameter to force the installation and configuration of OpenSSH Server, even if it's already installed.
.NOTES
This script is intended for use in a test or production environment. Make sure to test the script in a non-production environment before running it in production.
Author: W. Manurat
DISCLAIMER: Use scripts at your own risk, if there is anything I can help you with I will try but I do not take responsibility for the way that anyone else uses my scripts.
Sharing is caring. Share your knowledge with the world so that everybody can learn from it.
.LINK
The latest version can Always be found on my GIT page on the link below:
https://git.dcomputers.nl/Dcomputers/PowershellScripts
#>
#Parameters
param(
[Parameter(Mandatory=$false)]
[Bool]$Force
)
#region Global script settings and variables
#General
$Version = "v1.0"
$logfilelocation = "$($MyInvocation.MyCommand.Path | Split-Path -Parent)\Logs"
$logfilename = "$(Get-Date -Format yyyyMMddHHmmss)-Install-SFTP-Server.log"
#User Inputs
$customPort = Read-Host "Please enter the local port to be used for OpenSSH"
$groupName = Read-host "Enter the groupname"
$userName = Read-host "Enter the username for the user"
$password = Read-host "Enter the password for the user" -AsSecureString
$sshFilesPath = Read-host "Enter the full path to the SFTP root folder"
#endregion
#region prerequisites check
#Create log directory if not present and initiate logfile
if (!(test-path $logfilelocation)) {mkdir $logfilelocation}
Start-Transcript -path "$logfilelocation\$logfilename" -Append -Verbose
#Validate user input
if ($customPort -match '^\d+$') {
$portNumber = [long]$customPort
$check = $portNumber -ge 1 -and $portNumber -le 65535
} else {
$check = $false
}
if (($null -eq $customPort) -or (!($check))){
Write-Host "ERROR: The specified custom port does not range between 1 - 65535."
Write-Host "ERROR: Rerun script with the correct parameter"
Stop-Transcript
Pause
exit 1
}
#Check and install required roles
$Roles = @("OpenSSH.Client~~~~0.0.1.0","OpenSSH.Server~~~~0.0.1.0")
if (!($Force)){
if (!(Get-WindowsCapability -Online | Where-Object {$_.Name -in $Roles -and $_.State -ne 'Installed'})){
Write-Host "ERROR: All roles are already installed."
Write-Host "Rerun Script with -Force to force installation and configuration"
Stop-Transcript
Pause
exit 1
}
}
foreach ($role in $Roles) {
$check = Get-WindowsCapability -Online | Where-Object { $_.Name -eq "$role" } | Select-Object -ExpandProperty State
if ($check -ne "Installed"){
Write-Host "The role $role is not installed, installing it now"
Add-WindowsCapability -Online -Name $role
}
else {
Write-Host "INFO: $role is already installed skipping installation..."
}
}
#Start Service
$service = "sshd"
Set-Service -Name $service -StartupType 'Automatic'
Write-Host "INFO: Service Startup type changed to 'Automatic'"
Start-Service -Name $service
Write-Host "INFO: Service started"
#endregion
#region performing stufffs
#Configure firewall rules
#Disable default FW rule
if (Get-NetFirewallRule -Name "*SSH*" -ErrorAction SilentlyContinue) {
Disable-NetFirewallRule -Name "*SSH*"
Write-Host "INFO: Default Firewall Rule 'OpenSSH-Server-In-TCP' has been disabled."
}
else {
Write-Host "INFO: Default Firewall Rule 'OpenSSH-Server-In-TCP' does not exist."
}
#Create custom FW rule
# Check if a firewall rule with the same name already exists
if (!(Get-NetFirewallRule -Name "OpenSSH-Server-CustomPort-$customPort" -ErrorAction SilentlyContinue)) {
# Create a new firewall rule for OpenSSH with the custom port
New-NetFirewallRule -Name "OpenSSH-Server-CustomPort-$customPort" `
-DisplayName "OpenSSH Server (sshd) Custom Port $customPort" `
-Enabled True `
-Direction Inbound `
-Protocol TCP `
-Action Allow `
-LocalPort $customPort
Write-Host "INFO: New Firewall Rule 'OpenSSH-Server-CustomPort-$customPort' has been created and enabled."
} else {
Write-Host "WARNING: Firewall Rule 'OpenSSH-Server-CustomPort-$customPort' already exists."
if ($Force){
Get-NetFirewallRule -Name "OpenSSH-Server-CustomPort-$customPort" | Remove-NetFirewallRule -Confirm $false
Write-Host "INFO: Old (duplicate) custom rule is removed"
New-NetFirewallRule -Name "OpenSSH-Server-CustomPort-$customPort" `
-DisplayName "OpenSSH Server (sshd) Custom Port $customPort" `
-Enabled True `
-Direction Inbound `
-Protocol TCP `
-Action Allow `
-LocalPort $customPort
Write-Host "INFO: New Firewall Rule 'OpenSSH-Server-CustomPort-$customPort' has been created and enabled."
}
}
#Create Group & User
#Create Group if not exists
if (Get-LocalGroup -Name $groupName -ErrorAction SilentlyContinue) {
Write-Host "WARNING: The group $groupName already exists."
}
else {
New-LocalGroup -Name $groupName -Description "Group for SFTP access users"
Write-Host "INFO: Group $groupName has been created."
}
#create User and assign custom SFTP group
if (Get-LocalUser -Name $userName -ErrorAction SilentlyContinue) {
Write-Host "WARNING: The user $userName already exists."
$groupMembers = Get-LocalGroupMember -Group "$groupName" | Select-Object -ExpandProperty name
if (!($groupMembers -like "*$userName*")){
Write-Host "WARNING: The user is not part of the $groupName group. Adding user to the group."
Add-LocalGroupMember -Group $groupName -Member $userName
Write-Host "INFO: User $userName has been created and added to the group $groupName."
}
}
else {
New-LocalUser -Name $userName -Password $password -Description "User with SFTP access" -AccountNeverExpires -PasswordNeverExpires
Add-LocalGroupMember -Group $groupName -Member $userName
Write-Host "INFO: User $userName has been created and added to the group $groupName."
}
#Create SFTP Root folder
if (!(Test-Path "$sshFilesPath")) {
New-Item -Path "$sshFilesPath" -ItemType Directory
Write-Host "INFO: The SFTP root folder has been created at: $sshFilesPath."
}
else {
Write-Host "WARNING: The SFTP root folder already exists at: $sshFilesPath."
}
#Configure sshd_config
# Read the current contents of the sshd_config file
$sshdConfig = Get-Content (Join-Path $env:ProgramData "ssh\sshd_config")
# Change the default port using the value entered by the user
$sshdConfig = $sshdConfig -replace '^(#?Port\s+).*$', "Port $customPort"
# Add the SFTP configuration block for the group $groupname
$sftpConfig = @"
# SFTP configuration for group $groupname
Match Group $groupname
ForceCommand internal-sftp
ChrootDirectory "$sshFilesPath"
AllowTcpForwarding no
X11Forwarding no
"@
# Check if the SFTP configuration is already present
if (-Not ($sshdConfig -join "`n" -match "Match Group $groupname")) {
# Append SFTP configuration with a newline for separation
$sshdConfig += "`n" + $sftpConfig
Write-Host "INFO: SFTP configuration has been added to the sshd_config file."
}
else {
Write-Host "WARNING: SFTP configuration is already present in the sshd_config file."
}
# Write the modified content back to the sshd_config file
$sshdConfig | Set-Content -Path (Join-Path $env:ProgramData "ssh\sshd_config") -Force
Write-Host "INFO: The 'sshd_config' file has been updated successfully."
# Restart the SSH service to apply changes
Stop-Service -Name "sshd"
Start-Service -Name "sshd"
Write-Host "INFO: OpenSSH service has been restarted to apply the changes."
#endregion
Stop-Transcript
pause
Exit 0