Dyota's blog

Starting my journey with PowerShell

What is this post really about? It's about my short experience with PowerShell, how I got started, and how everyone can really benefit by knowing a little bit. If you work wotk computers at all, doesn't even have to be with IT or code, it's still beneficial to learn a little bit. I'll show you some things that I've done to make my life a little bit easier.

How I got started

Over the past two months or so, I've been using a command-line tool in PowerShell every day.

I had tried to do "use the command line every day" in the past - just to be "one of those guys" - but all I was doing at the time was just traversing the file system with cd and dir. It was uncomfortable and inefficient. I could just as well click on folders and files and get to where I need, as soon as I need it. I wasn't using any aliases, or modules, or anything else that may have made my life easier.

As with anything, it was when I found a reason to use the command line did I really start to explore.

tt

I had started to use this command-line time-tracking tool called tt. I highly recommend it to anyone who works on a computer all day, and especially if you have to bill your time to clients, as I sometimes do.

It is a time tracker, and you can "start" and "stop" tasks. Tyically, you start a task by simply typing tt start <taskname> now. It stores all of the data in a .json file in your $HOME directory.

I've always done some form of time tracking or another. I used to favour Excel sheets, mainly because I could fully trick it out with formulas and charts. However, there's always little niggles that the author of tt describes.

Why I dove deeper

Having a command-line utility is like a shotcut between tool and mind. If I want to record something, I can tell the machine right there and then, with words. There is no GUI to get in way.

This feeling is what prompted me to learn PowerShell propery to see what I else I can do like this - to connect my intention to the machine just that little bit closer.

The PowerShell profile

A lot of these shortcuts were made available by editing my profile. The profile a is script that PowerShell loads when it boots up, and I filled it with custom functions and shortcuts. Editing my PowerShell profile became something of a hobby for a time. I'll share with you some things that I did. A lot of them are just shortcuts for things that I commonly do.

cd; dir

In File Explorer, when you enter a folder, you see what's in it. In PowerShell/Command Prompt, you don't. It's a small thing, but this is exactly the type of thing that would turn off a beginner if you grew up in a world where graphical file explorers were the norm.

So I changed it.

function cdd ($path) {
        $path = Resolve-Path $path
        Set-Location $path
        Get-ChildItem $path
}

This is the same as typing cd; dir in sequence.

Wrapper around tt

tt has a number of commands built it, but I almost exclusively only use a few. One of them is tt start <taskname> now. There's very few times that I would specify a time other than now.

So I wrote a wrapper function in PowerShell that shortcuts all that.

function tts ($task)    {tt start $task now}

It's a small thing, but it makes a big difference as I'm starting and stopping tasks many times per day.

Todo list

Aside from a time tracker, I also used to have a todo list in Excel (back then, Excel was all I knew and I thought I was pretty good at it!). However, it is still another heavy program to open-close, and it gets in the way of my actual (Excel-based) work if I keep it open all day.

Aside from paper, the best todo list for work I've had so far is a simple text file. I used to just handle this in Notepad++, but I've since written some PowerShell functions to do just what I need.

All of these functions refer to a text file I have, the path of which is stored in the variable $todo.

To add a new item:

# "To do add"; appends a new line at the end of todo.txt with a [ ]
function tda ($todoitem) {Add-Content -Path $todo -Value ('[ ] ' + $todoitem)}

To print out just the not-yet-done items:

# "To do empty"; filter out lines in todo.txt with the characters "[ ]"
function tde ($searchTerm) {Get-Content $todo | Select-String "\[ \].*$searchTerm"}

To mark off the "done" items, I edit using Neovim and put an x in the square brackets. This part feels a bit caveman, but it works for now and I don't need to engineer it any further.

TIL

I learn new things every day. So that I can record a new learning as soon as I obtain it, without having to find a particular file/app to record it in, I wrote a small function to do it for me so that I can focus on just the writing.

# "Today I learned..."; adds a new line to til.txt ($til) with today's date in front.
function til ($lesson) {
    if ($lesson.length -eq 0) {Get-Content $til} 
    else {$date = (Get-Date -Format "yyyy-MM-dd"); "$date $lesson" | Add-Content -Path $til -Encoding "UTF8"}
}

git commands

I use git sometimes. However, I'm a solo developer working on very simple projects. The majority of my use of git is simply git add .; git commit -m "$message". Occasionally, that is followed by git push github master. So, I wrote shortcut functions for both of these.

# Add all files and commit
function gac($message) {
    # git add all and commit with a message
    Write-Host "Added all files to staging."
    git add .;
    Write-Host "Commited with message `"$message`""
    git commit -m $message;
}
# Add all, commit, and push to all remote repos
function gacp($message) {
    $remote = git remote;
    $branch = (git branch).split(' ')[1];
    # git add, commit, push to all remotes
    gac($message);
    $remote | Foreach-Object {
        Write-Host "Pushing to $_..."
        git push $_ $branch;
        Write-Host "Push to remote $remote repository complete.`n"
    }

My prompt

My prompt would be too long to share, but the gist of it is that it shows the time and what I'm working on via tt. I used to call tt every time the prompt rendered, which was an incredibly amateurish mistake. I now make it read the .json data file. It picks up what I'm working on at the moment, and how long I've been working on it for.

If I've been working on something for longer than 30 minutes, the "time elapsed" portion turns red. That's a sign for me to get up and walk around for a bit.

It's not a perfectly accurate system, but I personally like how I can make my prompt pull double duty by reminding me what I'm supposed to be working on and also act as a makeshift pomodoro timer, all without needing to have another app open on my desktop.

That's it!

These are my daily PowerShell things that make things a little bit smoother for me day to day. I'm learning how to write some more interesting scripts but those will be saved for another post.

#powershell