Windows 10 ISO to FAT32 Flash Drive

Uncategorized No Comments

Typically we can now use the Media Creation Tool to always have an up to date version of Windows 10 on a flash drive. Unfortunately the most up to date for the Media Creation Tool is a first half update (21H1) which only has 18 months of support. I always install the second half (20H2) as it will have 30 months of support for Education. I download the latest version of the ISO from our VLSC portal.

Prepare the Flash Drive

select disk X
create partition primary
select partition 1
format fs=fat32 quick label="Win10_20H2"
assign letter=w

Mount the ISO in Windows Explorer by double clicking the ISO file. Make note of the path. Example: E:\

robocopy e:\ w:\ /e

This will fail to copy the install.wim file as it is too large for a FAT32 volume. You must split it using:

Dism /Split-Image /ImageFile:m:\sources\install.wim /SWMFile:w:\sources\install.swm /FileSize:3800


Docker Commands

Uncategorized No Comments

The main ones I need:

docker ps

docker ps –all

docker rm <id>

docker images

docker exec -it <id> bash

Systemd Resolv

Uncategorized No Comments

edit /etc/systemd/resolved.conf and uncomment DNS.


pfSense on OVH VPS

Uncategorized 12 Comments

I have a unique situation where my ISP has me behind 2 NAT routers and applying to have a port forward always turns into a big problem. I have a need for some public facing services that I wish to host in my home lab. Originally I setup an OVH VPS using the OpenVPN Access Server and just connected to it with some port forwards. However, I was really missing some of the advanced features and GUI of pfSense. FreeBSD is not an option for an OVH VPS so I started down the path of trying to figure out how to get this to work.

First you must start out with a Ubuntu VPS. For this purpose I chose Ubuntu 18.04. I did a fresh install.

Once your VPS is ready refer to the email from OVH for your root password. The rest of this work will be done in the KVM. It is easier to copy and paste in a SSH session but the system isn’t accessible the entire time so the KVM is easier at this point.

Document your default gateway

root@vps:# route -n
Kernel IP routing table
Destination     Gateway         Genmask         Flags Metric Ref    Use Iface         UG    0      0        0 ens3 UH    0      0        0 ens3

In this example my default gateway is

Prepare grub to boot mfsbsd into RAM.

root@vps:# nano /etc/default/grub

root@vps:# nano /etc/default/grub.d/50-cloudimg-settings.cfg

root@vps:# apt install grub-imageboot -y
root@vps:# mkdir /boot/images
root@vps:# cd /boot/images
root@vps:# wget
root@vps:# update-grub2
root@vps:# reboot

I previously tried to install pfSense from the ISO this way but it always fails as it is looking for the CD. mfsbsd is designed to run from PXE in RAM so this was a working solution.

Boot into mfsbsd

In the grub boot menu select “Bootable Floppy Image: mfsbsd-se-12.0-RELEASE-amd64” then wait. It takes a bit for it to start. Let the system boot into Multi User.

username: root
password: mfsroot

document your interface name

root@mfsbsd:# ifconfig
vtnet0: flags=8943<UP,BROADCAST,RUNNING,PROMISC,SIMPLEX,MULTICAST> metric 0 mtu 1500

vtnet0 should be your interface name. Routing doesn’t work automatically because the gateway is in a different network than your DHCP assigned address. You must manually assign a route to the interface then add the default gateway.

root@mfsbsd:# /sbin/route add -host -iface vtnet0
root@mfsbsd:# /sbin/route add default

Download needed software

root@mfsbsd:# pkg install wget
root@mfsbsd:# cd /tmp
root@mfsbsd:# wget -O - --no-check-certificate | gunzip -c > pfsense.iso

You may need to adjust your pfSense ISO download URL. You have to use the –no-check-certificate because we don’t have trusted CA’s in the live mfsbsd.

Mount ISO and run installer from chroot

root@mfsbsd:# mdconfig -a -t vnode -f /tmp/pfsense.iso
root@mfsbsd:# mount -t cd9660 /dev/md1 /cdrom

root@mfsbsd:# mount -t devfs devfs /cdrom/dev
root@mfsbsd:# mount -t tmpfs tmpfs /cdrom/tmp

root@mfsbsd:# chroot /cdrom
root@mfsbsd:# /usr/sbin/bsdinstall

Welcome to the pfSense Installer

Perform a regular install. I chose UFS and left the installer to the defaults.

Reboot when done. The pfSense CLI wizard will start automatically.

DO VLANs need to be setup first? N
Type vtnet0 as your WAN interface.
LAN interface should be empty.
Press 8 and [enter] to access the pfSense Shell.

[2.4.4-RELEASE][admin@pfSense.localdomain]/root: /sbin/route add -host -iface vtnet0
[2.4.4-RELEASE][admin@pfSense.localdomain]/root: /sbin/route add default
[2.4.4-RELEASE][admin@pfSense.localdomain]/root: exit

Document your WAN IP address from the pfSense Welcome Screen.

Login to pfSense Web GUI and install Shellcmd

username: admin
password: pfsense

Immediately change your password. Its a warning banner at the top.

Click on System > Package Manager, then Available Packages.
Find Shellcmd and click on +Install

