Powershell Script For Installing Minecraft Bedrock Edition

In this article, I will go over the process of how I have developed a Powershell script to automate the process of setting up a Minecraft Server Bedrock Edition on an Ubuntu Server.

You can find the complete script on my Github page: https://github.com/ScriptingChris/pwsh-minecraft

Prerequisites

All you need to run this powershell script is an Ubuntu Server with Powershell installed.

To install Powershell on Ubuntu you can run the following command:

sudo snap install powershell

or if don’t want to use snap, you can use the approach described on Microsoft Docs:

# Update the list of packages
sudo apt-get update
# Install pre-requisite packages.
sudo apt-get install -y wget apt-transport-https software-properties-common
# Download the Microsoft repository GPG keys
wget -q https://packages.microsoft.com/config/ubuntu/16.04/packages-microsoft-prod.deb
# Register the Microsoft repository GPG keys
sudo dpkg -i packages-microsoft-prod.deb
# Update the list of packages after we added packages.microsoft.com
sudo apt-get update
# Install PowerShell
sudo apt-get install -y powershell

What should the script do?

I always like to start my scripts by looking at what are the end state or the goal of the script. Then i will part the script into sections which combined will accomplish that goal.

Goal of the script:

The goal of the script is to download the Minecraft Bedrock Edition Server, and Install it.

Tasks:

  1. Download the newest version of Minecraft Bedrock Server Edition
  2. Install the server
  3. Create the server as a systemctl service
  4. Start the server
  5. Cleaning up the temp files

Downloading the newest version of Minecraft Bedrock Server

First of all, I will start by setting the parameters for the script. I will use the parameters as variables primarily for folder structure and paths. This will also give the user a chance to easily change the folders they want the server installed in.

param (
    [Parameter(Mandatory=$true)]
    [String]$LinuxUsername,
    [String]$ServerWorkingDirectory = "/home/$LinuxUsername/bedrock-server",
    [String]$DownloadFilePath = "/home/$LinuxUsername/"
)

The parameter $LinuxUsername is the username for the actual user on the server who is running the server. This will look at the specific Home folder where the server will be installed.

The parameters $ServerWorkingDirectory and $DownloadFilepath is not need to be set by the user, but I have set them as parameters in case the user wants to change the paths.
Now to download the Minecraft Server File from “https://www.minecraft.net/en-us/download/server/bedrock” I will use Invoke-Webrequest.

The Powershell will look like this:

$request = Invoke-Webrequest -Uri "https://www.minecraft.net/en-us/download/server/bedrock"
$downloadLink = $request.Links | Where-Object class -match "btn" | Where-Object href -match "bin-linux/bedrock-server" | Select-Object -ExpandProperty href

try {
    Write-Output "Downloading the Minecraft server from: $downloadLink"
    $result = Invoke-Webrequest -Uri $downloadLink -OutFile "$DownloadFilePath/bedrock-server.zip"
}
catch {
    Write-Warning "Error - Failed downloading the Minecraft Server from: $downloadLink, with message: $($_.Exception.Message)"
    $_.Exception.Response.StatusCode.Value__
}

This snippet will find the download link by scraping the website with invoke-webrequest. It will look at the links with the class “btn”. Then it will format the link URL to find the specific URL to download the file.

This will be equal to going to the website and clicking on the download link:

The Minecraft Server Zip file will be downloaded to the user’s home folder.

Installing the Minecraft Server

The installation process is fairly simple since it is more or less just extracting the zip file into the desired folder.

To do this I will run the following:

# Extracting the server files
Try {
    Write-Output "Extracting the server files to $ServerWorkingDirectory"
    Expand-Archive -Path "$DownloadFilePath/bedrock-server.zip" -DestinationPath $ServerWorkingDirectory    
}
catch {
    $message = $_
    Write-Error -Message "Error - Failed extracting the files with message: $message"
}

One important thing now is that the actual server file, which is used to start the server is not executable, meaning you cannot start the server as it is now.

So to set the file to be executable I will run a bash command through PowerShell:

bash -c "find $ServerWorkingDirectory -name bedrock_server -type f -exec chmod 0755 {} \;"

Creating the server as a systemctl service

The reason for creating the server as a service is that it will be much easier to start, stop, and check the status of the server.

When running the server as a service you can start the server and it will just run in the background. 

It will also be a lot easier to set the server to restart if, your Ubuntu server ever shutdown or restarts.

To create the server as a service I will need to create a .service file and place it inside the folder: /etc/systemd/system

To do this through Powershell i will run the following:

$content = @"
[Unit]
Description=Minecraft Service
After=network.target

[Service]
User=$($LinuxUsername)

Type=simple

WorkingDirectory=$($ServerWorkingDirectory)
ExecStart=/bin/sh -c "./bedrock_server"
TimeoutStopSec=20
Restart=on-failure

[Install]
WantedBy=multi-user.target
"@

