Silent (Unattended) Uninstall of Dell Command | Update


MsiExec.exe /X{EC542D5D-B608-4145-A8F7-749C02BE6D94} /quiet /norestart

I needed to silently uninstall Dell Command | Update, and a Google search for such currently doesn’t turn up anything helpful. Their user’s guide is equally unhelpful, telling me to “see the operating system documentation…for information on uninstalling programs.” Thanks, Dell.



I searched HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall in the registry for an uninstall string, but with no luck. I then searched the registry for the text “2.3.0,” the current version of Dell Command | Update, in hopes of finding the uninstall information somewhere else, since there is an option to uninstall it through the Programs and Features section of the Control Panel.



That search eventually turned up the key Computer\HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Installer\UserData\S-1-5-18\Products\D5D245CE806B54148A7F47C920EBD649\InstallProperties, where we can see MsiExec.exe /X{EC542D5D-B608-4145-A8F7-749C02BE6D94} as the uninstall string.

Running that from the command line starts the uninstaller, but not in silent mode. Running msiexec /? returns the help for this command, which tells us that adding /quiet will run in silent mode. I threw in a /norestart just for good measure.




Finally, we have the following command line command to do a silent uninstall of Dell Command | Update:

MsiExec.exe /X{EC542D5D-B608-4145-A8F7-749C02BE6D94} /quiet /norestart

Mount Synology NAS to Raspberry Pi Using NFS

Here’s the equipment I used, this should work similarly on other software versions:

  • Synology NAS Running DSM 7.0
  • Raspberry Pi running Raspbian 10 (Buster)

This tutorial is based on these instructions from Synology, with modifications because they didn’t work exactly as listed:

Enable NFS on the Synology NAS:

  1. From the Synology web interface, Go to Control Panel > File Services > NFS
  2. Check Enable NFS Service. Set Maximum NFS Protocol to NFSv4.1 and click Apply.

Create NFS Permissions:

  1. Still in the Synology web interface, go to Control Panel > Shared Folder
  2. Select the folder you want to share and click Edit
  3. Click NFS Permissions > Create
    1. Enter a hostname or IP for the Raspberry Pi that will be accessing the folder.
    2. Leave Privilege on Read / Write and leave other settings at default, and click Save.
  4. Note the Mount path at the bottom of the folder edit page, then click Save again to save the folder settings.



Mount share on the Raspberry Pi:

  1. From the terminal – install nfs if not already installed:
    1. sudo apt update
    2. sudo apt install nfs-common
  2. Create the mount directory – change the path as appropriate:
    1. sudo mkdir /mnt/share
  3. Here’s where Synology instructions didn’t work. I kept getting a timeout error when trying to mount the share. This answer helped me get on the right track.
    1. To do a one time mount to ensure everything is working – replace IP address/ hostname and paths are appropriate:
      1. sudo mount -t nfs4 -o proto=tcp,port=2049 192.168.XX.XX:/volume1/share /mnt/share
    2. To mount so it persists after a reboot (thanks to this article):
      1. sudo nano /etc/fstab
      2. Add this line to the bottom, again replacing ip addresses / hostname and file paths as needed:
        1. 192.168.XX.XX:/volume1/share /mnt/share nfs defaults 0 0
      3. Exit, save the file, and reboot the pi (sudo reboot now).
      4. Once the Pi is back up, ensure the mount worked with ls /mnt/share

PowerShell Terminal: Menu Template

I created this for part of a bigger project and figured it’d make a good generic template for any PowerShell script needing a basic menu using the up and down arrow keys and enter key to make a selection.  For example data it lists the items in the root of the C: drive, but can easily be supplied any array of strings to list out in the menu. The chosen item is stored as a string in the $selection variable to be used later in the script.

<# Title: PowerShell Menu Template | Author: Michael Casey | Date: July 3rd, 2019 | Website: #>

#Sample list data to populate menu:
#Set $List to any array to populate the menu with custom options
$List = Get-ChildItem -Path C:\ -Name

#menu offset to allow space to write a message above the menu
$xmin = 3
$ymin = 3

