In this article, you’ll learn how to install and use Git for Windows. Specifically, you’ll combine the Git Windows client and the GitHub cloud service to keep your Windows PowerShell scripts always in sync, no matter where you work.
Latest posts by Timothy Warner (see all)

Windows systems administrators who’ve embraced Windows PowerShell have almost universally also adopted the Git source code management (SCM) technology. Git is free open-source software (FOSS) that does one thing and one thing well: tracks changes to source code files.

Even if you work in a team of one, you can still get a lot out of Git. If nothing else, distributed version control systems such as Git give you protected access to your source code from any computer. When I got into IT, the developers I worked with used centralized SCM tools such as Microsoft Visual SourceSafe (now Team Foundation Server). The weakness of centralized SCM solutions is that you had a single point of failure.

By contrast, with Git, all developers have a full copy of a tracked repository. Team members can pull changes from other team members’ repos and/or push changes to a central repo.

Enough preliminary—I want this to be a “quick and dirty” setup guide for those of you who knew you’d have to learn Git eventually but successfully put off the task until today. Let’s get started!

Installing Git for Windows

For starters, forget about mSysgit or the Posh-Git project—we finally have a full-featured Git client for Windows. You can download the software from either of the following websites:

I’ll walk you through the important installation dialog box choices and give you suggestions.

Particularly, Git for Windows includes useful extensions, as shown in the following dialog box. The Git Bash environment is particularly cool; it’s a Cygwin-like wrapper that allows you to run Linux Bash commands. (Let’s face it, Git was historically a Linux program. In fact, the inventor of Linux, Linus Torvalds, also invented Git.)

Git for Windows includes useful shell extensions

Git for Windows includes useful shell extensions

Speaking of Git Bash, I’d recommend that you integrate the Git environment with the Windows console. And, yes, in case you wondered, the integration applies to both Cmd.exe and PowerShell.exe.

Integrating Git Bash with the Windows console

Integrating Git Bash with the Windows console

One of the most important choices in Git for Windows is to allow the installer to add the Git tools to your system search path. This way, you can call Git from your PowerShell sessions no matter where your prompt is in the file system.

Make sure to add Git to your search path

Make sure to add Git to your search path

You may or may not know that Windows and Linux use different line-end escape characters. Your safest bet here is to choose to checkout Windows and commit UNIX line endings. This makes your PowerShell script code easily portable between Windows and, say, OS X systems.

Specifying line endings

Specifying line endings

Setting up your development environment

I’m running Windows PowerShell v5 RTM on a Windows 8.1 workstation.

PS C:\Users\Tim> $PSVersionTable.PSVersion

Major  Minor  Build  Revision
-----  -----  -----  --------
5      0      10586  51

Let’s say that we plan to create a big function that will assemble common system configuration information for a given computer. Because we want to see our revision history, as well as make the code available to other developers, we’ll use Git to track our script files.

I created a folder named get-sysinfo inside my home folder, and a file named get-sysinfo.ps1 within the folder.

Open your new script file in the Windows PowerShell ISE and add the following code:

# Get installed .NET Frameworks
Write-Host 'Installed .NET Framework Components' -ForegroundColor Yellow
Get-ChildItem 'HKLM:\SOFTWARE\Microsoft\NET Framework Setup\NDP' -Recurse |
Get-ItemProperty -Name Version,Release -ErrorAction 0 |
Where-Object { $_.PSChildName -match '^(?!S)\p{L}'} |
Select-Object -Property @{N='.NET Component';E={$_.PSChildName}}, @{N='Version';E={$_.Version}} |
Sort-Object -Property Version -Descending |
Format-Table -AutoSize

We’re almost ready to instruct Git to start tracking our project.

Configuring Git

Git tracks source code changes by (a) creating a unique hash value for each commit, and (b) associating each commit with a user identity. Open a fresh, elevated PowerShell console and let’s identify ourselves to Git. Run the following commands, substituting your e-mail address and personal name:

