Getting Started - Basics and Environment Customization

Welcome to my Getting Started with Windows PowerShell series!

We will be exploring:

Update 4/24/19: Look for some of these series pages to get revamped. PowerShell Core is making waves! If you haven’t checked it out, you should.

Looking to get started with Visual Studio Code + PowerShell? Check out this post:

Just What is PowerShell?

PowerShell is a framework provided by Microsoft that provides a platform for automation, general scripting, and well just about anything you can imagine doing with it. It's based on .NET, and has hooks into pretty much anything Windows can do. There are a lot of new things introduced with PowerShell, and it is ever evolving. You can also still use old commands you're familiar with like ping, but you have much more powerful options at your finger tips (like Test-Connection).  If you'd like a deeper dive into what PowerShell is, check out Microsoft's Scripting Guy's post, here.

PowerShell is an object-oriented programming language with a ton of features. Everything we work with PowerShell is an object one way or another. What this means is we can get information from it via properties, and take actions with it via methods.

You can use PowerShell in two distinct ways.

PowerShell also makes it easy to create your own custom objects, more on that in another post!

PowerShell Versions

Here's the breakdown: 

  • Windows 7 comes with Windows PowerShell version 2.0 installed by default. If you're still running Windows 7, and want to try out the latest version of PowerShell (currently 5.0), you'll need to install the Windows Management Framework update

  • Windows 8 versioning is a bit strange

  • You can run PowerShell 2.0-3.0

    • You cannot run PowerShell 4.0+

  • Windows 8.1 let's you run version 5.0

  • Windows 10 comes with PowerShell version 5.0 installed by default, and if you're all updated (which it is hard not to be with how Windows 10 updates work...) version 5.1+ will be available

If for some reason you're using a machine running Windows XP, PowerShell 2.0 will work with this download.

PowerShell Core

PowerShell core heralds the open sourcing of PowerShell, check it out on Github! You can even run it on your Raspberry Pi.

How can I check what version I have?

Well, first you'll have to open PowerShell

  1. Hit the Windows key or click the Start icon/button.

  2. Type in 'PowerShell', and select 'Windows PowerShell'

I recommend pinning PowerShell to your taskbar as well. This makes it really easy to launch.

PowerShell stores the version in a special variable dedicated to host information. This variable is aptly named $host. To see the value of this variable, type $host into your console and press enter. You should see a similar result to this:

If you simply wanted to return the latest version, try typing $host.Version to display the Version property only.

Finally, if you want to just return the Major Version, use $host.Version.Major.

For a more detailed write up on versions and supported OSs, see this post at 4sysops.

How PowerShell Works

PowerShell works by executing commands, and then provides you a way to interpreting the results. Everything in PowerShell either is or becomes an object in one way or another. Think of an object in this instance as something you can take action on via methods, and get information from via properties.

Let's learn some more basics before we go about customizing our environment. Don't worry too much about grasping terminology! With PowerShell especially, learning by doing is where it's at.

'Hello World'

Even the simplest thing in PowerShell, such as 'Hello World',  becomes an object you can take action on. Go ahead and type the following command in PowerShell:

'hello world'.Length

The above example should return 11, as seen below.

Since 'Hello World' is an object, we can pipe it via "|" to Get-Member to see what we can do with it. Piping in PowerShell is the act of adding the "|" character to take the results of the input before it, and pass that over to the next command. Let's go ahead and run this:

'Hello World' | Get-Member

You should see the following:

You can see that the object Type is of System.String, and below that the various methods and properties. To use them, simply add a dot after 'Hello World' and specify the one you'd like to use. For instance, I wonder what ToUpper does. Let's see!

'Hello World'.ToUpper

Hmm... that looks a little weird. That's because to execute the method, you need to put a pair of parentheses after it. Sometimes you can include different values in the parentheses to include overload options. What we're seeing here is the definition of those options for .ToUpper(). For this example we can just use:

'Hello World'.ToUpper()

Get-Member will likely be one of the handiest cmdlets you will use. It lets you know what properties and methods the object contains.

Now that we've covered some basics, let's get back to checking out...

Ping vs Test-Connection

Let's ping google.com via PowerShell.

Ping Google.com

Alright, pretty standard! Let's see what Test-Connection Google.com does.

Test-Connection Google.com

Now that looks a little bit different. So what's so special about Test-Connection? To see what else Test-Connection can do and the options it provides, use:

Get-Help Test-Connection

Notice under REMARKS it states that I don't have the help files stored on my computer. To remedy this, right click your PowerShell icon on the taskbar, and go to Run as Administrator. Then use this command:

Update-Help

Now let's see the help for Test-Connection again!

Get-Help Test-Connection

Under the SYNTAX portion you can see that Test-Connection accepts the -ComputerName parameter. This is the one that Google.com was placed into by default. It then specifies what the input is expected to be. This parameter accepts a string, and string array. That is what the [] next to string means. Think of an array as a collection of values.

To see examples of how to run Test-Connection, type:

Get-Help Test-Connection -Examples

Variables

