210 lines
9.0 KiB
PowerShell
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 |