Bash Scripts:

Battery Backup:

Did the battery die lol?

This script takes advantage of the fact that the wall server is a repurposed laptop in the best possible way: the battery acts as a UPS for the machine itself. Of course, the motherboard is connected directly to the battery and thus is able to detect some pertinent information: the state of the battery and the remaining charge as well. Thus, commands to read that information are readily accessible.

First I defined two functions, Numberize_String and State_Trimmer; I only call them one time each, but they streamline the readibility of the code. Next I defined the base command I would be using, and call it twice with modifications to pull specific information: the percentage of charge left and whether it is discharging or not.

Next I check if the battery is discharging. If it is, I further check if it is under 50% yet. If so, I create a variable called log_file pointing to a specific file path and check if that file exists; if it does not I create it. Next I output a shutdown message to that log file with the battery percentage left, as well as the time and date. Then I copy that to a shared location so anyone can easily read these logs. Finally, I send the command to gently shut down the server and in the meantime exit the loop.

If the battery is not discharging, or if it is but is still above 50%, I create a variable pointing to a different log file. I check if that file exists, and if not I create it. I then output to that file a message giving information about the battery: the state, the percentage left, the time and the date. Finally, I copy that file to a shared location so anyone can easily read these logs.

Minecraft Backup - Init:

Did we initialize our backup directory?

This script is used to prime the directories for receiving the backups. This script can be run manually, but the proper Minecraft Backup script will also run this if it detects the appropriate directories do not yet exist.

This script must be called with an argument supplied, which is the name of the Minecraft world to be backed up. It checks to see if there exists a directory by that name where Minecraft backups are kept. If such a directory does not exist, this script creates an array holding the intervals at which backups are to happen. Then it loops through the array and makes the named directory at the appropriate location, appending the name of the value the current index holds, and creates the parent directory as needed. Finally, it gives recursive ownership to the user 'minecraft' of the directories we just made.

This script is not run by user 'minecraft' because the script that actually saves backups can call this one, and that script needs sudo permissions. That is why we must give ownership back to user 'minecraft' after this script is run. I could check to see if 'minecraft' owns the directory before simply assigning ownership, but I think that taking recursive ownership of a directory that is only holding three empty directories is not much more resource-demanding than ownership of the parent directory.

Minecraft Backup:

Did we recover a corrupted backup?

This script is used to generate backups for my Minecraft server that I am hosting. When I originally wrote this I used three scripts to handle daily, weekly and monthly backups. The FREQUENCY variable held those three different values across the three scripts, while the DAYS variable held 7, 31 and 93. The WORLD_NAME variable was the same across all three scripts.

First the script checks to see if there exists a directory in the backup location with the same name as the Minecraft world. If this directory does not exist the above-mentioned script is called and the appropriate directories are created. Next, this script sends a message to the Minecraft server that any users who may be logged in will have a chance to see, warning them that the server will be backing up in 60 seconds and will return momentarily. Then the script sleeps for 60 seconds.

Next the script actually stops the server. After that it looks for any existing backups in the directory with this WORLD_NAME, in the subdirectory FREQUENCY for either daily, weekly, or monthly, and if it is older than the DAYS variable it will delete them. The script then sleeps for 5 additional seconds to give the server time to close and finish writing files, and takes a timestamp. It also saves a variable, BACKUP_FILE, with the complete directory path and file name, using the timestamp we took.

The script then creates the tar file, in the Minecraft backup directory, subdirectory WORLD_NAME, subdirectory FREQUENCY, and names it with the timestamp taken. The source of this tar file is at the Minecraft server subdirectory WORLD_NAME. The script then gives ownership of the newly-created backup file to user 'minecraft', while user 'zanycat' is given group ownership. Finally, the script restarts 'minecraft' systemd service.

PowerShell Scripts:

Standby after Minutes Readouts:

Did the computer enter standby already?

This script was written largely to gain some familiarity with PowerShell, but I also had a purpose in mind. If you run PowerShell as an Administrator and use the command powercfg /requests you will see a readout of hardware and software that may be keeping your computer from entering a standby state. Even if Windows is set to enter standby after 20 minutes of inactivity, sometimes an audio channel will keep it from doing so. Sometimes when you get up from your computer you want it to remain awake for some time before entering standby. That is what this script is for.

First, the user is prompted to enter the number of minutes they want to stay awake before entering standby. Then the script takes a timestamp of when it was run. The terminal tells the user the system will enter standby at a time equal to that time plus the length of time the user wanted to wait for.

The script then calls a function I wrote, StayAwakeForDelay with the value $delay supplied as an argument. This function also takes an optional argument, loopcycle (by default set to 60) in the case that a user calling this function wants the loop cycle longer or shorter than 60 seconds. This function creates a string that when Invoke-Expression is used on it, it returns the current time in 'HHmmss' format, cast as an integer. This string is called $intNowRequest

The function then creates a Wscript.Shell object that will be used to send keystrokes. Next it instantiates a variable, $sleepInt, holding the value of the current time plus the $delay variable, in 'HHmmss' format, cast as an integer. A while loop is entered that repeats as long as $sleepInt is greater than the value of Invoke-Expression $intNowRequest. This is why I saved the function call as a string, so that string could be invoked repeatedly with ease.

Inside of the while loop the Scroll Lock key is pressed twice, the input buffer is flushed, and the thread sleeps for a number of seconds equal to $loopCycle (which defaults to 60). This is repeated until the number of minutes $delay holds has passed, and then the function exits.

Next, the script creates a variable called $hibernateTimes and sets it equal to the result of another function I wrote, called EnterExitTimeHibernate. This simple function takes no parameters. It instantiates a variable, $timeEntered, and sets it equal to the current time. Then the function puts the machine into suspend mode, using | Out-Null in order to send any output from running that to Null instead of the console. When the machine is returned from suspend state this function resumes and the variable $timeExited is instantiated, which takes the current time again. The function then returns these two values to $hibernateTimes, which is an array holding these two values at indices 0 and 1.

The script then creates some output, which will both be written to the console and to a file. The first string, $commandRunAtMessage, tells the time and date the user ran the script. The second, $entryMessage, holds the time standby was entered. The third, $exitMessage, holds the time standby was exited. The fourth, $standbyMessage, returns the time between entering and exiting standby. This is done by calling a function, OutputDurationDHMS, and supplying a timespan object that is created from the date objects $hibernateTimes holds at both indices 0 and 1.

OutputDurationDHMS is kind of a clunky, ugly funciton. Basically, this function creates an empty output array, called $durationArray, and moves through each member of the $timespan parameter the function takes in appending, as a string, the value of each of those members plus the singular or the plural of said member. That is, ' days' or ' day', ' hours' or ' hour', ' minutes' or ' minute' and finally ' seconds' or ' second'. Note the space added between the value and the singular/plural. It is decided to use singular or plural based on if the value held at $timespan.Days/Hours/Minutes/Seconds is equal to 1 or not. It then returns a string that is each index of the array, 0 through 3, with a space between each.

The next two function calls are very similar. The first one is WriteVariablesToHost, which takes in an array of strings and iterates over it, writing each to the host (console). The second one, a little more complex, is WriteVariablesToFile. This function takes in an array of strings, as well as a file at a location and a 'true' or 'false' value. The function is called with a filename 'readouts.txt' in the current location, which is the desktop. If 'true' is supplied then the output file is appended to. If 'true' is not supplied then the output file is recreated and only the current string array values will be held.