Let's take advantage of the fact that Test-Connection's -ComputerName parameter can accept a string array. To do this, we'll need to create a variable and add some values to it. The best way to create a string array is to use this command:

[System.Collections.ArrayList]$testArray = @()

This above code will create an empty array in the variable $testArray. Think of a variable as a container of objects.

Let's add some hosts to this array that we'll want to use with Test-Connection

$testArray.Add('192.168.1.1')
$testArray.Add('google.com')
$testArray.Add('qwertyuiop.asdf')
 

Arrays in PowerShell always start with 0, and when we use the .Add method on this array you can see it outputs the index of the element(value) we are adding. To add an element without seeing that, simply pipe $testArray.Add('yahoo.com') to Out-Null.

$testArray.Add('yahoo.com') | Out-Null

You can see it did not return the index number this time. To display the values in the array, type:

$testArray

OK! Now that we have our array setup, let's use:

Test-Connection -ComputerName $testArray

You can even use Test-Connection with conditional logic. 

if (Test-Connection Google.com) {Write-Host "Success!"} 

Since Test-Connection Google.com returned $true, it proceeds to perform the command in the script block {}.

I wonder what happens if you replace Google.com with 'qwertyuiop.asdf'...

Alright! Now that we've gone through some more of the basic concepts, it's time to...

Customize Your Environment

Open up your PowerShell console and Right Click the title bar. 

  1. Select Properties.

  2. Select the Font tab to adjust the font.

  3. Select the Colors tab to set the colors you want.

Customizing your profile

PowerShell uses profile files to automatically load a script when you start the PowerShell console.

Let's take a look at the file PowerShell uses for your current user profile on all hosts (meaning the ISE and console). We'll get into the different host types in a different post. The special variable we'll want to look at is $profile, and we'll want to see the CurrentUserAllHosts property.

$profile.CurrentUserAllHosts

It looks like the generic Dell account (my way to have a fresh instance of PowerShell) I'm using would have the profile stored in:

C:\Users\Dell\Documents\WindowsPowerShell\profile.ps1

Since the folder and file do not exist, let's use the New-Item cmdlet to create each. Be sure to change the values to match what your result was from the $profile.CurrentUserAllHosts value. Note: the file will still be profile.ps1, and only the user name should change.

New-Item -Path C:\Users\Dell\Documents\ -ItemType Directory -Name WindowsPowerShell
New-Item -Path C:\Users\Dell\Documents\WindowsPowerShell\ -ItemType File -Name profile.ps1

To auto-magically do this, you can use the following commands:

New-Item -Path "$((Get-ChildItem ENV:\UserProfile).Value)\Documents\" -ItemType Directory -Name WindowsPowerShell
New-Item -Path "$((Get-ChildItem ENV:\UserProfile).Value)\Documents\WindowsPowerShell" -ItemType File -Name profile.ps1

Now you should be able to use the Start-Process cmdlet(which opens a file with the associated handler in Windows automatically) to open and edit the profile file.

Start-Process $profile.CurrentUserAllHosts

You should now have a blank text file open with profile.ps1 as the name in the upper left.

Let's add the following code to the profile.ps1 file:
I will detail what this code does in the next post!

$foregroundColor = 'white'
$time = Get-Date
$psVersion= $host.Version.Major
$curUser= (Get-ChildItem Env:\USERNAME).Value
$curComp= (Get-ChildItem Env:\COMPUTERNAME).Value

Write-Host "Greetings, $curUser!" -foregroundColor $foregroundColor
Write-Host "It is: $($time.ToLongDateString())"
Write-Host "You're running PowerShell version: $psVersion" -foregroundColor Green
Write-Host "Your computer name is: $curComp" -foregroundColor Green
Write-Host "Happy scripting!" `n

function Prompt {

$curtime = Get-Date

Write-Host -NoNewLine "p" -foregroundColor $foregroundColor
Write-Host -NoNewLine "$" -foregroundColor Green
Write-Host -NoNewLine "[" -foregroundColor Yellow
Write-Host -NoNewLine ("{0}" -f (Get-Date)) -foregroundColor $foregroundColor
Write-Host -NoNewLine "]" -foregroundColor Yellow
Write-Host -NoNewLine ">" -foregroundColor Red

$host.UI.RawUI.WindowTitle = "PS >> User: $curUser >> Current DIR: $((Get-Location).Path)"

Return " "

}

Once you've added the content, save profile.ps1.
Now close and re-open your PowerShell console.

It should now look similar to this:

Each time you type a command the function named prompt executes and changes both the prompt (to include the current time), and the Window Title (to include the current user and directory).

In the next post I will be going over command discovery and formatting results. 

Homework

  • Try to figure out exactly how the string format operator works in the prompt function to format the time.

  • Use Get-Command to discover more PowerShell commands.

  • Find some commands to run (maybe Get-Date)? and Pipe them to Get-Member to see what properties and methods they contain.

  • Declare a variable and use that variable to use the methods and display the properties available. Hint: $time = Get-Date.

  • Further customize your profile to change up your prompt and title!

Let me know if you have any questions! Feedback is always appreciated.

-Ginger Ninja

[Back to top]