git config –-global user.email “tim@4sysops.com”
git config –-global user.name “Tim Warner”

Tracking changes with Git

Open a new elevated PowerShell prompt and use cd or Set-Location to switch to the Get-sysinfo folder. Next, run git init:

PS C:\Users\Tim\get-sysinfo> git init
Initialized empty Git repository in C:/Users/Tim/get-sysinfo/.git/

Git creates the .git hidden directory to perform the metadata and change tracking. We run git status to see how our new repository looks now:

PS C:\Users\Tim\get-sysinfo> git status
On branch master

Initial commit

Untracked files:
  (use "git add <file>..." to include in what will be committed)

        get-sysinfo.ps1

nothing added to commit but untracked files present (use "git add" to track

What git status tells us is that we have one file in the folder (get-sysinfo.ps1), but at present the file isn’t tracked. Let’s use git add to change that situation, and then git status to verify:

PS C:\Users\Tim\get-sysinfo> git add .\get-sysinfo.ps1
PS C:\Users\Tim\get-sysinfo> git status
On branch master

Initial commit

Changes to be committed:
  (use "git rm --cached <file>..." to unstage)

        new file:   get-sysinfo.ps1

PS C:\Users\Tim\get-sysinfo>

Note that our script is tracked and staged for commit, but we still haven’t performed the commit that instructs Git to snapshot the file’s content. We use (as logic dictates) git commit for that. The -m switch is highly recommended because any comment we can include that describes the commit will be helpful to you and to other project developers. The “clean” message returned by git status tells me that our repo is up to date.

PS C:\Users\Tim\get-sysinfo> git commit -m "Added file to repository."
[master (root-commit) d7f2307] Added file to repository.
 1 file changed, 8 insertions(+)
 create mode 100644 get-sysinfo.ps1
PS C:\Users\Tim\get-sysinfo> git status
On branch master
nothing to commit, working directory clean
PS C:\Users\Tim\get-sysinfo>

 Comparing changes

Re-open the get-sysinfo.ps1 script and modify it into a simple function as shown below:

function Get-DotNetVersion
{
    Clear-Host
    Write-Host 'Installed .NET Framework Components' -ForegroundColor Yellow
    Get-ChildItem 'HKLM:\SOFTWARE\Microsoft\NET Framework Setup\NDP' -Recurse |
    Get-ItemProperty -Name Version,Release -ErrorAction 0 |
    Where-Object { $_.PSChildName -match '^(?!S)\p{L}'} |
    Select-Object -Property @{N='.NET Component';E={$_.PSChildName}}, @{N='Version';E={$_.Version}} |
    Sort-Object -Property Version -Descending |
    Format-Table -AutoSize
}
Get-DotNetVersion

Run git status and Git will inform you that the get-sysinfo.ps1 file has changed. No surprise there. We can run git diff HEAD to compare changes between the current file and the state of the file at last commit. Forgive the wonky color formatting in the Git console; we can customize that, of course, but we’ll need to cover that in a future article:

PS C:\Users\Tim\get-sysinfo> git diff head
diff --git a/get-sysinfo.ps1 b/get-sysinfo.ps1
index f69865c..6d4b03f 100644
--- a/get-sysinfo.ps1
+++ b/get-sysinfo.ps1
@@ -1,8 +1,12 @@
-<U+FEFF># Get installed .NET Frameworks
-Write-Host 'Installed .NET Framework Components' -ForegroundColor Yellow
-Get-ChildItem 'HKLM:\SOFTWARE\Microsoft\NET Framework Setup\NDP' -Recurse |
-Get-ItemProperty -Name Version,Release -ErrorAction 0 |
-Where-Object { $_.PSChildName -match '^(?!S)\p{L}'} |
-Select-Object -Property @{N='.NET Component';E={$_.PSChildName}}, @{N='Version'
;E={$_.Version}} |
-Sort-Object -Property Version -Descending |
-Format-Table -AutoSize
\ No newline at end of file
+<U+FEFF>function Get-DotNetVersion
+{
+    Clear-Host
+    Write-Host 'Installed .NET Framework Components' -ForegroundColor Yellow
+    Get-ChildItem 'HKLM:\SOFTWARE\Microsoft\NET Framework Setup\NDP' -Recurse |
+    Get-ItemProperty -Name Version,Release -ErrorAction 0 |
+    Where-Object { $_.PSChildName -match '^(?!S)\p{L}'} |
+    Select-Object -Property @{N='.NET Component';E={$_.PSChildName}}, @{N='Vers
ion';E={$_.Version}} |
+    Sort-Object -Property Version -Descending |
+    Format-Table -AutoSize
+}
PS C:\Users\Tim\get-sysinfo>

To be sure, the previous output isn’t the easiest to parse. You should check out some of the myriad Git GUI front-ends to make file comparisons easier:

  • Git Gui
  • Atlassian Source Tree
  • GitHub Desktop

Finally, we’ll add the file to our commit “stage” and make a second commit. The dot shortcut adds all files in the present working directory to the staged area:

git add .
Git commit -m “Changed the static code into a function.”

Pushing our project to GitHub

We have plenty of cloud-based public Git repositories available to us (Atlassian Bitbucket springs to mind), but my favorite by far is GitHub. Go there and create a free user account. You can host as many public repositories as you want for free. If you need private repos, then you’ll have to pay for a site subscription.

From your GitHub home page, click New repository and deploy a new repo to host our get-sysinfo project.

Creating a new public Git repository

Creating a new public Git repository

Do you see the highlighted options in the above screen capture? Normally it’s fine to let GitHub create preliminary documentation and whatnot in your public cloud repo. But, in this case, we’re going to push content from our local computer and we don’t want conflicts.

On the next page, you’ll see instructions for adding README and LICENSE files. We’re concerned with our repository .git URL; copy that to the clipboard to prepare ourselves for the next step.

Copying our repo URL

Copying our repo URL

We run git remote add to add a remote repository. We can then run git remote -v to verify:

PS C:\Users\Tim\get-sysinfo> git remote add origin https://github.com/timothywarner/get-sysinfo.git
PS C:\Users\Tim\get-sysinfo> git remote -v
origin  https://github.com/timothywarner/get-sysinfo.git (fetch)
origin  https://github.com/timothywarner/get-sysinfo.git (push)
PS C:\Users\Tim\get-sysinfo>

We use git push to upload our full local repository to the empty one waiting in the GitHub cloud:

PS C:\Users\Tim\get-sysinfo> git push origin master
Username for 'https://github.com': tim@4sysops.com
Password for 'https://tim@4sysops.com@github.com':
Counting objects: 6, done.
Compressing objects: 100% (4/4), done.
Writing objects: 100% (6/6), 863 bytes | 0 bytes/s, done.
Total 6 (delta 1), reused 0 (delta 0)
To https://github.com/timothywarner/get-sysinfo.git
 * [new branch]      master -> master
PS C:\Users\Tim\get-sysinfo>

We’ll finish by going back to GitHub and refreshing our repo page. Done and done!

Now our repo lives in the cloud and on our local computer.

Next steps

If you’re the curious sort like I am, then you probably have all sorts of questions:

Those are outstanding questions because we literally barely scratched the surface of what’s possible with Git. Let us know in the comments what coverage you’d like to see from us at 4sysops in the future.

In the meantime, I’ll leave you with a few key documentation resources to help you on your Git/PowerShell journey:

0 Comments

Leave a reply

Your email address will not be published.

*

© 4sysops 2006 - 2023

CONTACT US

Please ask IT administration questions in the forums. Any other messages are welcome.

Sending

Log in with your credentials

or    

Forgot your details?

Create Account