With Great PowerShell Comes Great Responsibility

This introduction to PowerShell outlines some of the more common problems that administrators face and how to solve them with PowerShell. You don’t need programming skills to use PowerShell, nor do you need to be adept at scripting of any kind. PowerShell handles the complex tasks behind the scenes by allowing you to work with a series of shortcut commands and parameters (switches) in the foreground.

In this first part, I introduce PowerShell information retrieval to you via the “Get” commands (cmdlets), which allow you to look at system information in a non-destructive way without changing anything. Think of the Get cmdlets as information browsing. In subsequent articles, you’ll see how to retrieve information and then change it.

Starting the PowerShell Environment

PowerShell cmdlets aren’t available in a standard CMD window. To invoke PowerShell, open a CMD window and then type powershell and Enter. You’ll see a response similar to the following:

C:\Users\khess>powershell
Windows PowerShell
Copyright (C) 2009 Microsoft Corporation. All rights reserved.
PS C:\Users\khess>

The PS tells you that you’re in PowerShell and that PowerShell is ready to receive instructions in the form of cmdlets, which are shortcut names for programs that do your administrative bidding.

Before diving into a discussion of Powershell, check your PowerShell version by typing $Host at the PS prompt.

PS C:\Users\khess> $Host


Name             : ConsoleHost
Version          : 2.0
InstanceId       : ccbc6963-c33e-4848-a8e5-aa1ccaf7d65c
UI               : System.Management.Automation.Internal.Host.InternalHostUserInterface
CurrentCulture   : en-US
CurrentUICulture : en-US
PrivateData      : Microsoft.PowerShell.ConsoleHost+ConsoleColorProxy
IsRunspacePushed : False
Runspace         : System.Management.Automation.Runspaces.LocalRunspace

You can also retrieve this information with the Get-Host cmdlet.

If the Version parameter doesn’t display 2.0, point your browser to the Microsoft support pages, scroll down the page, and download the appropriate components for your system. Once you’ve downloaded and installed the PowerShell 2.0 components, check your version again to be sure that you installed PowerShell 2.0.

PowerShell Syntax

All cmdlets have the following syntax:

PS> Verb-Noun [-Switch <string[]>]

Switches and strings extend the power of the cmdlets but are optional.

For example, the cmdlet to list the running processes on your system, Get-Process , is in the Verb-Noun format. The cmdlets are always shown with uppercase and lowercase words, but they’re really not case sensitive. Case is used for illustrative purposes only.

Cmdlets have the form, Verb-Noun, and nouns are always singular. Get-Processes , while grammatically satisfying, is syntactically incorrect in PowerShell.

When you type Get-Process at the PS prompt, you should see a table listing all of your system’s running processes that looks similar to Task Manager’s Processes tab.

PowerShell on Your Local System

Before touching production systems with PowerShell cmdlets or scripts, you should practice and test with your local workstation. A virtual machine would be an even better sandbox in which to test. Never test on production systems.

Now look at the Get-Process cmdlet output. Is it in the format you want? If not, you can change it by passing parameters to switches that the cmdlet interprets then returns your changes to you.

The default Get-Process cmdlet reports system process information in the following format:

Handles  NPM(K)    PM(K)      WS(K) VM(M)   CPU(s)     Id ProcessName          
-------  ------    -----      ----- -----   ------     -- -----------          
     81       9     2392       3076    76     0.12   3996 AmIcoSinglun64       
     74       9     1464       2568    42     0.09   2172 armsvc               
    195      10     2380       2984    62     0.50   1164 atieclxx             
    102       9     2024       2380    34     0.08    960 atiesrxx             
    118       9    15648      15772    50            2664 audiodg              
   1337     528    42548      61444   284 2,611.69   1540 AvastSvc             
    286      29    14140      11580   162    17.88   3528 AvastUI              
    156      21    24200      45392   160    13.57    996 chrome               
    159      32   106848     124604   245    79.54   2720 chrome

Your processes display in descending alphabetical order by ProcessName . This is not that useful to an administrator who needs to know which process is consuming too much CPU time. You need to sort by CPU consumption in descending order so that you can see the processes consuming your CPU resources. If you use Linux, the top command is the equivalent of what you want to see here.