#Write Menu
Write-Host ""
Write-Host "  Use the up / down arrow to navigate and Enter to make a selection"
[Console]::SetCursorPosition(0, $ymin)
foreach ($name in $List) {
    for ($i = 0; $i -lt $xmin; $i++) {
        Write-Host " " -NoNewline
    Write-Host "   " + $name

#Highlights the selected line
function Write-Highlighted {

    [Console]::SetCursorPosition(1 + $xmin, $cursorY + $ymin)
    Write-Host ">" -BackgroundColor Yellow -ForegroundColor Black -NoNewline
    Write-Host " " + $List[$cursorY] -BackgroundColor Yellow -ForegroundColor Black
    [Console]::SetCursorPosition(0, $cursorY + $ymin)     

#Undoes highlight
function Write-Normal {
    [Console]::SetCursorPosition(1 + $xmin, $cursorY + $ymin)
    Write-Host "  " + $List[$cursorY]  

#highlight first item by default
$cursorY = 0

$selection = ""
$menu_active = $true
while ($menu_active) {
    if ([console]::KeyAvailable) {
        $x = $Host.UI.RawUI.ReadKey()
        [Console]::SetCursorPosition(1, $cursorY)
        switch ($x.VirtualKeyCode) { 
            38 {
                #down key
                if ($cursorY -gt 0) {
                    $cursorY = $cursorY - 1

            40 {
                #up key
                if ($cursorY -lt $List.Length - 1) {
                    $cursorY = $cursorY + 1
            13 {
                #enter key
                $selection = $List[$cursorY]
                $menu_active = $false
    Start-Sleep -Milliseconds 5 #Prevents CPU usage from spiking while looping

Write-Host $selection
#May use switch statement here to process menu selection

Screenshot of the PowerShell menu template script running

PowerShell & Windows Task Scheduler: Trigger Audio Clip at Set Time Daily

Inspired by a scene in The Office, Season 8, Episode 6 where Andy plays Semisonic’s “Closing Time” at the end of every workday, I decided to configure my computer to automatically do the same.

The base script is pretty succinct. It just needs to be pointed to a .wav file near the end of the first line. The song is exactly 4 minutes long, so I had it start playing at 4:56 to conclude exactly at 5.

$action = New-ScheduledTaskAction -Execute 'Powershell.exe' -Argument '$PlayWav=New-Object System.Media.SoundPlayer; $PlayWav.SoundLocation="C:\Users\michael\Music\ClosingTime.wav"; $PlayWav.playsync()'
$trigger =  New-ScheduledTaskTrigger -Weekly -WeeksInterval 1 -DaysOfWeek Monday,Tuesday,Wednesday,Thursday,Friday -At 4:56pm
Register-ScheduledTask -Action $action -Trigger $trigger -TaskName "PlayClosingTime" -Description "A fun reminder that the workday is over!"

We can now see the task registered in Task Scheduler:


PowerTip: Use PowerShell to play WAV files

Use PowerShell to Create Scheduled Tasks



Schedule Windows Notifications with PowerShell (Windows Task Scheduler / Toast Notifications)

I’ve found too many times that I can sit in front of a computer screen for several hours without taking a break but that later in the day the eye strain catches up with me. I wanted something to remind me to take a quick break every 20 minutes, following the 20-20-20 rule. There’s a lot of programs that do something like this. Workrave may be the most popular, but I’ve had a few problems with it and decided I could probably do something simpler with a scheduled PowerShell script.


First off, I need the notification. There’s a handful of blogs on how to make a toast notification in PowerShell. There’s a PowerShell module for it, but I’d rather not have to install an external module. From the creator of that module, here’s a working example of creating a toast notification in PowerShell:

$app = '{1AC14E77-02E7-4E5D-B744-2EB1AE5198B7}\WindowsPowerShell\v1.0\powershell.exe'
[Windows.UI.Notifications.ToastNotificationManager, Windows.UI.Notifications, ContentType = WindowsRuntime]
$Template = [Windows.UI.Notifications.ToastTemplateType]::ToastImageAndText01
#Gets the Template XML so we can manipulate the values
[xml]$ToastTemplate = ([Windows.UI.Notifications.ToastNotificationManager]::GetTemplateContent($Template).GetXml())
[xml]$ToastTemplate = @"
<toast launch="app-defined-string">
<binding template="ToastGeneric">
<text>DNS Alert…</text>
<text>We noticed that you are near Wasaki. Thomas left a 5 star rating after his last visit, do you want to try it?</text>
<action activationType="background" content="Remind me later" arguments="later"/>
$ToastXml = New-Object TypeName Windows.Data.Xml.Dom.XmlDocument
$notify = [Windows.UI.Notifications.ToastNotificationManager]::CreateToastNotifier($app)

I’m just going to copy what I need and modify and condense it. For more reading on toast notifications in PowerShell this blog article and this one provide more detail, but be sure to note that since they were published, it’s become necessary to use a real app id to get the notification to show – details here.

Here’s the selection of code I’m using for the notification.


$app = '{1AC14E77-02E7-4E5D-B744-2EB1AE5198B7}\WindowsPowerShell\v1.0\powershell.exe'
[Windows.UI.Notifications.ToastNotificationManager, Windows.UI.Notifications, ContentType = WindowsRuntime]

$Template = [Windows.UI.Notifications.ToastTemplateType]::ToastImageAndText01

$ToastTemplate = ([Windows.UI.Notifications.ToastNotificationManager]::GetTemplateContent($Template).GetXml())

$ToastTemplate = @"
<toast launch="app-defined-string">
    <binding template="ToastGeneric">
      <text>Prevent Eye Strain</text>
      <text>Take a 20 second break</text>

$ToastXml = New-Object -TypeName Windows.Data.Xml.Dom.XmlDocument

$notify = [Windows.UI.Notifications.ToastNotificationManager]::CreateToastNotifier($app)



Running this script will create the following notification:

VBS Launcher

The one problem with this is that when run through the task scheduler, a PowerShell console window will flash briefly before the notification displays. To avoid this intrusive popup, a short VBScript program can be used to launch the PowerShell script we’ve just created.


Dim shell,command
command = "powershell.exe -nologo -command ""C:\Scripts\Reminder.ps1"""
Set shell = CreateObject("WScript.Shell")
shell.Run command,0



The next step is to schedule this script to run and produce the notification every 20 minutes. This ended up being way more complex than I originally imagined. The parameters for New-ScheduledTaskTrigger don’t allow setting a RepetitionInterval with a Daily or AtLogOn parameter, which makes doing this a little tricky. In the end, I took some inspiration from this solution. The best solution simply seemed to be to set up the task I want in the Windows Task Scheduler GUI, export the XML, and then use that in the PowerShell script. At this point I’m not really doing much in PowerShell itself to create the task, however, ultimately this still creates a code-based solution that can easily be put into other scripts or run on a server without a GUI.

After creating the task in Windows Task Scheduler, I ran

Export-ScheduledTask "BreakReminder"

in PowerShell and get the following XML:

<?xml version="1.0" encoding="UTF-16"?>
<Task version="1.2" xmlns="">
    <Description>A reminder every 20 minutes to take a 20 second break to prevent eye strain.</Description>
  <Actions Context="Author">

I then squeezed that all into one line and end up with the following very messy lines of PowerShell code that can be used to create the task from scratch.  The Reminder.ps1 and Launcher.vbs files from above just need to be saved somewhere and the file paths in Launcher.vbs and the below code need to be updated accordingly.

$TaskXML = '<Task version="1.2" xmlns=""> <RegistrationInfo> <Description>A reminder every 20 minutes to take a 20 second break to prevent eye strain.</Description> <URI>\BreakReminder</URI> </RegistrationInfo> <Triggers> <CalendarTrigger> <Repetition> <Interval>PT20M</Interval> <Duration>P1D</Duration> <StopAtDurationEnd>true</StopAtDurationEnd> </Repetition> <StartBoundary>2019-06-10T00:00:00</StartBoundary> <Enabled>true</Enabled> <ScheduleByDay> <DaysInterval>1</DaysInterval> </ScheduleByDay> </CalendarTrigger> </Triggers> <Settings> <MultipleInstancesPolicy>IgnoreNew</MultipleInstancesPolicy> <DisallowStartIfOnBatteries>false</DisallowStartIfOnBatteries> <StopIfGoingOnBatteries>true</StopIfGoingOnBatteries> <AllowHardTerminate>true</AllowHardTerminate> <StartWhenAvailable>false</StartWhenAvailable> <RunOnlyIfNetworkAvailable>false</RunOnlyIfNetworkAvailable> <IdleSettings> <StopOnIdleEnd>true</StopOnIdleEnd> <RestartOnIdle>false</RestartOnIdle> </IdleSettings> <AllowStartOnDemand>true</AllowStartOnDemand> <Enabled>true</Enabled> <Hidden>false</Hidden> <RunOnlyIfIdle>false</RunOnlyIfIdle> <WakeToRun>false</WakeToRun> <ExecutionTimeLimit>P3D</ExecutionTimeLimit> <Priority>7</Priority> </Settings> <Actions Context="Author"> <Exec> <Command>C:\Scripts\Launcher.vbs</Command> </Exec> </Actions> </Task>'

Register-ScheduledTask "BreakReminder" -Xml $TaskXML.OuterXml

Raspberry Pi: Schedule Print Job

After having a couple sets of ink cartridges dry up on me after extended non-use, I learned that I’d need to print something regularly to keep my cheap inkjet printer working. After ignoring a few of my own reminders to print a test page manually, I decided to create an automated solution using a cron job on a Raspberry Pi I already have running on my home network.

To send the file to the printer, I used CUPS (documentation here or here). I followed the tutorial here to get it installed and activate the web interface.

With the printer added, I ran lpstat -p -d to get the exact name of the printer, then lp -d <printer> <file> to send a file to the printer.

To add the weekly cron job, I ran crontab -e and added the following line to get it to print weekly at noon on Sundays:

0 12 * * Sun lp -d HP_DeskJet_printer Sample.pdf


Security vs Usability – Paper I Wrote

Here’s an 8 page paper I wrote for a systems administration class. The assigned topic was “security vs usability.”


In the field of information technology, usability and security are often seen as opposites where an increase in one comes at the expense of the other. Systems administrators must learn to strike a balance between the two. Where other people are concerned, too-stringent security policies can drive them to circumvent or ignore the policies, while lax policies can create organizational vulnerabilities. Newer technologies such as password managers and two factor authentication can increase security while remaining user friendly. Configuration managers, patch management systems, and automation frameworks assist a systems administrator with keeping servers and personal computers updated and secure, and newer mobile device managers do the same for portable, personal devices such as smartphones and tablets. Assisted by these technologies, the systems administrator can set policies and deploy systems that are safe enough to protect organizational assets while still setting up systems that are convenient and efficient for end users.

Keywords: Information technology, systems administration, security, usability, cybersecurity, passwords, antivirus, server, computer

Balancing Security and Usability Trade-offs in Systems Administration

To the average user, cybersecurity may currently mean that they add a number to their children or pet’s name to make a more secure password, they write it down but do not keep it somewhere obvious, or just that they hope no one “hacks” their iCloud photos. To the cybersecurity expert, security means long, random passwords stored in secure places, two (or more) factor authentication, securely encrypted web traffic and reliable backups. Sandwiched awkwardly in between the two is the systems administrator, who may oversee security policies for their organization and know that harder password requirements can result in users writing down passwords and storing them in obvious places or reusing them, yet the systems administrator also knows just how easy it can be to crack hashes of weaker passwords.

Security, of course, entails much more than just passwords, and this paper will explore many aspects of security as they relate to usability. However, authentication is one major problem that involves balancing security and usability. Figure 1 illustrates how many users simply see security measures as obstacles in their day to day tasks and don’t often think about the larger picture and what security measures need to accomplish. Figure 2 gives a more realistic look at how security and usability can be opposites and how a balance can often be found in the middle. Systems administrators, and IT departments generally, must strive to find the balance that allows them to be secure enough to protect critical assets, while still being usable enough that others in the organization are able to do their jobs efficiently.

Security Theory

At a conceptual level, security has always involved staying ahead of criminals or hackers. It is constantly evolving, and constantly involves creating both new technologies and new policies. Security is based on trust. Systems administrators must be able to trust that their systems adequately verify users and must create different levels of users with different access to each system. Because of the nature of security, it always takes time and effort. The more a process relies on built-in assumptions or automation, the easier it is for someone to gain illegitimate access to. Therefore, it seems authentication is always going to require some sort of manual process. Security is always going to need the attention of information technology professionals. For many people, security policies will always seem to be in the way, taking valuable work time away from actually accessing the data or running the process they want.

Because of this, security seems to be at odds with usability. The more secure something is, the more steps it requires to access. Ultra-secure facilities, such as defense contractors, may require many steps of physical and digital security before employees can access anything. Other organizations have to find a balance of requiring enough security precautions to protect themselves, while still allowing people to perform their normal functions and not be totally stopped by the security protocols.


As previously mentioned, setting password policies is one of the biggest trade-offs between usability and security. Cybersecurity experts push for longer passwords, citing how easy it is to crack shorter ones. Back in 2012, for instance, researchers demonstrated it was possible to crack every possible 8 character password with $8000 in computer equipment in just 6 hours (Goodin, 2012), and the price and speed of similar hardware have definitely only gone down in subsequent years. However, most IT professionals will cite countless examples of typical users writing passwords down on sticky notes, saving them in plain text, or reusing passwords when forced to specific password policies. As a good compromise, the National Institute of Standards and Technology recommends passwords be at least 8 characters in length, but that developers not force any specific pattern or use of certain characters (NIST, 2017), and that they allow much longer passwords and the use of all special characters. Passwords have been around since the early stages of computing. In many ways, they work the same now as they did then, but some technologies are trying to change that.

Several prominent solutions aim to make passwords more secure but also more usable. Prominent among these are password managers, which store passwords and allow the end user to forget them. This enables easy use of long, randomly generated passwords and unique passwords for each site. The major drawback is that this creates one central point of attack that could allow a hacker complete access to a person’s digital identity. Password managers are generally designed to be as user friendly as possible and represent a good solution for using secure passwords. However, the more technology-averse user may still see them as an additional and unnecessary technology to be learned. Password managers are a relatively new technology that stem from the increasing number of digital accounts people maintain and the increasing awareness of the weakness of reusing passwords across different services.

Two-factor authentication involves using something else for authentication, often a code sent to the user’s phone, in addition to a password. This takes the pressure off passwords as the sole point of failure in account security. Other methods of two-factor authentication include dedicated code generators and biometrics. On the one hand, two-factor authentication is inherently going to be twice as slow (and often slower) compared to only using one method, which makes it less usable and convenient. However, most popular two-factor authentication systems are not difficult for the average person to learn to use, and reduce the risk of more lenient password policies, which make them drastically more secure than strict, lengthy password policies alone.

Much is also being done in the field of biometrics to improve digital authentication experiences. Many phones and some laptops now ship with fingerprint readers, and some devices have facial recognition technology available. These technologies currently represent the ultimate in usability, taking almost no noticeable time or effort to use. However, they may not be the most secure. Apple claims that their Face ID facial recognition technology has about a 1 in 1,000,000 chance of authenticating the wrong user, while their Touch ID fingerprint readers have a 1 in 50,000 chance of doing so (Vrijenhoek, 2017). When compared with the 1 in 10,000 odds of guessing a four-digit passcode correctly, those odds sound pretty good, and may be best for unlocking a phone compared to short PINs or other alternatives. However, just a four-digit password using any combination of all 95 ASCII characters has 81 million possible values, and longer passwords may be better to protect mobile payments or make other more secure transactions. The availability of biometric authentication to the average consumer has drastically increased in recent years.


Updates are typically not popular among end users. From slow-running Windows updates halting work midday to fast changing web apps updating and losing functionality, many users find updates annoying and many organizations have policies to reduce or delay updates in order to minimize risk. Ironically, not updating frequently carries risks of leaving vulnerabilities unpatched, while updating frequently risks breaking systems and affecting the availability of a service. Systems administrators must be able to find a balance between the two.

When it comes to software updates, especially for endpoint software, faster and more frequent updates are generally preferred so that exposed vulnerabilities get patched. Most medium to large organizations have a patch management system in place. Microsoft System Center Configuration Manager can manage Windows updates as well as deploy and manage other software and keep it updated. System Center Configuration Manager is available for managing both user workstations and datacenter servers.

For Linux servers, a number of systems exist for managing updates and pushing out new software. Puppet, Ansible, Chef, SaltStack and Fabric are all major software platforms for Linux deployment management. From the systems administrator’s perspective, a management service like that is vital for keeping systems running secure software but also doing so efficiently and being easy to use for the systems administrator.

Software (including operating systems) generally needs some sort of review process before being deployed. For instance, one Windows 10 update released in October 2018 resulted in files disappearing for a number of users (Dunn, 2018). The professional and enterprise versions of Windows 10 include an option to delay feature updates for 6 months past their release to home users (Gordon, 2018). Many organizations have implemented this to allow time for bugs to be fixed before they deploy the feature updates, while still getting security updates for Windows.

Mobile Device Management

A large and more recent challenge to systems administrators is managing mobile devices. Depending on an organization’s policies, users may bring in personal devices and connect them to the network. They may also put corporate data, especially emails and contacts, onto an otherwise unsecured and unmanaged device. To combat this, many device management systems are adding features to manage mobile devices. Other mobile device management systems are offered as stand-alone technologies for managing personal devices only. These mobile device management systems are a new branch of configuration managers, which have been around for longer. Mobile device management can be tricky since mobile operating systems (Android, iOS) are different from the desktop and server operating systems typically found in organizations (Windows, Linux) and are built with different security models and permission structures.

Some organizations choose to separate these devices as much as possible. They may create separate wireless networks designed for these devices that have no access to other internal resources and may try to limit or ban organizational data from these devices. In more extreme cases, they may force users to maintain one device for corporate use and another for personal use. Other organizations may try a hybrid approach, allowing employees to access corporate email on a personal device so long as the device has an anti-virus app enabled and meets certain security requirements, such as a minimum passcode length or having a fingerprint reader. Here again a balance of usability must be found. Forcing the user to have especially long passcodes on their phones, for instance, could drive them to find ways to circumvent the policy.

Security Monitoring

From endpoint anti-virus systems to complex intrusion detection systems, it is vital that an organization have systems in place to detect and mediate security threats. In choosing these systems, security and reliability must be the foremost concern.

For endpoint antivirus software, many viable options exist for personal computers and mobile devices. The various and specific needs of an organization as well as their budget may determine the best option. Security should win out here (how reliable is the anti-virus?), however, usability is still a factor. An antivirus that slows down a computer noticeably or that has overzealous user notifications will slow users’ workflows while providing little benefit over a better alternative. Additionally, intrusion detection systems and other security monitoring services should be provisioned for the security of the company. These systems are not at all new in the information technology world, though more modern security software provides increasingly fast updates and options for automated monitoring.


Another security challenge the systems administrator faces is keeping data available. Many end users may not give much thought to backups, but to IT professionals who have worked with large storage arrays, the risk of data loss is ever present. Here the systems administrator must decide largely for themselves what the trade-offs of different backup systems are and also how to implement file recovery and make it available to the users. Creating a user-facing file recovery system is a necessity in most larger organizations and will involve trade-offs between usability and security.

Implementing file restore systems that are easy for the end user to access is a great way to make restoring files highly usable and avoid the systems administrator having to do each restore manually, which could be a monumental task in a large organization. Windows Backup’s Previous Version feature (Muir), for instance, is a very user-friendly way to allow file restores. However, it has certain security risks, like giving a user the ability to roll an entire network share back to a much older version, which could cause major problems if the files are shared with a large group of people. Other commercial software, like Crashplan for Business, allows users to access and restore their own files backed up from their individual machines, with minimal security risk, other than users maintaining their own accounts and passwords.

On the system’s administrator’s side, backups must be checked occasionally to ensure validity. Increasing automation saves the system administrator time and allows for frequent backups, but these increases in usability mean the system administrator is less likely to notice a failed backup or other errors in the backup system, resulting in increased risk to data availability.


Balancing security and usability is a delicate act for systems administrators, both in the systems they choose to set up for themselves, and in the systems they deploy to non-IT users. In setting up servers and networks, systems administrators may find it worth taking the time to set up complex and secure systems. However, when setting policies for other users, systems administrators need to find the balance that makes the systems usable (otherwise, why have them at all?) and avoids driving end users to do things like writing down passwords, sharing credentials, or otherwise circumventing protocols.

Fortunately, many technologies have been or are being developed to make securing systems easier. Password managers and two-factor authentication allow normal users drastically increased security over the traditional memorized password while maintaining a balance of being easy enough to use that most people can use them. Patch and configuration managers allow systems administrators to deploy updates and security policies to all systems within an organization. Increasing automation in backups and security monitoring present much easier to use systems to the IT professional, while minimizing increased security risk. With the right tools, the systems administrator can create systems that are both easier to use and more secure than they have been in the past.


Adams, S. (n.d.). Dilbert comic strip on 2007-11-16 | dilbert by scott adams. Retrieved December 2, 2018, from

Dunn, J. (2018, October 9). Microsoft hits the brakes on latest Windows 10 update – what to do. Retrieved December 2, 2018, from

Goodin, D. (2012, October 12). 25-GPU cluster cracks every standard Windows password in <6 hours. Retrieved December 1, 2018, from

Gordon, B. W., July 6, 2018 8:00AM EST, & July 6, 2018. (n.d.). How to delay major windows 10 updates. Retrieved December 2, 2018, from

Infotech solutions & services inc. | security-vs-usability1. (n.d.). Retrieved December 2, 2018, from

Leonhard, W. (n.d.). How to restore previous versions of a file in windows 7. Retrieved December 2, 2018, from

NIST Special Publication 800-63B. (n.d.). Retrieved December 1, 2018, from /sp800-63b.html

Vrijenhoek, J. (2017, December 20). Apple security: touch id vs. Face id. Retrieved December 1, 2018, from




Figure 1. Many users perceive security as an obstacle to getting their work done. Some managers may be prone to seeing security measures as a waste of budget or time.

Figure 2. Security and usability involve trade-offs, and improving one often comes at the cost of the other.

Raspberry Pi – Minimal Headless Setup

For my own quick reference, mostly taken from here:

  1. See end of article if SD card was previously used.
  2. Download Raspbian from
  3. Download and install Win32DiskImager from
  4. Using Win32 Disk Imager, write the ISO to the SD card
  5. Add a file called wpa_supplicant.conf in the boot drive with the following (adding your own SSID and password):
    ctrl_interface=DIR=/var/run/wpa_supplicant GROUP=netdev
  6. Add a blank file named ssh (with no file extension) to the boot drive to enable ssh. In Windows notepad or similar, save the file as “ssh” (with the quote marks) to avoid it adding a .txt file extension.
  7. Insert the SD card to the Raspberry Pi, and plug in to power. Wait a few seconds, then use the Fing app to get its IP address on a home network, and use Putty to SSH in using default credentials of pi / raspberry.
  8. Change the default password by running
Edit: Make Raspberry Pi Email You Its IP Address
As mentioned above, I’ve previously used the Fing app to find the IP address of the Pi on my home network. Recently, I’ve needed to access the Pi on a university network and wanted to do so without connecting it to a monitor and keyboard / mouse. Here’s a script to email the IP address of the Pi to myself every time it’s booted. Just modify the email and password (I’m using a secondary email account so I don’t care about the password being stored in plain text):
#pip install netifaces
import pip
def install(package):
if hasattr(pip, 'main'):
pip.main(['install', package])
pip._internal.main(['install', package])
if __name__ == '__main__':

import smtplib
import netifaces as ni
import socket

ip = ni.ifaddresses('wlan0')[ni.AF_INET][0]['addr']
hostname = socket.gethostname()
message = hostname + "\n" + ip

fromaddr = ''
toaddrs = ''
username = ''
password = 'password'
server = smtplib.SMTP('', '587')
server.sendmail(fromaddr, toaddrs, message)

Add the following to /etc/rc.local after the line “# By default this script does nothing.” and point it to the script you just saved:

sleep 20
python /path/to/

If the SD card was previously used in a Raspberry Pi, the partitions will need to be merged again.

  1. Open Disk Management.
  2. Right click and select Delete Volume for both partitions on the SD card.
  3. Right click and select New Simple Volume to create one partition for the whole SD card. Make sure the partition is FAT32. Win32DiskImager will create two partitions again, but this way it initially sees the whole SD card.


Ubuntu: Resume Script in Terminal After Reboot

I needed to reboot in the middle of my shell script to install Kubernetes / Brigade, and my Googling found several people with similar questions, but no answers that quite worked for me. Here’s the basic code just to get a shell script to reboot and then resume in a visible terminal after the reboot.

The commands to be run after the reboot are echoed into a new shell script, so characters like slashes and dollar signs need to be escaped with a backslash.

Most of the posts with similar questions mentioned that running a shell script with sudo is a bad idea. Since my script is designed to be run in a sandboxed VM and most of the commands needed sudo permissions anyways, I figured it’s not a problem in this case.

#after reboot
echo "echo \"Post-reboot content goes here\"

#remove this from running at startup
rm ~/.config/autostart/myScript.desktop
rm /home/$SUDO_USER/" >> /home/$SUDO_USER/

#make file executable
chmod +x ~/

#set new script to run after reboot
cd .config/
mkdir -p "autostart/"
cd ..
echo "[Desktop Entry]
Exec=x-terminal-emulator -e sudo /home/$SUDO_USER/
Name=Testing" >> ~/.config/autostart/myScript.desktop

#before reboot
echo "Pre-reboot commands go here"
sleep 30

reboot -f

Running the script:
 After the reboot:

Self-Elevating PowerShell and Batch Scripts

Many scripts require admin permissions, but remembering to right click and select “Run as Administrator” can be a pain. Fortunately, both batch and PowerShell scripts can written so that they’ll prompt for admin permissions if not run as an administrator. This won’t get around not having administrator permissions, but will save you a couple clicks every run by jumping straight to the UAC prompt.

Neither of these scripts are mine, but I’m documenting them here for my own quick and frequent reference.

CMD / Batch scripts:

:: Elevate.cmd - Version 4
:: Automatically check & get admin rights
:: see "" for description
 @echo off
 ECHO =============================
 ECHO Running Admin shell
 ECHO =============================

 setlocal DisableDelayedExpansion
 set cmdInvoke=1
 set winSysFolder=System32
 set "batchPath=%~0"
 for %%k in (%0) do set batchName=%%~nk
 set "vbsGetPrivileges=%temp%\OEgetPriv_%batchName%.vbs"
 setlocal EnableDelayedExpansion

  if '%errorlevel%' == '0' ( goto gotPrivileges ) else ( goto getPrivileges )

  if '%1'=='ELEV' (echo ELEV & shift /1 & goto gotPrivileges)
  ECHO **************************************
  ECHO Invoking UAC for Privilege Escalation
  ECHO **************************************

  ECHO Set UAC = CreateObject^("Shell.Application"^) > "%vbsGetPrivileges%"
  ECHO args = "ELEV " >> "%vbsGetPrivileges%"
  ECHO For Each strArg in WScript.Arguments >> "%vbsGetPrivileges%"
  ECHO args = args ^& strArg ^& " "  >> "%vbsGetPrivileges%"
  ECHO Next >> "%vbsGetPrivileges%"

  if '%cmdInvoke%'=='1' goto InvokeCmd 

  ECHO UAC.ShellExecute "!batchPath!", args, "", "runas", 1 >> "%vbsGetPrivileges%"
  goto ExecElevation

  ECHO args = "/c """ + "!batchPath!" + """ " + args >> "%vbsGetPrivileges%"
  ECHO UAC.ShellExecute "%SystemRoot%\%winSysFolder%\cmd.exe", args, "", "runas", 1 >> "%vbsGetPrivileges%"

 "%SystemRoot%\%winSysFolder%\WScript.exe" "%vbsGetPrivileges%" %*
 exit /B

 setlocal & cd /d %~dp0
 if '%1'=='ELEV' (del "%vbsGetPrivileges%" 1>nul 2>nul  &  shift /1)

 REM Run shell as admin (example) - put here code as you like
 ECHO %batchName% Arguments: P1=%1 P2=%2 P3=%3 P4=%4 P5=%5 P6=%6 P7=%7 P8=%8 P9=%9
 REM put remaining commands here
 cmd /k

source (stackoverflow)


Fortunately this one’s a lot shorter:

If (-NOT ([Security.Principal.WindowsPrincipal][Security.Principal.WindowsIdentity]::GetCurrent()).IsInRole([Security.Principal.WindowsBuiltInRole] "Administrator"))

	$arguments = "&amp; '" + $myinvocation.mycommand.definition + "'"
	Start-Process powershell -Verb runAs -ArgumentList $arguments

source (stackoverflow)