Barbarian Meets Coding
barbarianmeetscoding

WebDev, UX & a Pinch of Fantasy

12 minutes readpowershell

Basic PowerShell

PowerShell is a .NET based CLI where everything is a .NET object.

Commands in PowerShell are in the form of cmdlets (Command-lets) which have a Verb-Noun syntax.

Some of the most common verbs are Get, Set, Out, Start, Stop, Restart, Add and some of the most common nouns are Help, Command, Service, Computer, Location and ChildItems which end up in cmdlets like: Get-Help, Get-Command, Get-ChildItems, etc.

Introduction to PowerShell

In order to feel familiar to both DOS and UNIX users PowerShell provides support for the common DOS and UNIX commands as illustrated below:

{% codeblock lang:powershell %}

Basic DOS commands work as usual (via aliasing)

dir copy a.txt b.txt

Basic Linux/UNIX commands work as well (via aliasing)

ls cp a.txt b.txt

You can find the list of aliases by executing

get-alias

We can see that both dir and li map to get-childitem

get-childitem

{% endcodeblock %}

PowerShell achieves this by taking advantage of alias. If you want to set your own alias you can use different methods:

  • The set-alias cmdlet allows you to set per session (they will disappear when you close the PowerShell command line)
  • You can export your aliases to a file using export-alias, and import them later using import-alias

{% codeblock lang:powershell %}

set-alias set-alias list get-childitem export-alias C:\myalias.csv list export-alias C:\myalias.csv l* # you can also use wild characters import-alias C:\myalias.csv

{% endcodeblock %}

Using PowerShell Integrated Scripting Environment (ISE)

Microsoft provides the PowerShell ISE to ease producing complex PowerShell scripts. This tool provides a more IDE-like experience with debugging support.

You can either run whole scripts (F5) or only the current selection (F8).

.NET and PowerShell

{% codeblock lang:powershell %}

.Net is everywhere within PowerShell

$h = “Hello World” $h $h.Length $h.GetType() {% endcodeblock %}

Note how variables being with $ in PowerShell.

PowerShell Basic Commands

Exploring PowerShell

{% codeblock lang:powershell %}

Get-Command

Retrieves a list of all system commands that are loaded in your current environment

Get-Command

Can expand by searching for just a verb or a noun

Get-Command -verb “get” Get-Command -noun “service”

Get-Help

It can be used to explain a command

Get-Help Get-Command Get-Help Get-Command -examples Get-Help Get-Command -detailed Get-Help Get-Command -full

Most commands can also be passed a -? parameter to get help

Get-Command -? {% endcodeblock %}

Moving Around the File Tree

{% codeblock lang:powershell %}

Get-ChildItem

Lists all items in the current path

Get-ChildItem

Set-Location

Change the current path

Set-Location c:\GitHub Set-Location “c:\GitHub\Awesome Project”

You can combine cmdlets via pipelining to create more complex and powerful commands

Get-ChildItem | Where-Object { $_ Length -gt 100kb }

where $_ is the current object being iterated

and where -gt means greater than, -lt less than, -eq equal

Also note the 100kb that could be 100mb or 100gb

Get-ChildItem | Where-Object { $_ Length -gt 100kb } | Sort-Object Length

You can break commands up by leaving the pipe as the last character on each line

Get-ChildItem | Where-Object { $_ Length -gt 100kb } | Sort-Object Length

Format-Table

Use it to specify columns in the output and improve formatting

Get-ChildItem | Where-Object { $_ Length -gt 100kb } | Sort-Object Length | Format-Table -Property Name, Length -AutoSize

Select-Object

You can use Select-Object to retrieve certain properties from an object

Get-ChildItem | Select-Object Name, Length {% endcodeblock %}

PowerShell Providers

PowerShell uses the concept of Providers. A provider is a .NET library that provides a standard interface through which we can navigate through whatever object that provider represents. By using this concept, we can navigate through any object using the same commands we are comfortable with.

