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/
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
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
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:
| Flag | Description | When to use |
|---|---|---|
-m "message" | Inline commit message | Every standard commit |
-a | Stage all tracked modified files and commit in one step | Skip git add for already-tracked files |
--amend | Modify the most recent commit | Fix 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
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:
| Flag | Description | When to use |
|---|---|---|
| (no flag) | Diff between working directory and staging area | Before git add |
--staged | Diff between staging area and last commit | After git add, before git commit |
HEAD~1 | Diff between current state and the previous commit | Quick 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.
| Method | Authentication | Best for |
|---|---|---|
| HTTPS | Username + personal access token | Quick setup, corporate proxy environments |
| SSH | SSH key pair stored on your machine | Daily 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.
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
-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:
| Flag | Description | When to use |
|---|---|---|
-u origin main | Push and set upstream tracking branch | First push of a new branch |
--tags | Push local tags to remote | When releasing versioned scripts |
--force | Overwrite remote history | Only 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
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:
| Flag | Description | When to use |
|---|---|---|
| (no flag) | List local branches | Check what branches exist |
-d | Delete a merged branch | Cleanup after successful merge |
-D | Force delete an unmerged branch | Discard abandoned work |
-a | List local and remote branches | See the full picture including GitHub branches |
Common git checkout flags:
| Flag | Description | When to use |
|---|---|---|
branch-name | Switch to an existing branch | Move between branches |
-b branch-name | Create and switch in one step | Start new work |
-- filename | Discard changes in a specific file | Undo 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
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.
git pull, Git may refuse or report a conflict. Commit or stash your changes first before pulling.
Common git pull flags:
| Flag | Description | When to use |
|---|---|---|
| (no flag) | Fetch and merge from tracked remote branch | Standard daily sync |
--rebase | Fetch and rebase instead of merge | Keep a cleaner, linear commit history |
origin main | Pull from a specific remote and branch | When 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
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"
.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
| Command | What it does |
|---|---|
git status | Show 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 push | Push commits to tracked remote branch |
git pull | Fetch and merge changes from remote |
git log --oneline | Compact commit history |
git diff --staged | Show staged changes before committing |
git stash | Save uncommitted changes temporarily |
git stash pop | Restore stashed changes |
git branch -a | List 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