Then I will save the content into a file located in the users home folder, and from there I will copy it to: /etc/systemd/system

$serviceFile = "$DownloadFilePath/minecraft.service"
New-Item $serviceFile -Force
Add-Content -Path $serviceFile -Value $content
Write-Output "Copying the service file from: $DownloadFilePath to: /etc/systemd/system/"
bash -c "sudo cp $($serviceFile) /etc/systemd/system/"

Now once the file is copied, the service won’t actually be working until I reload the systemctl daemon. I do this by running:

Write-Output "Reloading the systemctl daemon"
bash -c "sudo systemctl daemon-reload"

Starting the server

Now before I start the server I want to set it to automatically start the server if the Ubuntu server ever restarts or shuts down.

To set the server to automatically start-up run the following:

bash -c "sudo systemctl enable minecraft"

And to start the server:

bash -c "sudo systemctl start minecraft"

Cleaning up the temp files

Now the last thing to do is to clean up after the installation process.

All there is to clean up is the download zip file, and the service file created in the home folder. To remove the two file I will just run the following:

Remove-Item -Path "$DownloadFilePath/bedrock-server.zip" -Force
Remove-Item -Path "$DownloadFilePath/minecraft.service" -Force

The Finished Script

<#
    .SYNOPSIS
        Script for automate the installation of a Minecraft Bedrock Server

    .DESCRIPTION
        This script will download the lates Minecraft Bedrock Edition Server.
        It will also create the server as a systemctl service.
        It will enable the service to automatically start after a restart.
        It will also start the service for you

    .NOTES
        To Install the server:
            "pwsh InstallMinecraftServer.ps1"
        
        To Start the server:
            "sudo systemctl start minecraft"
        
        To Stop the server:
            "sudo systemctl stop minecraft"
        
        To check server status:
            "sudo systemctl status minecraft"
#>


param (
    [Parameter(Mandatory=$true)]
    [String]$LinuxUsername,
    [String]$ServerWorkingDirectory = "/home/$LinuxUsername/bedrock-server",
    [String]$DownloadFilePath = "/home/$LinuxUsername/"
)

# Downloading the server files
$request = Invoke-Webrequest -Uri "https://www.minecraft.net/en-us/download/server/bedrock"
$downloadLink = $request.Links | Where-Object class -match "btn" | Where-Object href -match "bin-linux/bedrock-server" | Select-Object -ExpandProperty href
try {
    Write-Output "Downloading the Minecraft server from: $downloadLink"
    $result = Invoke-Webrequest -Uri $downloadLink -OutFile "$DownloadFilePath/bedrock-server.zip"
}
catch {
    Write-Warning "Error - Failed downloading the Minecraft Server from: $downloadLink, with message: $($_.Exception.Message)"
    $_.Exception.Response.StatusCode.Value__
}


# Extracting the server files
Try {
    Write-Output "Extracting the server files to: $ServerWorkingDirectory"
    Expand-Archive -Path "$DownloadFilePath/bedrock-server.zip" -DestinationPath $ServerWorkingDirectory    
}
catch {
    $message = $_
    Write-Error -Message "Error - Failed extracting the files with message: $message"
}


# Setting executable permissions on the server file
Write-Output "Setting the executable permissions on bedrock_server file"
bash -c "find $ServerWorkingDirectory -name bedrock_server -type f -exec chmod 0755 {} \;"


# Creating the systemctl service file
Write-Output "Generating the minecraft.service file"
$content = @"
[Unit]
Description=Minecraft Service
After=network.target

[Service]
User=$($LinuxUsername)

Type=simple

WorkingDirectory=$($ServerWorkingDirectory)
ExecStart=/bin/sh -c "./bedrock_server"
TimeoutStopSec=20
Restart=on-failure

[Install]
WantedBy=multi-user.target
"@

$serviceFile = "$DownloadFilePath/minecraft.service"
New-Item $serviceFile -Force
Add-Content -Path $serviceFile -Value $content
Write-Output "Copying the service file from: $DownloadFilePath to: /etc/systemd/system/"
bash -c "sudo cp $($serviceFile) /etc/systemd/system/"


Write-Output "Reloading the systemctl daemon"
bash -c "sudo systemctl daemon-reload"


# starting the Minecraft Server
Write-Output "Trying to start the Minecraft Server Service"
try {
    bash -c "sudo systemctl enable minecraft"
    bash -c "sudo systemctl start minecraft"
}
catch {
    Write-Warning -Message "$($_)"
}

# Cleaning up the process
Write-Output "Cleaning up temp files"
Remove-Item -Path "$DownloadFilePath/bedrock-server.zip" -Force
Remove-Item -Path "$DownloadFilePath/minecraft.service" -Force

Leave a Reply

This site uses Akismet to reduce spam. Learn how your comment data is processed.

This website uses cookies. By continuing to use this site, you accept our use of cookies.