Remotely/Utilities/Install-RemotelyServer.ps1
2021-07-29 07:53:55 -07:00

345 lines
12 KiB
PowerShell

<#
.SYNOPSIS
Configures IIS and installs the Remotely server.
.COPYRIGHT
Copyright © 2019 Translucency Software. All rights reserved.
#>
$ErrorActionPreference = "Stop"
$Host.UI.RawUI.WindowTitle = "Remotely Setup"
Clear-Host
#region Variables
$InstallPath = ""
$Website = $null
$ServerCmdlets = $false
$FirewallSet = $false
$CopyErrors = $false
if ($PSScriptRoot -eq ""){
$PSScriptRoot = (Get-Location)
}
$Root = (Get-Item -Path $PSScriptRoot).Parent.FullName
#endregion
#region Functions
function Wrap-Host
{
[CmdletBinding()]
[Alias()]
[OutputType([int])]
Param
(
# The text to write.
[Parameter(Mandatory=$false,
ValueFromPipelineByPropertyName=$true,
Position=0)]
[String]
$Text,
# Param2 help description
[Parameter(Mandatory=$false,
ValueFromPipelineByPropertyName=$true,
Position=1)]
[ConsoleColor]
$ForegroundColor
)
Begin
{
}
Process
{
if (!$Text){
Write-Host
return
}
$Width = $Host.UI.RawUI.BufferSize.Width
$SB = New-Object System.Text.StringBuilder
while ($Text.Length -gt $Width) {
[int]$LastSpace = $Text.Substring(0, $Width).LastIndexOf(" ")
$SB.AppendLine($Text.Substring(0, $LastSpace).Trim()) | Out-Null
$Text = $Text.Substring(($LastSpace), $Text.Length - $LastSpace).Trim()
}
$SB.Append($Text) | Out-Null
if ($ForegroundColor)
{
Write-Host $SB.ToString() -ForegroundColor $ForegroundColor
}
else
{
Write-Host $SB.ToString()
}
}
End
{
}
}
#endregion
#region Prerequisite Tests
### Test if process is elevated. ###
$User = [Security.Principal.WindowsIdentity]::GetCurrent()
if ((New-Object Security.Principal.WindowsPrincipal $User).IsInRole([Security.Principal.WindowsBuiltinRole]::Administrator) -eq $false) {
Wrap-Host
Wrap-Host "Error: This installation needs to be run from an elevated process (Run as Administrator)." -ForegroundColor Red
Read-Host "Press Enter to exit"
return
}
### Check Script Root ###
if (!$PSScriptRoot) {
Wrap-Host
Wrap-Host "Error: Unable to determine working directory. Please make sure you're running the full script and not just a section." -ForegroundColor Red
Read-Host "Press Enter to exit"
return
}
### Check OS version. ###
$OS = Get-WmiObject -Class Win32_OperatingSystem
if ($OS.Name.ToLower().Contains("home") -or $OS.Caption.ToLower().Contains("home")) {
Wrap-Host
Wrap-Host "Error: Windows Home version does not have the necessary features to run Remotely." -ForegroundColor Red
Read-Host "Press Enter to exit"
return
}
### Test if Windows Feature cmdlets are available. ###
if ((Get-Command -Name "Add-WindowsFeature" -ErrorAction Ignore) -eq $null) {
$ServerCmdlets = $false
}
else {
$ServerCmdlets = $true
}
#endregion
### Hosting Requirements ###
Wrap-Host
Wrap-Host "**********************************"
Wrap-Host " IMPORTANT" -ForegroundColor Green
Wrap-Host "**********************************"
Wrap-Host
Wrap-Host "You must have the .NET Core Runtime installed, which includes the IIS hosting module. The SDK doesn't have this."
Wrap-Host
Wrap-Host "If you have not already done so, please download and install it from the following link:"
Wrap-Host
Wrap-Host "https://dotnet.microsoft.com/download"
Wrap-Host
Read-Host "Press Enter to continue"
Clear-Host
### Intro ###
Clear-Host
Wrap-Host
Wrap-Host "**********************************"
Wrap-Host " Remotely Setup" -ForegroundColor Cyan
Wrap-Host "**********************************"
Wrap-Host
Wrap-Host "Hello, and thank you for trying out Remotely!" -ForegroundColor Green
Wrap-Host
Wrap-Host "This setup script will install Remotely on this machine. Please make sure you've already created a website in IIS where Remotely will be installed." -ForegroundColor Green
Wrap-Host
Wrap-Host "If you encounter any problems or have any questions, please contact Translucency_Software@outlook.com." -ForegroundColor Green
Wrap-Host
Read-Host "Press Enter to begin installation"
Clear-Host
### Automatic IIS Setup ###
if ($ServerCmdlets) {
$RebootRequired = $false
Wrap-Host
Wrap-Host "Installing IIS components..." -ForegroundColor Green
Write-Progress -Activity "IIS Component Installation" -Status "Installing web server" -PercentComplete (1/7*100)
$Result = Add-WindowsFeature Web-Server
if ($Result.RestartNeeded -like "Yes")
{
$RebootRequired = $true
}
Write-Progress -Activity "IIS Component Installation" -Status "Installing ASP.NET" -PercentComplete (2/7*100)
$Result = Add-WindowsFeature Web-Asp-Net
if ($Result.RestartNeeded -like "Yes")
{
$RebootRequired = $true
}
Write-Progress -Activity "IIS Component Installation" -Status "Installing ASP.NET 4.5" -PercentComplete (3/7*100)
$Result = Add-WindowsFeature Web-Asp-Net45
if ($Result.RestartNeeded -like "Yes")
{
$RebootRequired = $true
}
Write-Progress -Activity "IIS Component Installation" -Status "Installing web sockets" -PercentComplete (4/7*100)
$Result = Add-WindowsFeature Web-WebSockets
if ($Result.RestartNeeded -like "Yes")
{
$RebootRequired = $true
}
Write-Progress -Activity "IIS Component Installation" -Status "Installing IIS management tools" -PercentComplete (5/7*100)
$Result = Add-WindowsFeature Web-Mgmt-Tools
if ($Result.RestartNeeded -like "Yes")
{
$RebootRequired = $true
}
Write-Progress -Activity "IIS Component Installation" -Status "Installing web filtering" -PercentComplete (6/7*100)
$Result = Add-WindowsFeature Web-Filtering
if ($Result.RestartNeeded -like "Yes")
{
$RebootRequired = $true
}
Write-Progress -Activity "IIS Component Installation" -Status "IIS setup completed" -PercentComplete (7/7*100) -Completed
Start-Sleep 2
}
else
{
Wrap-Host
Wrap-Host "Installing IIS components..." -ForegroundColor Green
Write-Progress -Activity "IIS Component Installation" -Status "Installing web server" -PercentComplete (1/7*100)
DISM /Online /Enable-Feature /FeatureName:IIS-WebServer /All /Quiet
Write-Progress -Activity "IIS Component Installation" -Status "Installing ASP.NET" -PercentComplete (2/7*100)
DISM /Online /Enable-Feature /FeatureName:IIS-ASPNET /All /Quiet
Write-Progress -Activity "IIS Component Installation" -Status "Installing ASP.NET 4.5" -PercentComplete (3/7*100)
DISM /Online /Enable-Feature /FeatureName:IIS-ASPNET45 /All /Quiet
Write-Progress -Activity "IIS Component Installation" -Status "Installing web sockets" -PercentComplete (4/7*100)
DISM /Online /Enable-Feature /FeatureName:IIS-WebSockets /All /Quiet
Write-Progress -Activity "IIS Component Installation" -Status "Installing IIS management tools" -PercentComplete (5/7*100)
DISM /Online /Enable-Feature /FeatureName:IIS-ManagementConsole /All /Quiet
Write-Progress -Activity "IIS Component Installation" -Status "Installing web filtering" -PercentComplete (6/7*100)
DISM /Online /Enable-Feature /FeatureName:IIS-RequestFiltering /All /Quiet
Write-Progress -Activity "IIS Component Installation" -Status "IIS setup completed" -PercentComplete (7/7*100) -Completed
Start-Sleep 2
}
Clear-Host
$Sites = Get-Website
### Site Selection ###
while ($Website -eq $null) {
Wrap-Host
$Sites
Wrap-Host
Wrap-Host "Enter the ID of the website where Remotely will be installed." -ForegroundColor Green
Wrap-Host
$ID = Read-Host "Website ID"
$Website = Get-Website | Where-Object {$_.ID -like $ID}
}
$InstallPath = $Website.physicalPath.Replace("%SystemDrive%", $env:SystemDrive)
Wrap-Host
Wrap-Host "This will DELETE ALL FILES in the selected website and install Remotely Server. If this is not your intention, close this window now and create a new website where Remotely Server will be installed." -ForegroundColor Red
Wrap-Host
pause
# Stop site.
Clear-Host
Wrap-Host
Wrap-Host "Stopping website..." -ForegroundColor Green
Stop-Website -Name $($Website.name)
### File Cleanup ###
Wrap-Host
Wrap-Host "Cleaning up existing files..." -ForegroundColor Green
$Success = $false
while ($Success -eq $false) {
try {
Get-ChildItem -Path "$InstallPath" -Recurse | Remove-Item -Force -Recurse
$Success = $true
}
catch {
Start-Sleep -Seconds 1
}
}
### Download Server Package ###
try {
if ((Test-Path -Path "$env:TEMP\Server.zip")){
Remove-Item -Path "$env:TEMP\Server.zip" -Force
}
Wrap-Host "Downloading server package..."
[Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12
Invoke-WebRequest -Uri "https://remotely.lucency.co/Downloads/win-x64/Server.zip" -OutFile "$env:TEMP\Server.zip"
Wrap-Host "Extracting server files..."
[System.Reflection.Assembly]::LoadWithPartialName("System.IO.Compression.FileSystem") | Out-Null
[System.IO.Compression.ZipFile]::ExtractToDirectory("$env:TEMP\Server.zip", $InstallPath)
}
catch {
Wrap-Host
Wrap-Host "Error: Unable to download or extract client files." -ForegroundColor Red
Read-Host "Press Enter to exit"
return
}
### Set ACL on website folders and files ###
Wrap-Host
Wrap-Host "Setting ACLs..." -ForegroundColor Green
$Acl = Get-Acl -Path $InstallPath
$Rule = New-Object System.Security.AccessControl.FileSystemAccessRule("BUILTIN\IIS_IUSRS", "Modify", "ContainerInherit,ObjectInherit", "None", "Allow")
$Acl.AddAccessRule($Rule)
$Acl.SetOwner((New-Object System.Security.Principal.NTAccount("Administrators")))
Set-Acl -Path $InstallPath -AclObject $Acl
Get-ChildItem -Path $InstallPath -Recurse | ForEach-Object {
Set-Acl -Path $_.FullName -AclObject $Acl
}
### Firewall Rules ###
Wrap-Host
Wrap-Host "Checking firewall rules for HTTP/HTTPS..." -ForegroundColor Green
try
{
Enable-NetFirewallRule -Name "IIS-WebServerRole-HTTP-In-TCP"
Enable-NetFirewallRule -Name "IIS-WebServerRole-HTTPS-In-TCP"
if ((Get-NetFirewallRule -Name "IIS-WebServerRole-HTTP-In-TCP").Enabled -like "False" -or (Get-NetFirewallRule -Name "IIS-WebServerRole-HTTP-In-TCP").Enabled -like "False")
{
$FirewallSet = $false
}
else
{
$FirewallSet = $true
}
}
catch
{
$FirewallSet = $false
}
# Start website.
Start-Website -Name $($Website.name)
Wrap-Host
Wrap-Host
Wrap-Host
Wrap-Host "**********************************"
Wrap-Host " Server setup complete!" -ForegroundColor Green
Wrap-Host "**********************************"
Wrap-Host
Wrap-Host "Website bindings and SSL need to be set up in IIS, if they're not already. This process needs to be completed manually. I recommend researching Let's Encrypt for free, automated SSL certificates." -ForegroundColor Green
if ($RebootRequired) {
Wrap-Host
Wrap-Host "A reboot is required for the new IIS components to work properly. Please reboot your computer at your earliest convenience." -ForegroundColor Red
}
if ($FirewallSet -eq $false)
{
Wrap-Host
Wrap-Host "Firewall rules were not properly set. Please ensure that ports 80 (HTTP) and 443 (HTTPS) are open. Windows Firewall has predefined rules for these called ""World Wide Web Services (HTTP(S) Traffic-In)""." -ForegroundColor Red
}
if ($CopyErrors)
{
Wrap-Host
Wrap-Host "There were errors copying some of the server files. Please try deleting all files in the website directory and trying again." -ForegroundColor Red
}
Wrap-Host
Read-Host "Press Enter to exit..."