Git and GitHub for System Administrators: A Practical Guide

Git is version control software that tracks changes in files over time. System administrators use it to manage PowerShell scripts, configuration files, infrastructure documentation, and runbooks — anything that changes and needs a history. Without version control, you rely on file copies, timestamps, and memory to understand what changed and when.

GitHub is a cloud platform that stores Git repositories remotely. It adds backup, access from multiple machines, and a foundation for collaboration. This guide walks through Git and GitHub from first setup to everyday workflows. All examples use Windows 10/11 and PowerShell, with C:\Projects\AdminScripts as the working directory throughout.


Requirements

Before starting, make sure the following are in place.

  • Git for Windows — download and install from git-scm.com/download/win. Use default installer options. Git will be available in PowerShell after installation.
  • GitHub account — register at github.com. A free account covers everything in this guide.
  • PowerShell 5.1 or later — built into Windows 10/11. PowerShell 7+ also works.
  • No administrator rights required for most steps.

After installing Git, verify it is available:

git --version

Expected output:

git version 2.x.x.windows.x

Set your identity. Git requires this before you can make your first commit:

git config --global user.name "Your Name"
git config --global user.email "your@email.com"
git config --global init.defaultBranch main

Project Setup

Create the working directory and initialize a Git repository inside it:

New-Item -ItemType Directory -Path "C:\Projects\AdminScripts"
Set-Location "C:\Projects\AdminScripts"
git init

Expected output:

Initialized empty Git repository in C:/Projects/AdminScripts/.git/
Note: git init creates a hidden .git folder inside your project directory. This folder contains the entire repository history, configuration, and internal state. Do not delete or modify it manually.

[Screenshot placeholder — PowerShell window showing git init output]


Your First Commit

A commit is a saved snapshot of your project at a specific point in time. It records what changed, when, and who made the change. You can return to any commit at any point.

Create a sample PowerShell script in your project folder:

@'
# Get-ServerInfo.ps1
# Returns basic system information for the local machine

$info = [PSCustomObject]@{
    Hostname   = $env:COMPUTERNAME
    OS         = (Get-CimInstance Win32_OperatingSystem).Caption
    Uptime     = (Get-Date) - (Get-CimInstance Win32_OperatingSystem).LastBootUpTime
    PowerShell = $PSVersionTable.PSVersion.ToString()
}

$info | Format-List
'@ | Set-Content "Get-ServerInfo.ps1"

Check what Git sees in your working directory:

git status
Note: git status shows which files Git sees and what state they are in — untracked, modified, or staged. Run it often. It is the most useful orientation command in Git.

Git will list Get-ServerInfo.ps1 as an untracked file. This means Git sees it but is not yet recording changes to it. Stage the file to prepare it for the commit:

git add Get-ServerInfo.ps1
Note: Staging is a deliberate two-step design. git add moves files into the staging area — a preparation zone. Only staged files are included in the next commit. This lets you commit specific files even when multiple files have changed at once.

To stage all changed files at once:

git add .

Commit the staged file:

git commit -m "Add Get-ServerInfo script"

Write commit messages in the imperative form. Describe what the commit does, not what you did. Good: Add Get-ServerInfo script. Bad: added stuff, update, fix.

View the commit history:

git log --oneline

[Screenshot placeholder — git log --oneline output showing first commit hash and message]

Common git commit flags:

FlagDescriptionWhen to use
-m "message"Inline commit messageEvery standard commit
-aStage all tracked modified files and commit in one stepSkip git add for already-tracked files
--amendModify the most recent commitFix a typo in the last message or add a forgotten file

Tracking Changes

Once files are committed, Git tracks every subsequent change. Before committing again, you can inspect exactly what changed.

Modify the script to add a comment:

Add-Content "Get-ServerInfo.ps1" "`n# Last modified: $(Get-Date -Format 'yyyy-MM-dd')"

See what changed before staging:

git diff
Note: git diff shows the exact lines added and removed since the last commit. Lines starting with + are additions, lines starting with - are removals. Review this before every commit to catch unintended changes.

