Click here to Skip to main content
11,436,156 members (62,182 online)
Click here to Skip to main content

A PowerShell Introduction

, 4 Oct 2014 CPOL
Rate this:
Please Sign up or sign in to vote.
PowerShell is a very powerful tool, yet it's difference to the classic DOS command prompt gives you a hard time if you are used to the CMD. This article shall guide you into the World of PowerShell and give you an easy start.

Introduction

PowerShell is the better Command Prompt. It allows you to use any .Net functionality and access a lot of Windows' not-so-obvious functionality which were difficult to access with the CMD. PowerShell is based on .Net 2.0 and connects the philosophy of Pipes and Filters (known from Unix Shells) with the paradigm of object orientated programming.

The core of the PowerShell is based on small functionality units, called Cmdlets ("command-lets"). A list of the Cmdlets can be retrieved this Microsoft Technet page.

Background - Syntax

The syntax of the scripting language used for Powershell Scripts has its own syntax. This chapter gives you a brief overview over the syntax and removes some of the traps a PowerShell script hides in it.

Variables and Constants

#Variables are defined with a leading '$':
$programFilesX86 = (${env:ProgramFiles(x86)}, ${env:ProgramFiles} -ne $null)[0]

The above example sets the variable "programFilesX86" to the path of the program files folder for x86 programs. Because the folder doesn't exist on x86 platforms, the variable is set to the ordinary program files directory if the x86 folder isn't available.

#Constants are also defined with a leading '$' - 
#To distinguish them from variables, they shall be written in all-capital letters.
$CONSTVAL = "This value can't be changed"
Set-Variable CONSTVAL -option ReadOnly 

Even though not needed by interpreter specifications, I recommend you to write constants in all-capital letters to distinguish them from variables.

Functions

PowerShell script files are interpreted and if a method is called which isn't read by the interpreter before it is called, PowerShell will encounter an error. The best way to avoid this error trap is to define a method called "Main" at the top, and then define a jump to this very method at the end of the file:

function main{
   #main function, as known from classic structured programs.
   myFunction
}

function myFunction{
   Write-Host "myFunction was called"
}

main #Jump to execute main

The example below is supposed to do the exact same, but will not be able to run because the function "myFunction" isn't interpreted at the time it is called.

myFunction #Error - myFunction wasn't read yet, but is already called

function myFunction{
   Write-Host "myFunction was called" #will never be reached
}

Basic commands

File System

As the Command Prompt already did, PowerShell provides a vast amount of Cmdlets to access the file system and modify files and directories.

Copy a File

Files can be copied using the Copy-Item Cmdlet, where the first parameter specifies the source file and the second parameter specifies the source file's full path:

Copy-Item -Path "C:\Source\Powershell" -Destination "C:\Testumgebung"

The copy process can be made recursive by adding the -Recures parameter at the end of the command:

Copy-Item -Path "C:\Source\Powershell" -Destination "C:\Testumgebung" -Recurse

Get File or Folder information

File or folder information can be obtained using the Get-Item Cmdlet:

Get-Item -Path "C:\"

To get information about the child items of a path, you can either use Get-Item with an added wildcard or Get-ChildItem:

Get-Item -Path "C:\*"
Get-ChildItem -Path "C:\"

Both Cmdlets return details on the child items of C:\:

Remove a file or a directory

Remove-Item -Path "C:\Source\Test1\*.txt" -Recurse -Force

The -Recurse parameter can only be applied to files, while -Force also deletes locked files. In the above shown parametrization, any *.txt file will be removed from C:\Source\Test1 and its subfolders.

Copy a file or a directory

Copy-Item -Path "C:\Source\*.txt" -Destination "C:\Source\Textfiles" -Recurse

This command copies any *.txt file from C:\Source and its subfolders to C:\Source\Textfiles, and the sub folder structure remains unchanged.

Interaction with Processes

PowerShell provides a vast amount of Cmdlets to help you analyze and manipulate running processes.

You can start a new process with almost any possible option:

Start-Process powershell.exe

would start a new PowerShell instance. Start-Process is a mighty Cmdlet and does provide a lot of parameters. A list of all parameters can be found at this Microsoft Technet Homepage.

To get a list of all running processes on your system, you can use

Get-Process

This displays a list of all running processes, including some additional information:

Of course you can search for a very specific process by it's name:

Get-Process powershell

This behavior can be extended by searching for more than one process name, for example PowerShell and the Windows Explorer:

Get-Process powershell,explorer

You get the idea - Any number of process names can be checked that way. In case you are looking for a process which isn't running, PowerShell will return an error (e.g. throw). What you might haven't known yet is that the usage of wildcards is allowed for the process name, means that

Get-Process power*

will return every running process which starts with "power". Those who happen to know the WMI class Win32_Process may have recognized that all the demonstrated things can be done easily by this class. But PowerShell can do more: WMI doesn't expose properties such as company or product version, but PowerShell does. In the following example, Get-Process gets piped through the Select-Object Cmdlet, filtering out any information except the process name, product version, and the company:

Get-Process powershell | Select-Object name,productversion,company

Now you ask yourself how you are supposed to know which properties are available through get-process, don't you? You can find it out by yourself. The following line pipes get-process through get-member and displays all available members:

Get-Process | Get-Member

Try it out by yourself - You'll get a very long list of Members, and you are free to use all of them.

Of course you will sooner or later encounter the situation that you need to stop a running process - Use the stop-process Cmdlet to do it. It accepts either a process id or process name as parameter:

Stop-Process 23498
Stop-Process -processname notepad

Use .Net classes within your PowerShell Script

The following function starts a process using the .Net System.Diagnostics namespace. Of course the same can be achieved by simply using the Start-Process Cmdlet, but it gives you a good start on the syntactically correct way to use .Net classes in your PowerShell Script.

function StartProcess([string]$filePath, [array]$arguments, [bool] $waitForExit)
{
    $pinfo = New-Object System.Diagnostics.ProcessStartInfo #Make a new Process start info object
    $pinfo.FileName = $filePath #set the file name to the filePath argument
    $pinfo.RedirectStandardError = $true #standard error and stdout shall be redirected
    $pinfo.RedirectStandardOutput = $true
    $pinfo.UseShellExecute = $false
    $pinfo.Arguments = $arguments #set the arguments to the arguments specified $arguments
    $p = New-Object System.Diagnostics.Process #create a process
    $p.StartInfo = $pinfo # assign start info to the process
    $p.Start() | Out-Null # start the process
    IF($waitForExit){ #wait until the process has exited (if specified)
        $p.WaitForExit()
    }
}

Utilities

This chapter gives some examples of PowerShell functions I wrote myself. All of these functions provide a functionality which isn't given by existing Cmdlets, but still of use in many cases.

Create a directory if it doesn't exist

Just creating a directory throws an error if the directory already exists. This little helper function avoids this problem by only creating the directory if it doesn't exists:

function CreateDirectoryIfNotExisting([string]$dirPath){
   IF(!(Test-Path -Path $dirPath)){#check if the directory exists
      New-Item -ItemType directory -Path $dirPath #create it if it doesn't exist
   }
}

Abort script execution if a file/directory is missing

This function aborts the execution of the script if the specified file is missing on the file system.

function AbortIfFileMissing ([string]$filePath, [string]$name)
{
    IF(!(Test-Path $filePath)){#Not being able to find file throws
        Throw ("ERROR: The File $name was not found! Expected path: $filePath")
    }
    ELSE{
        Write-Host ("File " + $name + " found. It's located at " + $filePath)
    }
}

The function which has the same functionality regarding to a directory can be implemented following the same scheme:

function AbortIfDirectoryMissing ([string]$dirPath, [string]$name)
{
    IF(!(Test-Path $dirPath)){#Not being able to find directory throws
        Throw ("ERROR: The directory $name was not found! Expected path: $dirPath")
    }
    ELSE{
        Write-Host ($name + " found. It's located at " + $dirPath)
    }
}

Further reading

 

This chapter gives you a collection of Links which you can use to read further, more detailed information about specific PowerShell topics.

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)

Share

About the Author

Marco Bertschi
Software Developer (Junior)
Switzerland Switzerland
Software Developer (Swiss Federal VET Diploma), experienced with Qt C++, C#, RFC 5424 and Arduino Boards.
Music enthusiast, runner, part-time psychologist for friends, awesome guy and Air Force Sergeant First Class.
Follow on   Twitter

Comments and Discussions

 
QuestionDon't you want anyone to see... Pin
Nelek8-Nov-14 14:04
protectorNelek8-Nov-14 14:04 
AnswerRe: Don't you want anyone to see... Pin
Marco Bertschi9-Nov-14 21:22
protectorMarco Bertschi9-Nov-14 21:22 
GeneralMy vote of 5 Pin
Carsten V2.04-Oct-14 9:22
memberCarsten V2.04-Oct-14 9:22 
GeneralRe: My vote of 5 Pin
Marco Bertschi5-Oct-14 1:48
protectorMarco Bertschi5-Oct-14 1:48 
AnswerRe: My vote of 5 Pin
NewPast5-Oct-14 6:12
groupNewPast5-Oct-14 6:12 
SuggestionNice! Pin
Ronny9324-Apr-14 3:47
memberRonny9324-Apr-14 3:47 
AnswerRe: Nice! Pin
Marco Bertschi24-Apr-14 3:49
protectorMarco Bertschi24-Apr-14 3:49 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.

| Advertise | Privacy | Terms of Use | Mobile
Web01 | 2.8.150428.2 | Last Updated 4 Oct 2014
Article Copyright 2014 by Marco Bertschi
Everything else Copyright © CodeProject, 1999-2015
Layout: fixed | fluid