Click on Services > Shellcmd
Click +Add


/sbin/route add -host -iface vtnet0 && /sbin/route add default

Shellcmd Type:


Use the same command and +Add another command and select ”
afterfilterchangeshellcmd” as the Shellcmd Type.

Now when you reboot your pfSense will get its IP from DHCP and setup routing automatically for you. Even when you reload your filter.


At this point I now have a public IP address on a pfSense firewall. From here I was able to setup OpenVPN and setup NAT Port Forwarding to my home lab.

Disable Ubuntu GUI

Uncategorized No Comments

To disable GUI on boot, run:

sudo systemctl set-default

To enable GUI again issue the command:

sudo systemctl set-default

Remove darker images from timelapse

Uncategorized No Comments

I had a project where I took a picture from a security camera every 15 minutes in order to build a timelapse. The project lasted almost a year so I didn’t have a good way to set the day/night schedule as the seasons changed. I ended up taking pictures every 15 minutes for the whole project.

In order to build the final project I needed to remove all the dark images. I certainly wasn’t going to go through the entire folder contents and erase a group of pictures per night. In comes the utility identify from ImageMagick. This utility gives you the mean of the image so we can find the darker images.

$pictures = gci -Filter *.jpg -Recurse | Select -ExpandProperty FullName

foreach ($i in $pictures) {
    $mean = identify.exe -quiet -format "%[mean]" "$i"
    if ($([int]$mean) -le 10000) {
        Remove-Item "$i" -Force

YouTube Playlist Download for Plex

Uncategorized No Comments

youtube-dl -cio ‘S01E%(playlist_index)02d-%(title)s.%(ext)s’ ‘playlist.url’

Update configuration on AeroHive APs with Powershell and SSH

Uncategorized No Comments
$ahouis = @("00-19-77","88-5b-dd","08-EA-44","D8-54-A2","C4-13-E2","40-18-b1")

#get domain admin creds
$dacreds = $(Get-Credential -Message "Please enter domain admin credentials for pulling DHCP info.")
$creds = $(Get-Credential -Message "Please enter AeroHive SSH username and password.")
$server = Read-Host -Prompt "DHCP Server name?"

$dhcpscopes = Invoke-Command -Credential $dacreds -ComputerName $server -ScriptBlock { Get-DhcpServerv4Scope } | select ScopeId
$dhcpleases = $dhcpscopes | ForEach-Object { $scope = $_.'ScopeID'; Invoke-Command -Credential $dacreds -ComputerName $server -ScriptBlock { Get-DhcpServerv4Lease -ScopeId $Using:scope} } 

$aps = @()

$ahouis | ForEach-Object {
    $oui = $_
    $aps += $dhcpleases | ? { $_.'ClientId' -like "$($oui)*" }

$aps | select -ExpandProperty ipaddress | % {

    if (Test-Connection -Count 1 -ComputerName $_) {
        New-SSHSession -ComputerName $_ -Credential $creds -AcceptKey -Force
    } else {

#Get the sessions where we successfully made a connection.
Get-SSHSession | ? { $_.'Connected' -eq $True } | select -ExpandProperty SessionID | % {

    $session = Get-SSHSession -SessionId $_
    $stream = $session.Session.CreateShellStream("dumb",0,0,0,0,1000)
    $stream.Write("show capwap client | include `"Primary Name`"`n")
    Start-Sleep -Seconds 1
    $result = $stream.Read()

    $result.Split([System.Environment]::NewLine) | % {
        if ($_ -like "*Primary Name:*") {
            if ($_ -like "*:cloud-va2-cws-1*") {
                write-host "Already updated"
                #already done
            } elseif ($_ -like "*") {
                #command ran successfully but the host needs updated.
                #$stream.Write("capwap client name`n")
                write-host "Host $($session.Host) needs updated"
                write-host $_
                $stream.Write("capwap client server name`n")


#disconnect all sessions
Get-SSHSession | Remove-SSHSession


Move CD-Drive Letter in Lab

Uncategorized No Comments
1..26 | % { Invoke-Command -ComputerName "LABNAME-C$($_)" -ScriptBlock {
Get-WmiObject -Class Win32_volume -Filter "DriveLetter = ""$(Get-Volume | ? { $_.DriveType -eq "CD-ROM" } | select -ExpandProperty DriveLetter | select -first 1):""" |Set-WmiInstance -Arguments @{DriveLetter='Z:'} }

1..26 creates an array 1 through 26.
% is short for foreach
$($_) uses each number from the 1..26 array
$(Get-Volume | ? { $_.DriveType -eq “CD-ROM” } | select -ExpandProperty DriveLetter | select -first 1) gets the first cd drive.

Select only 25 Active Emails as CSV

Uncategorized No Comments

$mail = @(); $teachers = Get-ADUser -filter { mail -like "*" } -Properties mail | ? { $_.Enabled -eq $True } | select mail | select -First 25 | % { $mail += $_.mail }; $mail -join "," | clip
$mail = @(); $teachers = Get-ADUser -filter { mail -like "*" } -Properties mail | ? { $_.Enabled -eq $True } | select mail | select -First 25 -Skip 25 | % { $mail += $_.mail }; $mail -join "," | clip

« Previous Entries