Each Provider reveals itself to us through what is known as Drives. It is through these drives that we can navigate and retrieve data.

{% codeblock lang:powershell %}

List default providers

Get-PSProvider Get-PSDrive

Move to the END drive to look at the environment variables

Set-Location env: Get-ChildItem Get-ChildItem | Format-Table -Property Name, Value -AutoSize

Move to the ALIAS drive to look at your alias

Set-Location alias: Get-ChildItem {% endcodeblock %}

You are not limited to the built-in providers. You can add new providers through a concept called Snap-in‘s. Once you have loaded new providers via snap-in’s, you will see that you have new drives that you can use.

{% codeblock lang:powershell %}

Get-Snapin

Show list of snap-ins

Get-PSSnapin ## show list of snap-ins that are currently loaded Get-PSSnapin -Registered ## Show list of snap-ins that are registered but not loaded

Add-PSSnapin

Loads snap-ins in the current environment

Add-PSSnaping SqlServerCmdletSnapin100 Get-PSSnaping -Name “Sql*” # Validate they are loaded

Using the new SQLServer drive

Set-Location SQLSERVER: Get-ChildItem Get-ChildItem | Select-Object PSChildName

Change the location to the SQL root to get all available servers

Set-Location SQL Get-ChildItem

Change location to server

Set-Location A-SERVER Get-ChildItem

Change location to default instance

Set-Location DEFAULT Get-ChildItem

Change location to the list of databases

Set-Location Databases Get-ChildItem | Select-Object PSChildName

Change location to a database

Set-Location Northwind Get-ChildItem

Change to the object tables

Set-Location Tables Get-ChildItem

Remove-PSSnapin

You can use Remove-PSSnapin to remove Snap-ins from your current environment

Remove-PSSnapin SqlServerCmdletSnapin100 {% endcodeblock %}

It is easy to appreciate that the concept of providers results in a huge extensibility point for PowerShell.

PowerShell Variables

Basic Overview

Using Variables in PowerShell

{% codeblock lang:powershell %}

All variables start with $

$hi = “Hello World” $hi # print variable. Syntactic sugar for: Write-Host $hi $hi.GetType() # String

Types are mutable

$hi = 10 $hi.GetType() # Int32

You can force strongly typed variables by using this notation

[System.Int32]$myInt = 42 $myint $myint.GetType() $myint = “Obliteration!!!! RuntimeException”

Although you can use the full type name, PowerShell provides shortcuts for the most common types

[int] $i = 42 [string] $s = “Hello!”

Others include short, float, decimal, single, bool, byte…

Not just variables are types

(42).GetType() “I am Awesome”.ToUpper() “I am Awesome”.Contains(“Awesome”) {% endcodeblock %}

Performing Comparison Operations

{% codeblock lang:powershell %} $var = 42

PowerShell uses these operators for comparisons because it reserves the common ones for other operations

$var -gt 40 # instead of > $var -lt 40 # instead of < $var -eq 42 # instead of = $var -ne 24 # instead of != $var -ge 11 # instead of >= $var -le 22 # instead of <=

For comparing strings we can use

$var = “hello” $var -Like “h*” # Like wildcard pattern matching $var -NotLike “hola” # Not Like $var -Match “hell.” # Matches based on regular expressions $var -NotMatch “hola” # Not-Matches based on regular expressions {% endcodeblock %}

Performing Calculations

{% codeblock lang:powershell %}

Like in any other language

$var = 42 + 22 * 3 / 1

Supports unary operators

$var++ $var—

Beware of Implicit type conversions

“42” -eq 42 # True 42 -eq “42” # True

Whatever is on the right is converte to the data type on the left

42 -eq “042” # True “042” -eq 42 # False {% endcodeblock %}

Using the Variable Cmdlets

{% codeblock lang:powershell %}

Any time you operate with variables

