PowerShell can be started in a number of ways:
It should be noted that PowerShell is invariably used to carry out administrative tasks, and as such, will often need to be launched using the Run as administrator option (this enables the "administrative" token, as controlled by Windows' User Account Control protection).
You can quickly determine the version of PowerShell installed on the local machine by viewing the values in the built-in $PSVersionTable variable (this variable is a , or "associative array" - more on these later).
PowerShell introduces the concept of execution policies. An execution policy determines under what conditions a PowerShell script will be allowed to run, thus providing a mechanism for securing computers against PowerShell-based malicious software (malware). The default execution policy settings vary between the versions of Microsoft Windows. However, the available policy values remain the same for all installations; they are:
Policy Value | Effect |
---|---|
Restricted | Scripts cannot execute. |
AllSigned | All scripts, whether on the local machine, or on a network resource, must be by a trusted publisher. |
RemoteSigned | Script on the local machine can execute, but remote scripts must be . |
Unrestricted | Unsigned scripts can be executed, but a warning will be displayed when executing scripts sourced from the Internet (see for further information). |
Bypass | Nothing is blocked and no warnings are displayed. This setting should clearly not be used. |
The current Execution Policy settings can be viewed using the Get-ExecutionPolicy cmdlet:
Execution Policy settings can be controlled via Group Policy or by using the Set-ExecutionPolicy cmdlet. For example, to change the Execution Policy for the current user to RemoteSigned, type:
All current versions of Microsoft Windows are members of the "Windows NT" family, which dates back to 1993, when Windows NT 3.1 was released. The internals of Windows NT and its derivatives are object-based, with virtually all operating system primitives (processes, threads, mutexes, semaphores, Etc.) and higher-level abstractions (file handles, COM objects, messages, services, Etc.) being represented as class objects with their own methods, properties and access control lists (ACLs).
So why mention this? Well, PowerShell has been designed to interact with this object-based model natively. That is, the default behaviour of PowerShell is to work with objects. This makes PowerShell incredibly versatile in terms of what can be achieved from an interactive shell or script.
Up until now, the Windows Shell has behaved like MS-DOS, which, like most other shells, provides only textual interaction with the operating system. For example, if you wish to list the contents of the current directory in the legacy Windows shell, you would type dir. On a UNIX based operating system, you would type ls. Both of these commands would return a textual list of files, directories and symbolic links, the formatting of which being dependent on the version of the operating system, the system locale, and certain user preferences. If you were writing a script to carry out a task based on the contents of the current directory, you would have to use various commands, such as for, forfiles, findstr, grep, awk, Etc., to interpret the textual output, before carrying out your task.
PowerShell, on the other hand, works differently. For example, when you use the Get-ChildItem cmdlet (or use one of its , such as gci, dir or ls) to list the contents of the current directory, but we\'ll cover that later.' ); , it returns an of file system objects. If you don't instruct PowerShell to do anything with the returned objects, it will "burst" them and render the results to the console as a textual representation. This is demonstrated below.
This is obviously a very simple, and somewhat contrived, example, but this concept carries through to all aspects of the Windows operating system, and any other technologies exposed to PowerShell (such as Microsoft Exchange Server and VMware vSphere).
PowerShell is made up of numerous cmdlets (lightweight commands). The base installation of PowerShell V5.0 includes over 500 cmdlets and these can be extended upon by importing or adding snap-ins.
All cmdlets names follow the format verb-noun, where verb is the action you wish to perform, and noun is the object or item you wish to interact with. The list of approved verbs is documented in Microsoft's TechNet library, with examples including: Add, Clear, Close, Copy, Find, Get, Move, Select, Test, Unlock and Watch (this list is not exhaustive).
The list of available nouns depends on which modules are loaded and which snap-ins have been added. A subset of the default nouns includes Acl, Alias, ChildItem, Command, Computer, Content, Date, Event, File, Help, Html, Item, Json, List, Member, Module, Object, Output, Path, Process, RestMethod, Service, TimeSpan, Type and Xml.
The Get-Command cmdlet can be used to list the currently available cmdlets.
The Get-Command cmdlet can also return the commands that use the given verb or noun, for example:
If you cannot remember the cmdlet that you require, you can use the -Name parameter with wildcards:
Finally, to list the cmdlets exposed by a specific module, you can use the -Module parameter:
As mentioned above, PowerShell can be extended by means of importing modules. The Import-Module cmdlet loads the required module(s) into the current PowerShell shell (i.e.: into the existing POWERSHELL.EXE process).
The PSModulePath environment variable holds the search path for available modules. By default, the search path includes the $HOME\Documents\WindowsPowerShell\Modules and $PSHOME\Modules directories, where $HOME is a built-in variable specifying the current user's profile directory and $PSHOME is the root directory of the PowerShell installation.
The Get-Module cmdlet can be used to list the loaded modules or to list the available modules:
To import a module, simply use the Import-Module cmdlet, specifying the required module using the -Name parameter:
You can also create your own modules to organise and share your procedures, functions and cmdlets. This will be covered in the section.
The next thing that distinguishes PowerShell is the "pipeline". The pipeline is essentially an extension of the already familiar behaviour of piping data between commands, where the pipe symbol (|) is used to take the output of one command and pass it to another command as input. Almost all PowerShell cmdlets accept objects as piped input. Equally, almost all PowerShell cmdlets generate object-based output. This behaviour, combined with a number of filtering and manipulation cmdlets makes it possible to perform some very powerful operations from either an interactive shell, or from a PowerShell script.
PowerShell therefore makes it very easy to achieve the goal of most human-computer interactions, that is, get some information, filter out the information that you are not interested in, manipulate the information (e.g.: perform a sort operation) and then either output the information for human consumption (e.g.: in the form of a report), or execute subseqsequent commands based on the information.
We're getting ahead of ourselves here, but let's quickly demonstrate PowerShell's pipeline (we'll explain all of the cmdlets involved later on):
In this example, we get a list of active process objects (Get-Process), we then sort the list by working set size, in descending order (). We then select the top five processes and retrieve just their process name, process ID and working set sizes (). Finally, we render the output to an HTML report (ConvertTo-HTML and Out-File).
To perform this operation without PowerShell would require a considerable number of lines of VBScript, Perl or Python code. PowerShell's pipeline is discussed in more depth in section .