Issue the following cmdlet to sort by CPU time:

PS> Get-Process | Sort-Object -Descending -Property CPU


Handles  NPM(K)    PM(K)      WS(K) VM(M)   CPU(s)     Id ProcessName
-------  ------    -----      ----- -----   ------     -- -----------
   1073      73    86628      77748   418 ...58.57   2744 explorer
   2214     125   222264     262652   654 ...88.10   2752 chrome
    138      27    37056      12492   572 8,534.05    732 pcmontask
    329      17     8744      14484    86 4,442.07   5992 WmiPrvSE
    730      35   130680     123496   281 3,719.10    584 svchost

Your next question might be, “How would I know to run that cmdlet with that syntax to get the displayed results?” You wouldn’t unless you had some experience with PowerShell syntax and piping from one cmdlet to another.

To learn more advanced cmdlet syntax, like the one shown above, you have to write out the desired results from your script: List processes (easy) in order of highest CPU usage to lowest.

PowerShell gives you the ability to pipe the output of one cmdlet into the input of another cmdlet. If you’re also a Unix or Linux shell scripter, then you know the power of the pipe. If not, you’ll discover it with PowerShell.

However, before you can effectively pipe the output of one cmdlet into another, you need to know what the output is and how you want it configured when piped to the other cmdlet. You also need to know what your options are for filtering output from both cmdlets. An extensive Help system is available to assist you, which is outlined in more detail in the “PowerShell Help System” section later in this article.

You aren’t limited to processes on your system; you can also look at the status of services with a command such as:

PS> Get-Service

Status   Name               DisplayName
------   ----               -----------
Running  AdobeARMservice    Adobe Acrobat Update Service
Stopped  AeLookupSvc        Application Experience
Stopped  ALG                Application Layer Gateway Service
Running  AMD External Ev... AMD External Events Utility
Stopped  AppIDSvc           Application Identity
Stopped  Appinfo            Application Information

You see that the Get-Service cmdlet returns a table displaying Status , Name , and DisplayName of all services on your system. Although this is useful information, if you want to look at a single service or a group of related services, a display of all services is a bit cumbersome. Try the following command:

PS> Get-Service -Name wmi*

Status   Name               DisplayName
------   ----               -----------
Stopped  wmiApSrv           WMI Performance Adapter

Notice that I used the -Name switch to filter on the service name. If you try -DisplayName in your filter, when you enter -Status , an error is returned from the system because Status is not a parameter you can manipulate directly. It’s a bit advanced at this point to tell you why, so I’ll tell you that when you find such a property, you’ll have to use a workaround. One workaround is to use Sort-Object .

For example, to see a list of all services and their statuses filtered by status, enter:

PS> Get-Service | Sort-Object Status

Status   Name               DisplayName
------   ----               -----------
Stopped  QWAVE              Quality Windows Audio Video Experience
Stopped  QBFCService        Intuit QuickBooks FCS
Stopped  RasMan             Remote Access Connection Manager
Stopped  RasAuto            Remote Access Auto Connection Manager
Stopped  WwanSvc            WWAN AutoConfig

PowerShell on Remote Systems

Using PowerShell on a local system is interesting and useful, but the real power of PowerShell is using it with remote systems. The beauty of PowerShell is that you don’t have to RDP or connect remotely in any direct way to run PowerShell commands on a remote system to which you have access: You just have to specify the remote computer’s name with the -ComputerName switch and the name of the remote system. If you do not specify a computer name, the command defaults to the local system.

For example, to see a list of running processes on a remote system, enter,

PS> Get-Process -ComputerName [Remote System Name ]

My remote Windows server name is XenApp1:

PS> Get-Process -ComputerName XenApp1

Handles  NPM(K)    PM(K)      WS(K) VM(M)   CPU(s)     Id ProcessName
-------  ------    -----      ----- -----   ------     -- -----------
    237      11     2880       6616    47            1168 2XAgent
    153      13     7604      10508    60            1116 2XController
    264      10     8404      10832    58            1152 2XProxyGateway
    110       8     7144       9564    54            1132 2XRedundancy
    116       3     1016       4144    22            1188 appmgr

It works the same way for services:

PS> Get-Service -ComputerName XenApp1 -DisplayName Windows*


