This page looks best with JavaScript enabled

There's PowerShell In My Marzicraft!

 ·  ☕ 5 min read

One of the servers I manage is a Minecraft server for a friend. It’s called Marzicraft, it has a candy theme, and it’s delightful, even if I do say so myself. :) I recently replaced the .bat scripts I wrote to maintain it with a single PowerShell script. Even if you aren’t supporting a Minecraft server, hopefully there’s some useful information here for your own work.

If you are intending to use this script for your own Minecraft server, please be aware that I’ve put this together with a dedicated server in mind. This script won’t be of any use to you if you have shared hosting, or hosting where you don’t get access to the operating system. I also manage a Minecraft server that uses shared hosting with limited access to the host, and I’ll talk about managing that in a future post. So, on to the script.

For me, I needed to automate backup and general clean-up tasks. If you’re not aware, whenever a Minecraft server restarts, it compresses the current logs and creates new ones. The Minecraft process needs to restart at least twice per day, so after a while you can have a disk full of logs.

The script below has been tested on Windows Server 2008 R2, although you will need to install .NET Framework 4.5 and Windows Management Framework 5.0.

It should run on later versions of Windows although .NET Framework 4.5 will still need to be installed.

The script!

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
# ----------------------------------
# Script: Marzicraft-Maintenance.ps1
# Author: Mike Galvin
# Date: 17/10/2016
# ----------------------------------
#Set Paths
$World = "C:\_Marzicraft_Server\MAIN_WORLD"
$Logs = "C:\_Marzicraft_Server\logs"
$Backup = "C:\OneDrive\Marzicraft_Bkup"
$Server = "C:\_Marzicraft_Server"
$Scripts = "C:\_Scripts"
 
#Backup the World
Copy-Item $World $Scripts\world_temp -recurse
Add-Type -AssemblyName "system.io.compression.filesystem"
[io.compression.zipfile]::CreateFromDirectory("$Scripts\world_temp", "$Scripts\MAIN_WORLD-{0:yyyy-MM-dd-HH-mm}.zip" -f (get-date))
remove-item $Scripts\world_temp -recurse
move-item $Scripts\MAIN_WORLD-*.zip $Backup\World
Get-ChildItem Path $Backup\World Recurse | Where-Object CreationTime lt (Get-Date).AddDays(-7) | Remove-Item
Get-ChildItem Path $Logs Recurse | Where-Object CreationTime lt (Get-Date).AddDays(-7) | Remove-Item
 
#Backup the Server core
ROBOCOPY /MIR /R:0 /W:0 /LOG:$Backup\Scripts\backup.log /NP /NDL $Server $Backup\Server /XD $World $Server\dynmap\web\tiles
ROBOCOPY /MIR /R:0 /W:0 /LOG+:$Backup\Scripts\backup.log /NP /NDL $Scripts $Backup\Scripts

I’ll talk about the obvious thing at the end first. Yes! Robocopy isn’t a PowerShell command, it’s a command line utility. It’s still a great tool and at the time of writing the script it was 1AM. I’ll most likely revisit it in future at some point and improve the script. As for the rest of the code, let’s go through it:

1
2
3
4
5
6
#Set Paths
$World = "C:\_Marzicraft_Server\MAIN_WORLD"
$Logs = "C:\_Marzicraft_Server\logs"
$Backup = "C:\OneDrive\Marzicraft_Bkup"
$Server = "C:\_Marzicraft_Server"
$Scripts = "C:\_Scripts"

First, the directories are set as variables.

1
Copy-Item $World $Scripts\world_temp -recurse

The Minecraft world folder is copied to a temp location.

1
Add-Type -AssemblyName "system.io.compression.filesystem"

The script loads the .NET assembly to create .zip files. This piece of code I found on the fantastic TechNet blog Hey, Scripting Guy!

1
[io.compression.zipfile]::CreateFromDirectory("$Scripts\world_temp", "$Scripts\MAIN_WORLD-{0:yyyy-MM-dd-HH-mm}.zip" -f (get-date))

A .zip file is created from the copied world and the file is named with the current date and time.

1
2
remove-item $Scripts\world_temp -recurse
move-item $Scripts\MAIN_WORLD-*.zip $Backup\World

The temp world folder and contents is deleted and the .zip file backup is moved to the backup location, in this case, the OneDrive location on the server.

1
2
Get-ChildItem Path $Backup\World Recurse | Where-Object CreationTime lt (Get-Date).AddDays(-7) | Remove-Item
Get-ChildItem Path $Logs Recurse | Where-Object CreationTime lt (Get-Date).AddDays(-7) | Remove-Item

The script then deletes any backup files and Minecraft log files older than 7 days.

1
2
ROBOCOPY /MIR /R:0 /W:0 /LOG:$Backup\Scripts\backup.log /NP /NDL $Server $Backup\Server /XD $World $Server\dynmap\web\tiles
ROBOCOPY /MIR /R:0 /W:0 /LOG+:$Backup\Scripts\backup.log /NP /NDL $Scripts $Backup\Scripts

The final step of the script is to backup the rest of the core Minecraft server files to the backup location, whilst ignoring the world folder and some additional files which aren’t required. A log of the copy operation is saved in the backup location.

What you should have at the end of this script is:

  • A folder named ‘Server’ with a copy of the server files.
  • A folder named ‘World’ with 7 days worth of backups of the world.
  • A folder named ‘Scripts’ with a copy of the backup script and a log of the Robocopy sync operation.

This script works great for how Marzicraft is setup. Depending on how your Minecraft server is set up, you’re mileage may vary. Minecraft is so modifiable that there are many, many quirks with each version and they can all behave differently depending on which mods/plugins/managers are installed. I have the script set to run every day via Task Scheduler. Running PowerShell scripts can be a little frustrating if you’re used to the old batch scripts. In the case of Task Scheduler you must enter this command as the action:

1
PowerShell.exe -ExecutionPolicy Bypass C:\_Scripts\Marzicraft-Maintenance.ps1

Here, you are running PowerShell, bypassing the execution policy (which is a common thing that trips everyone up) and then executing the script. When testing your script, open up the Command Prompt and run the above command. I can also recommend the PowerShell ISE which is a great environment for writing scripts, testing them as well as learning PowerShell.

If you have any questions or comments please leave them below.

-Mike

Share on
Support the author with