Run git status again — the file now shows as modified. Stage and commit the change:

git add Get-ServerInfo.ps1
git commit -m "Add modification date comment to Get-ServerInfo"

Common git diff flags:

FlagDescriptionWhen to use
(no flag)Diff between working directory and staging areaBefore git add
--stagedDiff between staging area and last commitAfter git add, before git commit
HEAD~1Diff between current state and the previous commitQuick review of what the last commit changed

Connecting to GitHub

Create a repository on GitHub

Log into GitHub and create a new repository. Set the name to AdminScripts and the visibility to Private — recommended for any repository containing scripts with environment-specific details. Do not initialize with a README, since you already have a local repository with commits.

[Screenshot placeholder — GitHub new repository creation page with Private selected]

SSH vs HTTPS

Git connects to GitHub using two protocols. Choose one before adding the remote.

MethodAuthenticationBest for
HTTPSUsername + personal access tokenQuick setup, corporate proxy environments
SSHSSH key pair stored on your machineDaily use — no repeated credential prompts

SSH is recommended for regular use. Once configured, you authenticate silently on every push and pull.

Set up SSH on Windows

Generate an SSH key pair:

ssh-keygen -t ed25519 -C "your@email.com"

Accept the default file location. Set a passphrase or leave blank.

Start the SSH agent and add your key:

Get-Service ssh-agent | Set-Service -StartupType Automatic
Start-Service ssh-agent
ssh-add "$env:USERPROFILE\.ssh\id_ed25519"

Copy your public key to the clipboard:

Get-Content "$env:USERPROFILE\.ssh\id_ed25519.pub" | Set-Clipboard

Go to GitHub → Settings → SSH and GPG keys → New SSH key. Paste the key and save.

Test the connection:

ssh -T git@github.com

Expected output:

Hi [your-username]! You've successfully authenticated, but GitHub does not provide shell access.
Warning: Never share or commit your private key file (id_ed25519). Only the public key (id_ed25519.pub) goes to GitHub. The private key stays on your machine.

Connect your local repository to GitHub

git remote add origin git@github.com:[your-username]/AdminScripts.git

Push your commits to GitHub:

git push -u origin main
Note: The -u flag sets origin/main as the upstream tracking branch. After this first push, you can use git push and git pull without specifying the remote and branch every time.

Common git push flags:

FlagDescriptionWhen to use
-u origin mainPush and set upstream tracking branchFirst push of a new branch
--tagsPush local tags to remoteWhen releasing versioned scripts
--forceOverwrite remote historyOnly when you are certain — this is destructive

Working with Branches

A branch is an independent line of development. It lets you work on a change — a script rewrite, a new feature, a config update — without touching the stable version until you are ready to merge.

Practical scenario: You want to extend Get-ServerInfo.ps1 with disk usage reporting, but the current version is already in use on a server. Create a branch, develop and test there, then merge only when it works.

List existing branches:

git branch

Create a new branch and switch to it:

git checkout -b feature/add-disk-info
Note: git checkout -b creates a new branch and switches to it in one step. The branch starts as an exact copy of the current branch. All changes you make stay isolated here until you merge.

Make changes and commit on the branch:

# Add disk information to the script
Add-Content "Get-ServerInfo.ps1" @'

# Disk usage for all fixed drives
Get-PSDrive -PSProvider FileSystem | Where-Object { $_.Used -gt 0 } |
    Select-Object Name,
        @{N="Used_GB"; E={[math]::Round($_.Used/1GB,2)}},
        @{N="Free_GB"; E={[math]::Round($_.Free/1GB,2)}} |
    Format-Table -AutoSize
'@

git add Get-ServerInfo.ps1
git commit -m "Add disk usage section to Get-ServerInfo"

Switch back to main and merge the branch:

git checkout main
git merge feature/add-disk-info

Delete the branch after merging — it has served its purpose:

git branch -d feature/add-disk-info

Common git branch flags:

FlagDescriptionWhen to use
(no flag)List local branchesCheck what branches exist
-dDelete a merged branchCleanup after successful merge
-DForce delete an unmerged branchDiscard abandoned work
-aList local and remote branchesSee the full picture including GitHub branches

Common git checkout flags:

FlagDescriptionWhen to use
branch-nameSwitch to an existing branchMove between branches
-b branch-nameCreate and switch in one stepStart new work
-- filenameDiscard changes in a specific fileUndo uncommitted edits to one file

Pulling and Staying in Sync

When working across multiple machines or with colleagues, your local repository will fall behind the remote. Keeping in sync is a core Git habit.

Fetch remote changes without applying them:

git fetch
Note: git fetch downloads changes from the remote repository but does not touch your working directory. It updates your remote-tracking references so you can inspect what changed before deciding to merge. Use it when you want to check what others pushed without disrupting your current work.

Pull remote changes and apply them immediately:

git pull

git pull is shorthand for git fetch followed by git merge. It downloads and immediately applies changes to your current branch.

Check upstream tracking status for all branches:

git branch -vv

This shows each local branch alongside its remote tracking branch and whether you are ahead, behind, or in sync with the remote.

Warning: If you have local uncommitted changes and run git pull, Git may refuse or report a conflict. Commit or stash your changes first before pulling.

Common git pull flags:

FlagDescriptionWhen to use
(no flag)Fetch and merge from tracked remote branchStandard daily sync
--rebaseFetch and rebase instead of mergeKeep a cleaner, linear commit history
origin mainPull from a specific remote and branchWhen upstream tracking is not set

Useful Everyday Commands

git log

git log --oneline --graph

Shows a compact history with branch topology. Useful for understanding what happened and when. Add --all to include remote branches in the graph.

[Screenshot placeholder — git log --oneline --graph output with branch merges visible]

git stash

# Save uncommitted changes temporarily
git stash

# Restore them when ready
git stash pop
Note: git stash temporarily saves your uncommitted changes and restores the working directory to the last commit state. git stash pop brings them back. Use this when you need to switch branches quickly without committing unfinished work.

.gitignore

A .gitignore file tells Git which files and folders to never track. Create one in your project root:

@'
# Log and temporary files
*.log
*.tmp

# Output and export folders
output\
exports\

# Editor and OS metadata
.vscode\
Thumbs.db
desktop.ini

# Sensitive files - never commit these
*.key
*.pfx
secrets.ps1
credentials.ps1
'@ | Set-Content ".gitignore"

git add .gitignore
git commit -m "Add .gitignore for logs, exports, and sensitive files"
Never commit credentials: Passwords, API keys, and secrets have no place in a Git repository — even a private one. Use .gitignore to exclude sensitive files before they are ever staged. If credentials were committed by mistake, consider them compromised and rotate them immediately.

Quick reference

CommandWhat it does
git statusShow working directory and staging area state
git add .Stage all changes in the current directory
git commit -m "msg"Commit staged changes with a message
git pushPush commits to tracked remote branch
git pullFetch and merge changes from remote
git log --onelineCompact commit history
git diff --stagedShow staged changes before committing
git stashSave uncommitted changes temporarily
git stash popRestore stashed changes
git branch -aList all local and remote branches

Tips for Sysadmins

Add PowerShell aliases for the commands you use most. Add these to your PowerShell profile ($PROFILE):

# Git shortcuts - add to $PROFILE
function gs { git status }
function ga { git add . }
function gp { git push }
function gl { git log --oneline --graph }

Store only text files. Git is designed for text. Store scripts, configs, YAML, JSON, and Markdown. Do not store compiled binaries, installers, or large files — they bloat the repository history permanently and cannot be undone without rewriting history.

Run git status constantly. Make it a habit before and after every operation. It costs nothing and prevents most common mistakes.

Commit early, commit often. Small commits are easier to understand, review, and revert. A commit that does one thing is better than a commit that does ten.

Use branches for anything non-trivial. Even for solo work. A branch costs nothing and gives you a safe space to experiment without touching a working version.


Related Resources

Official documentation