mirror of
https://github.com/immense/Remotely.git
synced 2025-10-26 11:27:15 +00:00
345 lines
12 KiB
PowerShell
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..." |