# tip: cache password with "sudo ls"
# uninstall currently installed version
sudo apt-get remove libreoffice*
sudo apt-get remove --purge libreoffice*
# download and install LibreOffice
cd ~/Install
wget https://download.documentfoundation.org/libreoffice/stable/7.4.4/deb/x86_64/LibreOffice_7.4.4_Linux_x86-64_deb.tar.gz
tar -xvzf LibreOffice_7.4.4_Linux_x86-64_deb.tar.gz
cd LibreOffice_7.4.4.2_Linux_x86-64_deb/DEBS
sudo dpkg -i *.deb
# download and install offline help files
cd ~/Install
wget https://download.documentfoundation.org/libreoffice/stable/7.4.4/deb/x86_64/LibreOffice_7.4.4_Linux_x86-64_deb_helppack_en-US.tar.gz
tar -xvzf LibreOffice_7.4.4_Linux_x86-64_deb_helppack_en-US.tar.gz
cd LibreOffice_7.4.4.2_Linux_x86-64_deb_helppack_en-US/DEBS
sudo dpkg -i *.deb
# delete extracted installation files
cd ~/Install
rm -rf ~/Install/LibreOffice_7.4.4.2_Linux_x86-64_deb
rm -rf ~/Install/LibreOffice_7.4.4.2_Linux_x86-64_deb_helppack_en-US
Author: jchaven
Do Something on Plug-in of USB Drive
Linux is able to identify a device when something is plugged into an already-running system and then do something in response. Part of this is done with Udev which supplies a dynamic device directory containing only the nodes for devices which are connected to the system. It creates or removes the device node files in the /dev directory as they are plugged in or taken out.
Using this I am able to backup a Linux system to an external hard drive just by plugging in the USB drive. When the drive is connected Linux will detect it, mount it, and start a backup. Once the backup is done the drive will remain mounted so I can review the files before removing the drive.
The process goes something like this: I plug in the USB drive, the system will detect it and mount the drive. A Udev rule will fire off a small script creating a job using “AT” to start the backup script one minute later. AT will start the backup script which will create a directory on the USB drive and backup files to that directory. I then review the backup, unmount the drive, then unplug it.
Udev rules are stored in these two locations:
joey@HAVEN-E6520:~$ ls /usr/lib/udev/rules.d total 940K -rw-r--r-- 1 root root 947 Nov 30 2019 39-usbmuxd.rules -rw-r--r-- 1 root root 998 Jan 20 2019 40-usb-media-players.rules -rw-r--r-- 1 root root 42K Feb 24 2020 40-usb_modeswitch.rules -rw-r--r-- 1 root root 655 Aug 31 11:27 40-vm-hotadd.rules -rw-r--r-- 1 root root 210 Feb 16 2022 50-firmware.rules -rw-r--r-- 1 root root 3.9K Aug 31 11:27 50-udev-default.rules -rw-r--r-- 1 root root 7.2K Feb 13 2020 55-dm.rules -rw-r--r-- 1 root root 1.5K Apr 6 2020 56-dm-parts.rules -rw-r--r-- 1 root root 921 Sep 13 2021 56-hpmud.rules -rw-r--r-- 1 root root 2.4K Feb 13 2020 56-lvm.rules -rw-r--r-- 1 root root 8.4K Aug 31 11:27 60-autosuspend-chromiumos.rules -rw-r--r-- 1 root root 703 Apr 1 2020 60-block.rules -rw-r--r-- 1 root root 1.1K Apr 1 2020 60-cdrom_id.rules -rw-r--r-- 1 root root 69 Jan 17 2017 60-crda.rules -rw-r--r-- 1 root root 413 Apr 1 2020 60-drm.rules -rw-r--r-- 1 root root 990 Apr 1 2020 60-evdev.rules -rw-r--r-- 1 root root 394 Apr 1 2020 60-fido-id.rules -rw-r--r-- 1 root root 329 Jan 8 2016 60-inputattach.rules -rw-r--r-- 1 root root 282 Apr 1 2020 60-input-id.rules -rw-r--r-- 1 root root 7.2K Jun 15 2020 60-libgphoto2-6.rules -rw-r--r-- 1 root root 3.5K Sep 17 2020 60-libsane.rules -rw-r--r-- 1 root root 201 Jul 25 2016 60-openobex.rules -rw-r--r-- 1 root root 912 Feb 10 2020 60-pcmcia.rules -rw-r--r-- 1 root root 616 Apr 1 2020 60-persistent-alsa.rules -rw-r--r-- 1 root root 2.7K Apr 1 2020 60-persistent-input.rules -rw-r--r-- 1 root root 1.8K Feb 13 2020 60-persistent-storage-dm.rules -rw-r--r-- 1 root root 7.6K Aug 31 11:27 60-persistent-storage.rules -rw-r--r-- 1 root root 2.1K Apr 1 2020 60-persistent-storage-tape.rules -rw-r--r-- 1 root root 769 Apr 1 2020 60-persistent-v4l.rules -rw-r--r-- 1 root root 736 Apr 1 2020 60-sensor.rules -rw-r--r-- 1 root root 1.2K Apr 1 2020 60-serial.rules -rw-r--r-- 1 root root 211 Dec 3 2019 60-tpm-udev.rules -rw-r--r-- 1 root root 181 Mar 6 2022 60-virtualbox-dkms.rules -rw-r--r-- 1 root root 454 May 11 2021 60-virtualbox.rules -rw-r--r-- 1 root root 565 Apr 1 2020 61-autosuspend-manual.rules -rw-r--r-- 1 root root 292 Apr 29 2020 61-gnome-settings-daemon-rfkill.rules -rw-r--r-- 1 root root 292 Aug 21 2021 61-mate-settings-daemon-rfkill.rules -rw-r--r-- 1 root root 456 Aug 31 11:27 61-persistent-storage-android.rules -rw-r--r-- 1 root root 387 Feb 15 2020 64-btrfs-dm.rules -rw-r--r-- 1 root root 612 Aug 31 11:27 64-btrfs.rules -rw-r--r-- 1 root root 257 Jul 6 09:53 64-xorg-xkb.rules -rw-r--r-- 1 root root 75K Apr 21 2021 65-libwacom.rules -rw-r--r-- 1 root root 190 Jun 5 2020 66-snapd-autoimport.rules -rw-r--r-- 1 root root 1.2K Apr 6 2020 68-del-part-nodes.rules -rw-r--r-- 1 root root 4.9K Mar 20 2020 69-cd-sensors.rules -rw-r--r-- 1 root root 225K Mar 26 2020 69-libmtp.rules -rw-r--r-- 1 root root 6.5K Feb 13 2020 69-lvm-metad.rules -rw-r--r-- 1 root root 1.2K Mar 11 2020 69-wacom.rules -rw-r--r-- 1 root root 432 Apr 1 2020 70-joystick.rules -rw-r--r-- 1 root root 734 Apr 1 2020 70-mouse.rules -rw-r--r-- 1 root root 172 Feb 21 2019 70-pcspkr-beep.rules -rw-r--r-- 1 root root 568 Apr 1 2020 70-power-switch.rules -rw-r--r-- 1 root root 429 Nov 3 2020 70-printers.rules -rw-r--r-- 1 root root 473 Apr 1 2020 70-touchpad.rules -rw-r--r-- 1 root root 3.9K Jul 13 2019 70-u2f.rules -rw-r--r-- 1 root root 2.8K Aug 31 11:27 70-uaccess.rules -rw-r--r-- 1 root root 461 Aug 31 11:27 71-power-switch-proliant.rules -rw-r--r-- 1 root root 3.7K Aug 31 11:27 71-seat.rules -rw-r--r-- 1 root root 437 Mar 16 2022 71-u-d-c-gpu-detection.rules -rw-r--r-- 1 root root 636 Aug 31 11:27 73-seat-late.rules -rw-r--r-- 1 root root 969 Aug 30 04:40 73-special-net-names.rules -rw-r--r-- 1 root root 452 Apr 1 2020 75-net-description.rules -rw-r--r-- 1 root root 174 Apr 1 2020 75-probe_mtd.rules -rw-r--r-- 1 root root 936 Apr 8 2022 77-mm-broadmobi-port-types.rules -rw-r--r-- 1 root root 3.7K Apr 8 2022 77-mm-cinterion-port-types.rules -rw-r--r-- 1 root root 1.8K Apr 8 2022 77-mm-dell-port-types.rules -rw-r--r-- 1 root root 866 Apr 8 2022 77-mm-dlink-port-types.rules -rw-r--r-- 1 root root 7.9K Apr 8 2022 77-mm-ericsson-mbm.rules -rw-r--r-- 1 root root 3.1K Apr 8 2022 77-mm-fibocom-port-types.rules -rw-r--r-- 1 root root 1.6K Apr 8 2022 77-mm-foxconn-port-types.rules -rw-r--r-- 1 root root 907 Apr 8 2022 77-mm-gosuncn-port-types.rules -rw-r--r-- 1 root root 525 Apr 8 2022 77-mm-haier-port-types.rules -rw-r--r-- 1 root root 2.5K Apr 8 2022 77-mm-huawei-net-port-types.rules -rw-r--r-- 1 root root 15K Apr 8 2022 77-mm-longcheer-port-types.rules -rw-r--r-- 1 root root 3.3K Apr 8 2022 77-mm-mtk-port-types.rules -rw-r--r-- 1 root root 2.2K Apr 8 2022 77-mm-nokia-port-types.rules -rw-r--r-- 1 root root 1.6K Apr 8 2022 77-mm-qcom-soc.rules -rw-r--r-- 1 root root 3.1K Oct 12 2021 77-mm-qdl-device-blacklist.rules -rw-r--r-- 1 root root 4.4K Apr 8 2022 77-mm-quectel-port-types.rules -rw-r--r-- 1 root root 1.6K Apr 8 2022 77-mm-sierra.rules -rw-r--r-- 1 root root 3.8K Apr 8 2022 77-mm-simtech-port-types.rules -rw-r--r-- 1 root root 9.2K Apr 8 2022 77-mm-telit-port-types.rules -rw-r--r-- 1 root root 739 Apr 8 2022 77-mm-tplink-port-types.rules -rw-r--r-- 1 root root 4.2K Apr 8 2022 77-mm-ublox-port-types.rules -rw-r--r-- 1 root root 4.5K Apr 8 2022 77-mm-x22x-port-types.rules -rw-r--r-- 1 root root 17K Apr 8 2022 77-mm-zte-port-types.rules -rw-r--r-- 1 root root 965 Aug 31 11:27 78-graphics-card.rules -rw-r--r-- 1 root root 4.8K Apr 1 2020 78-sound-card.rules -rw-r--r-- 1 root root 1.4K Aug 31 11:27 80-debian-compat.rules -rw-r--r-- 1 root root 615 Apr 1 2020 80-drivers.rules -rw-r--r-- 1 root root 190 Jan 28 2019 80-ifupdown.rules -rw-r--r-- 1 root root 1.3K Mar 31 2022 80-iio-sensor-proxy.rules -rw-r--r-- 1 root root 211 Apr 14 2022 80-libinput-device-groups.rules -rw-r--r-- 1 root root 2.1K Apr 8 2022 80-mm-candidate.rules -rw-r--r-- 1 root root 295 Aug 31 11:27 80-net-setup-link.rules -rw-r--r-- 1 root root 11K Sep 5 2021 80-udisks2.rules -rw-r--r-- 1 root root 528 Aug 31 11:27 81-net-dhcp.rules -rw-r--r-- 1 root root 528 Nov 26 2021 84-nm-drivers.rules -rw-r--r-- 1 root root 11K Mar 3 2020 85-brltty.rules -rw-r--r-- 1 root root 82 Aug 21 2019 85-hdparm.rules -rw-r--r-- 1 root root 1.9K Jan 30 2020 85-hplj10xx.rules -rw-r--r-- 1 root root 1.7K Nov 26 2021 85-nm-unmanaged.rules -rw-r--r-- 1 root root 221 Feb 5 2018 85-regulatory.rules -rw-r--r-- 1 root root 563 Apr 14 2021 90-alsa-restore.rules -rw-r--r-- 1 root root 350 Dec 1 2020 90-bolt.rules -rw-r--r-- 1 root root 265 Apr 23 2019 90-console-setup.rules -rw-r--r-- 1 root root 281 Jul 2 23:18 90-fwupd-devices.rules -rw-r--r-- 1 root root 1.9K Sep 25 2019 90-libgpod.rules -rw-r--r-- 1 root root 1.1K Apr 14 2022 90-libinput-fuzz-override.rules -rw-r--r-- 1 root root 576 Nov 26 2021 90-nm-thunderbolt.rules -rw-r--r-- 1 root root 9.2K Nov 19 2021 90-pulseaudio.rules -rw-r--r-- 1 root root 847 Mar 8 2019 95-cd-devices.rules -rw-r--r-- 1 root root 479 Feb 13 2020 95-dm-notify.rules -rw-r--r-- 1 root root 1.4K Apr 6 2020 95-kpartx.rules -rw-r--r-- 1 root root 1.6K Dec 10 2019 95-upower-csr.rules -rw-r--r-- 1 root root 570 Dec 10 2019 95-upower-hidpp.rules -rw-r--r-- 1 root root 8.0K Dec 10 2019 95-upower-hid.rules -rw-r--r-- 1 root root 354 Dec 10 2019 95-upower-wup.rules -rw-r--r-- 1 root root 171 Jun 1 20:59 96-e2scrub.rules -rw-r--r-- 1 root root 372 Jan 5 2020 97-dmraid.rules -rw-r--r-- 1 root root 1.5K Jun 8 07:09 97-hid2hci.rules -rw-r--r-- 1 root root 4.7K Aug 31 11:27 99-systemd.rules joey@HAVEN-E6520:~$ ls /etc/udev/rules.d total 112K -rwxr-xr-x 1 root root 1.9K May 12 2020 40-libsane.rules -rw-r--r-- 1 root root 921 May 12 2020 56-hpmud.rules -rw-r--r-- 1 root root 62K Jun 7 22:42 70-snap.core.rules -rw-r--r-- 1 root root 1011 Jun 7 22:42 70-snap.freecell-solitaire.rules -rw-r--r-- 1 root root 2.6K Jun 7 22:42 70-snap.keepassxc.rules -rw-r--r-- 1 root root 941 Jun 7 22:42 70-snap.motioneye.rules -rw-r--r-- 1 root root 1.4K Jun 7 22:42 70-snap.mysql-workbench-community.rules -rw-r--r-- 1 root root 1.2K Jun 7 22:42 70-snap.notepadqq.rules -rw-r--r-- 1 root root 935 Jun 7 22:42 70-snap.skype.rules -rw-r--r-- 1 root root 935 Jun 7 22:42 70-snap.slack.rules -rw-r--r-- 1 root root 885 Jun 7 22:42 70-snap.spotify.rules -rw-r--r-- 1 root root 989 Jun 7 22:42 70-snap.vlc.rules -rwxr-xr-x 1 root root 1.9K May 12 2020 S99-2000S1.rules
I created my Udev rule in the “/etc/udev/rules.d” directory. The next step was to identify the USB drive when connected. The command “udevadm” is used to determine this. The important parts of the command’s output are highlighted below.
joey@HAVEN-E6520:~$ udevadm monitor --kernel --property --subsystem-match=usb monitor will print the received events for: KERNEL - the kernel uevent KERNEL[687713.585492] add /devices/pci0000:00/0000:00:1d.0/usb2/2-1/2-1.4 (usb) ACTION=add DEVPATH=/devices/pci0000:00/0000:00:1d.0/usb2/2-1/2-1.4 SUBSYSTEM=usb DEVNAME=/dev/bus/usb/002/013 DEVTYPE=usb_device NOTE: THIS IS THE DEVICE PRODUCT=152d/562/3 TYPE=0/0/0 BUSNUM=002 DEVNUM=013 SEQNUM=75152 MAJOR=189 MINOR=140 KERNEL[687713.586155] add /devices/pci0000:00/0000:00:1d.0/usb2/2-1/2-1.4/2-1.4:1.0 (usb) ACTION=add DEVPATH=/devices/pci0000:00/0000:00:1d.0/usb2/2-1/2-1.4/2-1.4:1.0 SUBSYSTEM=usb DEVTYPE=usb_interface NOTE: THIS IS THE INTERFACE PRODUCT=152d/562/3 TYPE=0/0/0 INTERFACE=8/6/80 MODALIAS=usb:v152Dp0562d0003dc00dsc00dp00ic08isc06ip50in00 SEQNUM=75153 KERNEL[687713.587040] bind /devices/pci0000:00/0000:00:1d.0/usb2/2-1/2-1.4/2-1.4:1.0 (usb) ACTION=bind DEVPATH=/devices/pci0000:00/0000:00:1d.0/usb2/2-1/2-1.4/2-1.4:1.0 SUBSYSTEM=usb DEVTYPE=usb_interface DRIVER=uas PRODUCT=152d/562/3 TYPE=0/0/0 INTERFACE=8/6/98 MODALIAS=usb:v152Dp0562d0003dc00dsc00dp00ic08isc06ip62in00 SEQNUM=75156 KERNEL[687713.587110] bind /devices/pci0000:00/0000:00:1d.0/usb2/2-1/2-1.4 (usb) ACTION=bind DEVPATH=/devices/pci0000:00/0000:00:1d.0/usb2/2-1/2-1.4 SUBSYSTEM=usb DEVNAME=/dev/bus/usb/002/013 DEVTYPE=usb_device DRIVER=usb PRODUCT=152d/562/3 TYPE=0/0/0 BUSNUM=002 DEVNUM=013 SEQNUM=75157 MAJOR=189 MINOR=140
The next step was to create a Udev rule. Udev rules are processed in order. Therefore, I named mine starting with “99” to make sure it is one of the last rules to run. I also named the rule something descriptive and specific to the device attached.
sudo nano /etc/udev/rules.d/99-usbdrive-fantom6.rules
This rule only needs a single line to execute a script.
ACTION=="add", SUBSYSTEM=="usb", ENV{DEVTYPE}=="usb_device", ENV{PRODUCT}=="152d/562/3", RUN+="/home/joey/Scripts/udev.sh 1> /dev/null"
Conditions for UDEV rule:
- ACTION==”add” match if device added (not removed)
- SUBSYSTEM==”usb” match if subsystem is “usb”
- ENV{DEVTYPE}==”usb_device” match if devtype is “usb_device” (not :usb_interface”) – without this the script ran twice
- ENV{PRODUCT}==”152d/562/3″ match if product is “152d/562/3”
What to do if conditions match:
- RUN+=”/home/joey/Scripts/udev.sh” – command needs to be quick else drive will not mount
It appears the action performed by the rule needs to be quick. I initially tried running the backup script from the rule but, the drive would not mount. I determined it would only mount after the rule completed.
The rule runs the following script that essentially does just one thing: schedule the execution of another script that does the backup. However, some extra commands are run to log results and display a notification on the screen.
#!/bin/bash
LOGFILE='/home/joey/script.log'
echo "$(date)|INFO|Starting script: udev.sh" >> "$LOGFILE"
# https://stackoverflow.com/questions/28195805/running-notify-send-as-root
function notify-send() {
#Detect the name of the display in use
local display=":$(ls /tmp/.X11-unix/* | sed 's#/tmp/.X11-unix/X##' | head -n 1)"
#Detect the user using such display
local user=$(who | grep '('$display')' | awk '{print $1}' | head -n 1)
#Detect the id of the user
local uid=$(id -u $user)
sudo -u $user DISPLAY=$display DBUS_SESSION_BUS_ADDRESS=unix:path=/run/user/$uid/bus notify-send "$@"
}
# send notification
notify-send "External Harddrive Detected" "Fantom external drive has been detected. A backup will be started soon." -t 0 -u Normal -i /usr/share/icons/gnome/48x48/devices/drive-multidisk.png
# schedule a backup
echo "sudo -u joey /home/joey/Scripts/backup_e6520.sh" | at now + 1 minute
With this script and the Udev rule in-place the execution of a backup script is scheduled and the following notification pops-up when the USB drive is connected.
About one minute after plugging in the external drive the following backup script is executed and another pop-up notification is displayed.
#!/bin/bash
# Backup Dell E6520 laptop to Fantom "F6" external harddrive
# Run from via cron (NOT USED):
# /home/joey/Scripts/backup_e6520.sh
# ---------- copy ----------
# Backup Dropbox at 1AM each day
# * 1 * * * /home/joey/Scripts/backup_e6520.sh 1> /dev/null
# ---------- copy ----------
# save and change IFS
OLDIFS=$IFS
IFS=$'\n'
RUNDATE=`date +%Y%m%d` # append date to file
LOGFILE='/home/joey/script.log'
LOCKFILE="/home/joey/Temp/backup_e6520.lock"
#SCRIPT=`basename "$0"` # get name of this script
SCRIPT='/home/joey/Scripts/backup_e6520.sh'
TARGETDIR="/media/joey/F6/Backups/Laptop E6520/$RUNDATE"
TITLE_BACKUP_START='Backup Started'
MESSAGE_BACKUP_START='Starting backup of the laptop to the Fantom external hard drive.'
TITLE_BACKUP_DONE='Backup Completed'
MESSAGE_BACKUP_DONE='Backup of the laptop to the Fantom external hard drive has completed.'
TITLE_BACKUP_WARN='Backup Failed'
MESSAGE_BACKUP_WARN='Backup of the laptop to the Fantom external hard drive has failed. Check the script log.'
# function to allow notifications to logged-in user
function notify-send() {
#Detect the name of the display in use
local display=":$(ls /tmp/.X11-unix/* | sed 's#/tmp/.X11-unix/X##' | head -n 1)"
#Detect the user using such display
local user=$(who | grep '('$display')' | awk '{print $1}' | head -n 1)
#Detect the id of the user
local uid=$(id -u $user)
sudo -u $user DISPLAY=$display DBUS_SESSION_BUS_ADDRESS=unix:path=/run/user/$uid/bus notify-send "$@"
}
echo -------------------------------------------------------------------------- | tee -a "$LOGFILE"
echo "$(date)|INFO|Starting script: $SCRIPT" >> "$LOGFILE"
echo "Starting script: `date`"
# send notification
notify-send "$TITLE_BACKUP_START" "$MESSAGE_BACKUP_START" -t 0 -u Normal -i /usr/share/icons/gnome/48x48/status/network-transmit.png
# if lock file exists something is wrong - abort
if [ -f "$LOCKFILE" ]; then
# lock file exists
echo "$(date)|ERROR|Lock file exists. Aborting." >> "$LOGFILE"
echo "Error: lock file exists."
echo "Note: this script is run automatically when the USB hard drive is plugged in and may be running."
# send notification
notify-send "$TITLE_BACKUP_WARN" "$MESSAGE_BACKUP_WARN" -t 0 -u Normal -i /usr/share/icons/gnome/48x48/status/dialog-warning.png
else
echo "$(date)|INFO|Lock file not found. Continuing." >> "$LOGFILE"
# wait for USB drive to be mounted
#sleep 30
# check if backup folder already exists (if so abort)
if [ -d "$TARGETDIR" ]; then
# backup folder exists, abort
echo "$(date)|ERROR|Backup folder exists. Aborting." >> "$LOGFILE"
echo "Error: backup folder already exists. A backup has already been run."
# send notification
notify-send "$TITLE_BACKUP_WARN" "$MESSAGE_BACKUP_WARN" -t 0 -u Normal -i /usr/share/icons/gnome/48x48/status/dialog-warning.png
else
#echo "Backup started: `date`" | tee -a "$LOGFILE"
echo "$(date)|INFO|Backup started: `date`" >> "$LOGFILE"
echo "Starting backup."
# create lock file
echo 'This file should not exist for more than a few hours.' > "$LOCKFILE"
# Create an array to hold directories to backup
declare -a DIRARRAY
DIRARRAY+=('/home/joey/Desktop')
DIRARRAY+=('/home/joey/Documents')
DIRARRAY+=('/home/joey/Development')
DIRARRAY+=('/home/joey/Pictures')
DIRARRAY+=('/home/joey/Scripts')
DIRARRAY+=('/home/joey/mame')
DIRARRAY+=('/home/joey/Streams')
DIRARRAY+=('/home/joey/websites')
DIRARRAY+=('/home/joey/Temp')
DIRARRAY+=('/home/joey/Videos')
DIRARRAY+=('/home/joey/Downloads')
DIRARRAY+=("/media/joey/SD Card/Dropbox/Dropbox")
# Test: dump array
#echo ${DIRARRAY[@]}
# Create new backup destination folder
mkdir "$TARGETDIR"
#echo Backing-up folders to: "$TARGETDIR" | tee -a "$LOGFILE"
echo "$(date)|INFO|Backing-up files to: $TARGETDIR" >> "$LOGFILE"
echo "Backing-up files to: $TARGETDIR"
# Backup each folder to a separate archive
for i in ${DIRARRAY[@]}
do
#echo Processing folder: $i | tee -a "$LOGFILE"
echo "$(date)|INFO|Processing folder: $i" >> "$LOGFILE"
echo "Processing folder: $i"
SOURCEDIR=$i # full path of folder to archive
THISDIR=${i##*/} # last name of folder in path
FILENAME=$THISDIR.tar.gz # name of backup file
# strip leading slash off source directory path
SOURCEDIR=${SOURCEDIR#/}
# run archive command
tar -C / -cpzf $TARGETDIR/$FILENAME $SOURCEDIR
done
# Delete array
unset DIRARRAY
# delete lockfile
echo "$(date)|INFO|Deleting lock file" >> "$LOGFILE"
rm $LOCKFILE
# send notification
notify-send "$TITLE_BACKUP_DONE" "$MESSAGE_BACKUP_DONE" -t 0 -u Normal -i /usr/share/icons/gnome/48x48/status/network-transmit.png
fi # check if backup folder exists
# END PROCESSING
fi # check if lock file exists
echo "$(date)|INFO|Processing complete. Restoring file system separator" >> "$LOGFILE"
# restore IFS
IFS=$OLDIFS
echo "$(date)|INFO|Exiting script" >> "$LOGFILE"
echo "Exiting script: `date`"
echo -------------------------------------------------------------------------- | tee -a "$LOGFILE"
exit
When the backup script is executed at the scheduled time the following notification is displayed and files start writing to the external hard drive.
When the backup is complete a final notification is displayed letting me know I can disconnect the hard drive. In this example, the backup script does not un-mount the USB drive. I leave it mounted so I can review the files backed-up.
If, when the backup script is executed, it detects an error (like a lock file indicating a backup is already taking place) it will not backup any files and display a notification of the error.
Troubleshooting
-
USB drive not mounting when plugged in.
Check for an error in the Udev rule or the script that the rule fires off that is preventing the rule from finishing. It appears that no other rules that would’ve executed for this device will not run until yours completes – even if it is the last one.
-
Notifications sent in backup script not displayed.
This is because udev.sh is run as root and submits the backup job also as root. So, when the backup script is running it is not running as you (or another user). This is discussed in this thread o Stack Overflow: https://stackoverflow.com/questions/28195805/running-notify-send-as-root
-
Monitor syslog for events.
In another terminal window run the following to monitor the events taking place and scripts being executed: sudo tail -f /var/log/syslog
I had to install the “AT” command utility and could not find a way to script a job with “cron”. It may be possible to schedule the backup script using Systemd timers or some other mechanism. TBH Systemd is still new to me and I tend to fallback on old tried-and-true ways even if they are more expensive in time or resources.
Resources
https://www.thegeekdiary.com/how-to-run-a-script-when-usb-devices-is-attached-or-removed-using-udev/
http://migueleonardortiz.com.ar/udev/running-bash-scripts-using-udev-rules/1505
https://linuxconfig.org/tutorial-on-how-to-write-basic-udev-rules-in-linux
Mount Veracrypt volumes Linux script
In Veracrypt you can save mounted volumes as favorites which makes it easier to mount those volumes when starting Veracrypt. Although the container and mount path are saved you still need to enter the volume’s password and key if needed for each volume being mounted. On top of that, when using Linux you’ll be prompted to enter your Linux account password for sudo. With several volumes to mount this can be time-consuming and cumbersome.
Fortunately, Veracrypt includes the ability to manage encrypted volumes from the command-line. You can supply the password and key to mount the volumes on the commannd-line in the terminal. You can put these commands in a script to mount multiple volumes. Running from script will allow you to mount several volumes and only have to enter your Linux password for sudo once. However, putting passwords in scripts is a big security risk.
A better way is to have the script prompt for the password. The following script will mount multiple volumes and only prompt for the password one time. To make this work I set the password for the Veracrypt volumes the same as my Linux system password. The script will pass the sudo password (which is the same as the Veracrypt password) to the Veracrypt command satisfying the sudo prompt.
#!/bin/bash
# Mount/unmount Veracrypt (Truecrypt) volumes on Dell laptop
# v2 - Check for mounted volumes and unmount if found. Otherwise mount volumes.
# save and change IFS
OLDIFS=$IFS
IFS=$'\n'
RUNDATE=`date +%Y%m%d` # append date to file
LOGFILE='/home/joey/script.log'
LOCKFILE='/home/joey/Temp/veracrypt.lock' # file to indicate volumes should be mounted
SCRIPT=`basename "$0"` # get name of this script
echo -------------------------------------------------------------------------- | tee -a "$LOGFILE"
echo "Executing script: $SCRIPT" | tee -a "$LOGFILE"
# prompt for password
echo "Enter Password (not echoed): "
read -s PASSWORD
echo "NOTE: If prompted to enter 'Administrator' password, ignore it."
# Check for lock file. If exists unmount volumes else mount volumes
if [ -f $LOCKFILE ]; then
echo "Lock file found." | tee -a "$LOGFILE"
echo "Attempting to un-mount Veracrypt volumes" | tee -a "$LOGFILE"
# Unmount Veracrypt volumes
veracrypt --text --dismount
# Display system notification
notify-send "Veracrypt" "Veracrypt volumes unmounted." -t 0 -u Normal -i /usr/share/icons/mate/48x48/status/changes-prevent.png
# Remove lock file
rm $LOCKFILE
else
echo "Attempting to mount Veracrypt volumes" | tee -a "$LOGFILE"
# PUT KEYLESS VOLUMES FIRST
# Volume 2
VCSLOT=2
VCVOLUME=/home/joey/e6ef0971-7801-442f-9f6c-f3f945922efb
VCMOUNT=/media/veracrypt2
VCPASSWD=$PASSWORD
VCKEYFIL=
echo "Mounting volume $VCVOLUME to mount point $VCMOUNT" | tee -a "$LOGFILE"
echo $PASSWORD | veracrypt --text --mount $VCVOLUME $VCMOUNT --password $VCPASSWD --pim 0 --keyfiles "$VCKEY" --protect-hidden no --slot $VCSLOT --verbose
# Volume 1 - requires key
VCSLOT=1
VCVOLUME=/home/joey/3c1547fa-1ad3-11eb-adc1-0242ac120002
VCMOUNT=/media/veracrypt1
VCPASSWD=$PASSWORD
VCKEY=/home/joey/.safe/3c1547fa-1ad3-11eb-adc1-0242ac120002.key
echo "Mounting volume $VCVOLUME to mount point $VCMOUNT" | tee -a "$LOGFILE"
echo $PASSWORD | veracrypt --text --mount $VCVOLUME $VCMOUNT --password $VCPASSWD --pim 0 --keyfiles "$VCKEY" --protect-hidden no --slot $VCSLOT --verbose
# List volumes
echo "Mounted Veracrypt volumes:" | tee -a "$LOGFILE"
echo $PASSWORD | veracrypt --text --list | tee -a "$LOGFILE"
# Display system notification
notify-send "Veracrypt" "Veracrypt volumes mounted." -t 0 -u Normal -i /usr/share/icons/mate/48x48/status/changes-prevent.png
# Create lock file
echo $(date) > $LOCKFILE
fi
# restore IFS
IFS=$OLDIFS
echo "Script completed: `date`" | tee -a "$LOGFILE"
echo -------------------------------------------------------------------------- | tee -a "$LOGFILE"
When the above script is run in terminal it prompts for the password and using “tee” outputs log entries to the screen and a file.
joey@HAVEN-E6520:~$ Scripts/veracrypt.v2.sh -------------------------------------------------------------------------- Executing script: veracrypt.v2.sh Enter Password (not echoed): NOTE: If prompted to enter 'Administrator' password, ignore it. Attempting to mount Veracrypt volumes Mounting volume /home/joey/e6ef0971-7801-442f-9f6c-f3f945922efb to mount point /media/veracrypt2 Volume "/home/joey/e6ef0971-7801-442f-9f6c-f3f945922efb" has been mounted. Mounting volume /home/joey/3c1547fa-1ad3-11eb-adc1-0242ac120002 to mount point /media/veracrypt1 Volume "/home/joey/3c1547fa-1ad3-11eb-adc1-0242ac120002" has been mounted. Mounted Veracrypt volumes: 2: /home/joey/e6ef0971-7801-442f-9f6c-f3f945922efb /dev/mapper/veracrypt2 /media/veracrypt2 1: /home/joey/3c1547fa-1ad3-11eb-adc1-0242ac120002 /dev/mapper/veracrypt1 /media/veracrypt1 Script completed: Mon 12 Sep 2022 12:33:50 AM EDT -------------------------------------------------------------------------- joey@HAVEN-E6520:~$
Running the script again causes it to dismount the volumes.
joey@HAVEN-E6520:~$ Scripts/veracrypt.v2.sh -------------------------------------------------------------------------- Executing script: veracrypt.v2.sh Enter Password (not echoed): NOTE: If prompted to enter 'Administrator' password, ignore it. Lock file found. Attempting to un-mount Veracrypt volumes Script completed: Mon 12 Sep 2022 12:34:04 AM EDT -------------------------------------------------------------------------- joey@HAVEN-E6520:~$
Resources
https://linuxhint.com/how-to-install-and-use-veracrypt-on-ubuntu/
https://arcanecode.com/2021/06/14/veracrypt-on-the-command-line-for-windows/
Upgrade LibreOffice 7.3.2.2 on Linux Mint
# tip: cache password with "sudo ls"
# uninstall currently installed version
sudo apt-get remove libreoffice*
sudo apt-get remove --purge libreoffice*
# download and install LibreOffice
cd ~/Install
wget https://download.documentfoundation.org/libreoffice/stable/7.3.2/deb/x86_64/LibreOffice_7.3.2_Linux_x86-64_deb.tar.gz
tar -xvzf LibreOffice_7.3.2_Linux_x86-64_deb.tar.gz
cd LibreOffice_7.3.2.2_Linux_x86-64_deb/DEBS
sudo dpkg -i *.deb
# download and install offline help files
cd ~/Install
wget https://download.documentfoundation.org/libreoffice/stable/7.3.2/deb/x86_64/LibreOffice_7.3.2_Linux_x86-64_deb_helppack_en-US.tar.gz
tar -xvzf LibreOffice_7.3.2_Linux_x86-64_deb_helppack_en-US.tar.gz
cd LibreOffice_7.3.2.2_Linux_x86-64_deb_helppack_en-US/DEBS
sudo dpkg -i *.deb
# delete extracted installation files
cd ~/Install
rm -rf ~/Install/LibreOffice_7.3.2.2_Linux_x86-64_deb
rm -rf ~/Install/LibreOffice_7.3.2.2_Linux_x86-64_deb_helppack_en-US
Upgrade LibreOffice 7.1.5.2 on Linux Mint
Commands to install LibreOffice 7.1.5.2 from the Terminal in Linux Mint. Get link to most recent version from https://download.documentfoundation.org/libreoffice/stable/
# tip: cache password with "sudo ls"
# uninstall currently installed version
sudo apt-get remove libreoffice-*
sudo apt-get remove --purge libreoffice-*
# download and install LibreOffice
cd ~/Install
wget https://download.documentfoundation.org/libreoffice/stable/7.1.5/deb/x86_64/LibreOffice_7.1.5_Linux_x86-64_deb.tar.gz
tar -xvzf LibreOffice_7.1.5_Linux_x86-64_deb.tar.gz
cd LibreOffice_7.1.5.2_Linux_x86-64_deb/DEBS
sudo dpkg -i *.deb
# download and install offline help files
cd ~/Install
wget https://download.documentfoundation.org/libreoffice/stable/7.1.5/deb/x86_64/LibreOffice_7.1.5_Linux_x86-64_deb_helppack_en-US.tar.gz
tar -xvzf LibreOffice_7.1.5_Linux_x86-64_deb_helppack_en-US.tar.gz
cd LibreOffice_7.1.5.2_Linux_x86-64_deb_helppack_en-US/DEBS
sudo dpkg -i *.deb
# delete extracted installation files
cd ~/Install
rm -rf ~/Install/LibreOffice_7.1.5.2_Linux_x86-64_deb
rm -rf ~/Install/LibreOffice_7.1.5.2_Linux_x86-64_deb_helppack_en-US
Upgrade LibreOffice 7.1.2.2 on Linux Mint
Commands to install LibreOffice 7.1.2.2 from the Terminal in Linux Mint. Get link to most recent version from https://download.documentfoundation.org/libreoffice/stable/
# tip: cache password with "sudo ls"
# uninstall currently installed version
sudo apt-get remove libreoffice-*
sudo apt-get remove --purge libreoffice-*
# download and install LibreOffice
cd ~/Install
wget https://download.documentfoundation.org/libreoffice/stable/7.1.2/deb/x86_64/LibreOffice_7.1.2_Linux_x86-64_deb.tar.gz
tar -xvzf LibreOffice_7.1.2_Linux_x86-64_deb.tar.gz
cd LibreOffice_7.1.2.2_Linux_x86-64_deb/DEBS
sudo dpkg -i *.deb
# download and install offline help files
cd ~/Install
wget https://download.documentfoundation.org/libreoffice/stable/7.1.2/deb/x86_64/LibreOffice_7.1.2_Linux_x86-64_deb_helppack_en-US.tar.gz
tar -xvzf LibreOffice_7.1.2_Linux_x86-64_deb_helppack_en-US.tar.gz
cd LibreOffice_7.1.2.2_Linux_x86-64_deb_helppack_en-US/DEBS
sudo dpkg -i *.deb
# delete extracted installation files
cd ~/Install
rm -rf ~/Install/LibreOffice_7.1.2.2_Linux_x86-64_deb/DEBS
rm -rf ~/Install/LibreOffice_7.1.2.2_Linux_x86-64_deb_helppack_en-US
Upgrade LibreOffice 6.4.5.2 on Linux Mint
Commands to install LibreOffice 6.4.5.2 from the Terminal in Linux Mint. Get link to most recent version from https://www.libreoffice.org/download/
# tip: cache password with "sudo ls"
# uninstall currently installed version
sudo apt-get remove libreoffice-*
sudo apt-get remove --purge libreoffice-*
# download and install LibreOffice
cd ~/Install
wget https://download.documentfoundation.org/libreoffice/stable/6.4.5/deb/x86_64/LibreOffice_6.4.5_Linux_x86-64_deb.tar.gz
tar -xvzf LibreOffice_6.4.5_Linux_x86-64_deb.tar.gz
cd LibreOffice_6.4.5.2_Linux_x86-64_deb/DEBS
sudo dpkg -i *.deb
# download and install offline help files
cd ~/Install
wget https://download.documentfoundation.org/libreoffice/stable/6.4.5/deb/x86_64/LibreOffice_6.4.5_Linux_x86-64_deb_helppack_en-US.tar.gz
tar -xvzf LibreOffice_6.4.5_Linux_x86-64_deb_helppack_en-US.tar.gz
cd LibreOffice_6.4.5.2_Linux_x86-64_deb_helppack_en-US/DEBS
sudo dpkg -i *.deb
# delete extracted installation files
rm -rf ~/Install/LibreOffice_6.4.5.2_Linux_x86-64_deb
rm -rf ~/Install/LibreOffice_6.4.5.2_Linux_x86-64_deb_helppack_en-US
Copy filename and path from Office
You can copy to the clipboard the full filename, including the path, of the current document in Microsoft Office applications. This is helpful in increasing productivity since you do not have to open Windows Explorer then hunt down your file and copy the path from there (by holding down the SHIFT key – even MORE work!!)
In the Office application, in this case Excel, click on the File tab:
In the Info section the document name is displayed with the document’s location displayed right below it. This line is clickable. When clicked on you get the option to copy the link location to the clipboard:
Upgrade LibreOffice 6.2.5.2 on Linux Mint
Commands to install LibreOffice 6.2.5.2 from the Terminal in Linux Mint. Get link to most recent version from https://www.libreoffice.org/download/
# tip: cache password with "sudo ls"
# uninstall currently installed version
sudo apt-get remove libreoffice-*
sudo apt-get remove --purge libreoffice-*
# download and install LibreOffice
cd ~/Install
wget https://download.documentfoundation.org/libreoffice/stable/6.2.5/deb/x86_64/LibreOffice_6.2.5_Linux_x86-64_deb.tar.gz
tar -xvzf LibreOffice_6.2.5_Linux_x86-64_deb.tar.gz
cd LibreOffice_6.2.5.2_Linux_x86-64_deb/DEBS
sudo dpkg -i *.deb
# download and install offline help files
cd ~/Install
wget http://download.documentfoundation.org/libreoffice/stable/6.2.5/deb/x86_64/LibreOffice_6.2.5_Linux_x86-64_deb_helppack_en-US.tar.gz
tar -xvzf LibreOffice_6.2.5_Linux_x86-64_deb_helppack_en-US.tar.gz
cd LibreOffice_6.2.5.2_Linux_x86-64_deb_helppack_en-US/DEBS
sudo dpkg -i *.deb
# delete extracted installation files
rm -rf ~/Install/LibreOffice_6.2.5.2_Linux_x86-64_deb
rm -rf ~/Install/LibreOffice_6.2.5.2_Linux_x86-64_deb_helppack_en-US
Get ShoreTel Agents Using Powershell
The Powershell script below can be used to quickly get the number of Shoretel Workgroup agents currently logged-in to take calls. Save the code to .ps1 file.
Add-Type -Path "C:\Program Files (x86)\MySQL\MySQL Connector Net 6.10.8\Assemblies\v4.5.2\MySql.Data.dll"
$Connection = [MySql.Data.MySqlClient.MySqlConnection]@{ConnectionString='server=172.18.1.10;port=4308;uid=st_configread;pwd=passwordconfigread;database=shoreware'}
$Connection.Open()
$MYSQLCommand = New-Object MySql.Data.MySqlClient.MySqlCommand
$MYSQLDataAdapter = New-Object MySql.Data.MySqlClient.MySqlDataAdapter
$MYSQLDataSet = New-Object System.Data.DataSet
$MYSQLCommand.Connection=$Connection
$MYSQLCommand.CommandText='SELECT COUNT(UserDN) AS ''ActiveAgents'' FROM shoreware.workgroupagents WHERE AgentStateID not in (0);'
$MYSQLDataAdapter.SelectCommand=$MYSQLCommand
$NumberOfDataSets=$MYSQLDataAdapter.Fill($MYSQLDataSet, 'data')
foreach($DataSet in $MYSQLDataSet.tables[0])
{
$ActiveAgents = $DataSet.ActiveAgents
}
$Connection.Close()
echo "`n`nTOTAL LOGGED IN AGENTS: $ActiveAgents`n`n"
When executed the script will return the number of agents logged-in similar to this:
Note: the MySQL .NET connector for the version of MySQL server running on your ShoreTel server must be installed on the workstation running the script.
Resources:
http://www.systemadept.com/2017/07/12/querying-mysql-databases-from-powershell/?i=1
https://www.quadrotech-it.com/blog/querying-mysql-from-powershell
Add Exchange account to Outlook Mail App
Microsoft has updated the Outlook Mail App (at least for Android) and broke the connection for Exchange accounts. If you already had an Exchange account you’ll likely find it no-longer synchronizes with Exchange.
Furthermore, if you attmept to delete and re-add the account you’ll find you cannot select a type of account to add (or so it seems).
You can still use the Outlook app to check Exchange mailboxes. You just have to know the trick!
- Tap the Gear icon to open the Settings window:
- Tap Add Account:
- Then select Add an email account at bottom of screen:
- The app will automatically find accounts on the device and select them to add. Unselect the accounts you don’t want added and then tap Add Account at bottom of screen:
- At this point the app will prompt for an email address. It will use this to create an IMAP account (we don’t want this). Enter email address and tap Continue
- Here is the trick! Tap the ? icon:
- At the bottom of the screen will be additional options. Tap Change account provider:
- Now, you can tap Exchange to create an Exchange account:
- You’ll likely need to enter additional information like server name, domain, etc. To do this enable Advanced Settings:
- Enter any needed information and tap the check-mark icon
- The Outlook Mail App will attempt to connect…
- … and if successful you should be able to view your Exchange mailbox:
These screenshots came off my Kindle Fire tablet. However, the same problem was overcome on a Lenovo 10″ tablet using these instructions.
Upgrade LibreOffice on Linux Mint
Commands to install LibreOffice 6.2 from the Terminal in Linux Mint. Get link to most recent version from https://www.libreoffice.org/download/
# tip: cache password with "sudo ls"
# uninstall currently installed version
sudo apt-get remove libreoffice-core
sudo apt-get remove --purge libreoffice-core
# download and install LibreOffice
cd ~/Install
wget https://www.libreoffice.org/donate/dl/deb-x86_64/6.2.3/en-US/LibreOffice_6.2.3_Linux_x86-64_deb.tar.gz
tar -xvzf LibreOffice_6.2.3_Linux_x86-64_deb.tar.gz
cd LibreOffice_6.2.3.2_Linux_x86-64_deb/DEBS
sudo dpkg -i *.deb
# download and install offline help files
cd ~/Install
wget http://download.documentfoundation.org/libreoffice/stable/6.2.3/deb/x86_64/LibreOffice_6.2.3_Linux_x86-64_deb_helppack_en-US.tar.gz
tar -xvzf LibreOffice_6.2.3_Linux_x86-64_deb_helppack_en-US.tar.gz
cd LibreOffice_6.2.3.2_Linux_x86-64_deb_helppack_en-US/DEBS
sudo dpkg -i *.deb
# delete extracted installation files
rm -rf ~/Install/LibreOffice_6.2.3.2_Linux_x86-64_deb
rm -rf ~/Install/LibreOffice_6.2.3.2_Linux_x86-64_deb_helppack_en-US
Command-line Compression Options
A comparison of command-line options to compress files using 7-Zip and native commands in Windows and Linux.
For testing I created a Word document of Lorem Ipsum and saved it in Word and PDF formats.
Windows Command Prompt
There is no built-in Windows program able to run in a CMD prompt that does what is wanted.* However, the open-source utility 7za.exe can be copied to any Windows folder without installation and be executed from a batch file.
Command: 7z.exe a -t7z target.7z C:\source\folder\
C:\_Tools\7zip\7za.exe a -t7z C:\Temp\Zip\test.7z C:\Temp\Zip\Files\
Changing the archive type to “zip” causes 7Zip to create a slightly larger archive.
Powershell Core on Windows and Linux
Powershell Core can be installed on both Windows and Linux. The following commands will work with Windows Powershell (deprecated) and Powershell Core (open-source).
# Command syntax:
# Compress-Archive -Path C:\source\folder -DestinationPath C:\target\target.zip
Compress-Archive -Path C:\Temp\Zip\files -DestinationPath C:\Temp\Zip\powershell.zip
# Command syntax:
# Compress-Archive -Path C:\source\folder -DestinationPath C:\target\target.zip
Compress-Archive -Path /home/joey/temp/zip/files -DestinationPath /home/joey/temp/zip/powershell2.zip
Tar command on Linux and Windows 10 BASH
Linux includes the venerable “tar” command, once used to create tape-archives. Installing the Ubuntu Linux subsystem on Windows 10 brngs this feature to Windows as well.
# Command syntax:
# tar -czvf name-of-archive.tar.gz /path/to/directory-or-file
tar -czvf files.tar.gz /mnt/c/temp/zip/files/
Same command run on Linux Mint.
# Command syntax:
# tar -czvf name-of-archive.tar.gz /path/to/directory-or-file
tar -czvf files2.tar.gz /home/joey/temp/zip/files/
Bonus: Windows Compressed Folders
Just to compare how efficient Windows built-in feature is to the command-line options above.
Resources:
https://superuser.com/questions/1105516/comparing-7z-exe-and-7za-exe
* There are compression tools built-in to Windows such as compact and makecab that are not covered here.
Generate passwords using Powershell
The Powershell script below can be used to generate 20 passwords using random words and numbers. Save the code to .ps1 file along with a “words” file in .csv format.
# Generates passphrases similar to password generator on intranet
# inspired by:
# https://www.hanselman.com/blog/DictionaryPasswordGeneratorInPowershell.aspx
# requires CSV file in same directory as script
#--------------------------------------------------------------------------------------------------
$rand = new-object System.Random
# read-in very large file creating smaller list of random words
$words = Get-Content "words.csv" | Sort-Object {Get-Random} -unique | select -first 100
Function Create-Password
{
# query the smaller list of words for single entry (2 times)
$word1 = $words | Sort-Object {Get-Random} -unique | select -first 1
$word2 = $words | Sort-Object {Get-Random} -unique | select -first 1
# create random digits
$number1 = Get-Random -Minimum 1000 -Maximum 9999
# concatenante and return new random password
return (Get-Culture).TextInfo.ToTitleCase($word1) + (Get-Culture).TextInfo.ToTitleCase($word2) + $number1
}
# generate 20 passwords
for($i=1; $i -le 20; $i++){
Create-Password
}
When executed the script will return 20 random passwords similar to this:
Note: you will need a “words” file from which random words will be pulled. I already had a “words” table in a MySQL database and used it to query for words between 5 and 7 characters in length. This gave me a file with about 15,000 words.
More information about obtaining a words list can be found on the following sites:
https://github.com/dwyl/english-words
https://stackoverflow.com/questions/2213607/how-to-get-english-language-word-database
Random strings in Powershell
Powershell code to generate 20 strings of 24 random letters and numbers.
for($i=1; $i -le 20; $i++){([char[]]([char]'a'..[char]'z' + [char]'A'..[char]'Z') + 0..9 | sort {get-random})[0..23] -join ''}
This will generate strings similar to this:
Move Dropbox files on Linux Mint
I have the Dropbox client installed on my Linux Mint machine and it has worked flawlessly for years. Suddenly, I started getting a notification pop-up telling me to move my Dropbox files as they will stop being synced in November.
A quick search revealed the rather cryptic message is a result of Dropbox’s decision to stop supporting certain file systems across all operating systems. With Linux appearing to be the most impacted as they will only support Ext4 without encryption (unless whole-disk; e.g. LUKS) going forward. Of course, I running Ext4 with my Home directory encrypted.
So, after looking for alternatives I decided to stay with Dropbox and try to work-around the problem. I decided I would create a partition that Dropbox would like. Since my laptop (an old Dell 6250) has an SD card reader I rarely use I decided to use an 16GB SD card (8 times more storage than I have with Dropbox).
First, I formatted an SD card as Ext4:
Then I moved the folder location in the Dropbox client to use the new directory. The client automatically moves the file and deletes the old location folder.
Next step was to create a symlink to make the old location still work for applications/scripts that would look to the old location:
ln -s /media/joey/Sync/Dropbox /home/joey/Dropbox
The only real risk is the SD card getting corrupted and losing the files. To address this a simple bash script will backup the files each night:
#!/bin/bash
# Backup Dropbox folder to local disk
# Run from via cron:
# /home/joey/Scripts/backup_dropbox.sh
# ---------- copy ----------
# Backup Dropbox at 1AM each day
# * 1 * * * /home/joey/Scripts/backup_dropbox.sh 1> /dev/null
# ---------- copy ----------
RUNDATE=`date +%Y%m%d` # append date to file
FILENAME=Dropbox_backup-$RUNDATE.tar.gz # name of backup file
SOURCEDIR=/media/joey/Sync/Dropbox # Dropbox location (real location)
TARGETDIR=/home/joey/Backups # Destination of backup file
# run archive command
tar -cpzf $TARGETDIR/$FILENAME $SOURCEDIR
Fix broken trust using Powershell
When trying to log in to PC using a domain credential you get the following error:
“The trust relationship between this workstation and the primary domain failed” error when you log in to Windows 7
At this point I would usually re-join to the domain or run the Network Wizard, reboot, and continue on. There has to be a better way. And in-fact, there is via the Powershell command:
Reset-ComputerMachinePassword –server -credential
However, when I ran the command to reset the password I got an error stating the account could not be found on the domain controller:
PS C:\A3336> Reset-ComputerMachinePassword -server DELLR710 -credential AP\client_admin Reset-ComputerMachinePassword : Cannot find the computer account for the local computer from the domain controller DELLR710. At line:1 char:1 + Reset-ComputerMachinePassword -server DELLR710 -credential AP\client_admin ... + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + CategoryInfo : OperationStopped: (A3336:String) [Reset-ComputerMachinePassword], InvalidOperationException + FullyQualifiedErrorId : CannotFindMachineAccount,Microsoft.PowerShell.Commands.ResetComputerMachinePasswordCommand PS C:\A3336>
The fix was to create the account on the domain controller which I was able to do with Powershell on another PC that had Remote Server Administration Tools (RSAT) installed.
PS C:\AP01-1255-915> New-ADcomputer –name "A3336" –SamAccountName "A3336" -Enabled $true PS C:\AP01-1255-915>
Now when the command is run on the client PC I am prompted to enter a username and password with permission to join computers to the domain and the command completes successfully.
PS C:\A3336> Reset-ComputerMachinePassword -server DELLR710 -credential AP\client_admin PS C:\A3336>
http://implbits.com/active-directory/2012/04/13/dont-rejoin-to-fix.html
https://ss64.com/ps/reset-computermachinepassword.html
https://support.microsoft.com/en-us/help/2771040/the-trust-relationship-between-this-workstation-and-the-primary-domain
Start remote PC using WOL and Powershell
How to power-on remote PC using wake-on-lan (WOL) and Powershell. Run from a Windows 7 Pro with Powershell running with domain admin credentials.
$Mac = "f0:92:1c:e3:8f:60" $MacByteArray = $Mac -split "[:-]" | ForEach-Object { [Byte] "0x$_"} [Byte[]] $MagicPacket = (,0xFF * 6) + ($MacByteArray * 16) $UdpClient = New-Object System.Net.Sockets.UdpClient $UdpClient.Connect(([System.Net.IPAddress]::Broadcast),7) $UdpClient.Send($MagicPacket,$MagicPacket.Length) $UdpClient.Close() PS C:\Install> ping -4 -t AP01-1221-314 Pinging AP01-1221-314.AP.local [10.10.1.130] with 32 bytes of data Reply from 10.10.1.179: Destination host unreachable. Reply from 10.10.1.179: Destination host unreachable. Reply from 10.10.1.179: Destination host unreachable. Reply from 10.10.1.179: Destination host unreachable. Reply from 10.10.1.179: Destination host unreachable. Reply from 10.10.1.179: Destination host unreachable. Request timed out. Request timed out. Request timed out. Request timed out. Request timed out. Request timed out. Request timed out. Reply from 10.10.1.130: bytes=32 time=2ms TTL=128 Reply from 10.10.1.130: bytes=32 time=1ms TTL=128 Reply from 10.10.1.130: bytes=32 time=2ms TTL=128 Reply from 10.10.1.130: bytes=32 time=2ms TTL=128 Reply from 10.10.1.130: bytes=32 time=2ms TTL=128 Reply from 10.10.1.130: bytes=32 time=2ms TTL=128 Ping statistics for 10.10.1.130: Packets: Sent = 19, Received = 12, Lost = 7 (36% loss), Approximate round trip times in milli-seconds: Minimum = 1ms, Maximum = 2ms, Average = 1ms Control-C PS C:\Install>
Just change MAC address and copy and paste. Of course, WOL must be enabled on remote PC for this to work.
Note: you’ll need Remote Server Administration Tools (RSAT) installed which you can download from Microsoft:
https://support.microsoft.com/en-us/help/2693643/remote-server-administration-tools-rsat-for-windows-operating-systems