Status   Name               DisplayName
------   ----               -----------
Running  AudioSrv           Windows Audio
Stopped  FontCache3.0.0.0   Windows Presentation Foundation Fon...
Stopped  idsvc              Windows CardSpace
Stopped  MSIServer          Windows Installer
Stopped  SharedAccess       Windows Firewall/Internet Connectio...
Stopped  stisvc             Windows Image Acquisition (WIA)
Stopped  UMWdf              Windows User Mode Driver Framework
Running  W32Time            Windows Time
Running  winmgmt            Windows Management Instrumentation
Running  WinRM              Windows Remote Management (WS-Manag...
Running  Wmi                Windows Management Instrumentation ...
Stopped  WPFFontCache_v0400 Windows Presentation Foundation Fon...
Running  WSearch            Windows Search

Similarly, you can run a cmdlet to view a subset of running services. In this example, I want to see all services that are related to the 2X service.

PS> Get-Service -ComputerName XenApp1 -Name 2X*

Status   Name               DisplayName
------   ----               -----------
Running  2X Publishing A... 2X Publishing Agent
Running  2X Redundancy S... 2X Redundancy Service
Running  2X SecureClient... 2X SecureClientGateway
Running  2X Terminal Ser... 2X Terminal Server Agent

Are you seeing the pattern of how PowerShell works for local versus remote systems?

Basically, any cmdlet that works locally will also work remotely if you specify -ComputerName <Remote Computer Name> in the syntax.

The PowerShell Help System

If you’re going to use PowerShell with any of its advanced features or write your own scripts, you’ll need to learn to use PowerShell’s Help system. To get help, you simply type the cmdlet Get-Help at the PS prompt. To find help with a specific cmdlet, use the Get-Help cmdlet followed by the command with which you need assistance:

PS> Get-Help Get-Process <ENTER>

The Help system looks like Unix-style man pages with the cmdlet name (NAME ), a short description (SYNOPSIS ), cmdlet syntax (SYNTAX ), an extended description (DESCRIPTION ), links and related commands (RELATED LINKS ), and additional information (REMARKS ).

To see examples of the cmdlet you’re interested in, type:

PS> Get-Help Get-Process -examples

Powershell also understands wildcards (* ? ). For example, to see a list of all of the Get cmdlets, use:

PS> Get-Help Get*

To see a list of all possible Get cmdlets with a four-letter Noun, use:

PS> Get-Help Get?????

Name                              Category  Synopsis
----                              --------  --------
Get-Verb                          Function  Get-Verb [[-verb] <String[]>] [-...
Get-Help                          Cmdlet    Displays information about Windo...
Get-Date                          Cmdlet    Gets the current date and time.
Get-Host                          Cmdlet    Gets an object that represents t...
Get-Item                          Cmdlet    Gets the item at the specified l...

You have to use five ? characters, one for the (- ) and then four for the Noun portion.

Don’t ignore the related cmdlets in the RELATED LINKS portion of cmdlet help. For example, Get-Process has four related cmdlets that you might find useful:

  • Start-Process
  • Stop-Process
  • Wait-Process
  • Debug-Process

Summary

PowerShell is an important tool to add to your Windows adminsitrator toolbox. The more experience you gain with this essential tool, the better you’ll like it. PowerShell isn’t a traditional scripting language, although it does include many of the same attributes: variables, prompted input, redirected output, looping, and advanced decision making. If you’re new to PowerShell, practice with the Get cmdlets for a while before attempting any “Set” or other intrusive cmdlets.

Your assignment for this part of the series is to practice running Get cmdlets on your local system and on remote systems to view system information. If you want to venture further into this powerful language and its possibilities in your environment, please set up a virtual machine so you don’t irreversibly damage a live or production system.

Next month, I’ll show you how to manipulate services and processes and launch applications via PowerShell.

[Part 2, Part 3]

Related content

comments powered by Disqus
Subscribe to our ADMIN Newsletters
Subscribe to our Linux Newsletters
Find Linux and Open Source Jobs



Support Our Work

ADMIN content is made possible with support from readers like you. Please consider contributing when you've found an article to be beneficial.

Learn More”>
	</a>

<hr>		    
			</div>
		    		</div>

		<div class=