Behind the scenes, PowerShell is calling Cmdlets

New-Variable

Lets you create new variables

New-Variable -Name var -Value 42 $var

Get-Variable

Lets you display a variable and its value

Get-Variable var -valueonly Get-Variable var Get-Variable # Shows all variables

Set-Variable

Assigns a new value to an existing variable

Set-Variable -Name var -Value 24

Clear-Variable

Clear the contents of a variable like $var = $null

Clear-Variable -Name var

Remove-Variable

Completely removes variable

Remove-Variable -Name var {% endcodeblock %}

Strings

{% codeblock lang:powershell %}

Define strings as usual with "" or ”

“Hello World” ‘Hello World’ “Hi ‘Hello World’” “Hi ""Hello World"" ”

For escape sequences use the backtick `

“Hello n World" # new line "Hello World nr" # CLRF "Hello t World” # tab

When you want to create large blocks of text you use here-strings

The @” must be the last characters in the line

$hello = @”
Hello This is Jaime How are you doing? “@

The ”@ must be the first characters in the line

String interpolation

$you = “Malin” “Hello $you, How are you doing?” # Hello Malin, How are you doing?

You can escape interpolation as usual with the backtick `

String interpolation only works with string defined between "" and not ”

You can use PowerShell expressions within strings. They need to be wrapped in $()

“There are $((Get-Children).Count) items in this folder $(Get-Location)”

You can do string formatting with a C#-like syntax

in C#

$coins = 10 [string]::Format(“There are {0} coins left.”, $coins)

PowerShell Syntactic Sugar

$lives = 2 “There are {0} coins left.” -f $coins “There are {0} coins and {1} lives left. You have lost” -f $coins, $lives

You can compare strings using wildcards

“Hello World” -like “Hello*” “Hello World” -like “Hola Mundo” “Hello World” -like “?ello World” “Hello World” -like “Hello*[a-e]”

You can match strings using regular expressions

“111-111-1111” -match “[0-9]{3}-[0-9]{3}-1111”

{% endcodeblock %}

Arrays

{% codeblock lang:powershell %}

Define arrays easily in PowerShell as

$array = “one”, “two”, “three” $array[0] # display first item within array $array # display all items ina rray $array.GetType() # returns Object[]

The format Array creation syntax is

$array = @(“one”, “two”, “three”) $array = @() # this is an empty array

You can use a shorthand syntax to load arrays with numeric values

$array = 1..10 # Array with numbers from 1 to 10

Operations on arrays

$numbers = 1..5 $numbers.Count $numbers -contains 42 $numbers -notcontains 24 {% endcodeblock %}

Hast Tables

{% codeblock lang:powershell %}

Define hashtables as

$hash = @{“Key = “Value”; “Name” = “Jaime”; “Surname” = “González García”} $hash # Display all contents $hash[“Name”] # Gets the value for “Name” that is “Jaime” $hash.”Name” # As above $mykey = “Name” $hash.$mykey # You can use variables as keys $hash.$(“Name”) # Or expressions

Adding and removing values

$hash[“Age”] = “29” # Add $hash.Remove(“Age”) # Remove

List key or values

$hash.Keys $hash.Values

Check if a key or values exist

$hash.Contains(“Age”) $hash.ContainsValue(“Jaime”) $hash.Keys -contains “Age” $hash.Values -contains “Jaime” {% endcodeblock %}

Built-in Variables

{% codeblock lang:powershell %} $true $false $NULL $pwd # Current directory $Home # Home directory $host # info about machine $PID # Process ID for Shell $PSVersionTable # Information about the current version of PS $_ # Current Object Get-ChildItem | Where-Object { $_.Name -like “*.ps1”} {% endcodeblock %}

Resources


Jaime González García

Written by Jaime González García , dad, husband, software engineer, ux designer, amateur pixel artist, tinkerer and master of the arcane arts. You can also find him on Twitter jabbering about random stuff.Jaime González García