Learning and Exploring PowerShell

PowerShell is a great window into the world of Microsoft and other PowerShell enabled technologies.  You can use it on the fly or as a framework to automate various processes.  You can build tools for IT or end users that reach across technologies to provide a consistent, flexible solution.  Before and while doing this, you will need to know how to explore and get help within PowerShell.

A quick tip for anyone not using Windows 8 / Server 2012 or later:  Download and install Windows Management Framework 3.  This includes the updated PowerShell ISE, which is fantastic for every day use and for learning, with features like Intellisense, GUI command discovery, and ctrl-c / ctrl-v compatibility.

Discovering Commands

PowerShell has many commands.  You could easily end up with thousands of commands in your session; how do you know what to run?

The following commands will help you discover which commands are available.  Once you have things narrowed down, you might need to hop on the web to find out which command is appropriate for your scenario.

#List all commands.  In PowerShell 3, this covers commands in modules and snapins that you haven’t added yet.
Get Command

#List all commands, including external executables in the PATH variable.
Get-Command –name *

#List all commands loaded in the current session (PowerShell 3)
Get-Command –ListImported

#List all modules available, all PSSnapins available
Get-Module -ListAvailable
Get-PSSnapin -Registered

#List all commands from the PowerCLI snapin and the Active Directory module
Get-Command -Module VMware.VimAutomation.Core, ActiveDirectory

#List all commands that start with Convert
Get-Command -name Convert*

#List all commands with VM anywhere in the name
Get-Command –name *VM*

#List all commands with the verb ConvertTo or Get.  Use -noun to search for nouns
Get-Command -verb ConvertTo, Get

#List all commands that take the parameter ComputerName
Get-Command -parametername ComputerName

Getting help for a command

At this point, you should have an idea of one or a handful of commands that could meet your needs.  Use the built in help system or Internet to find out how to use these or to pick which command is appropriate for your use case.

This can be difficult.  There is more than one way to skin a cat, and there are many, many PowerShell users out there who try to be helpful, but might end up posting inefficient or outdated code.  Maybe they tried translating VBScript to PowerShell, didn’t realize there was already a command for the code they wrote, or didn’t think through the execution of their code.

A quick note – Starting with PowerShell 3, you will want to run Update-Help, or just confirm that you want to download the updated help when you first run Get-Help. This needs to be done as an administrator unfortunately.

#Pull up a browser with the latest help info for Get-ChildItem - note this will only work with commands where HelpUri is defined
Get-Help Get-ChildItem –online

#Pull up all help details for Get-Command - full details, parameter info, examples, etc.
Get-Help Get-Command –full

#List all about_ help articles.  These describe the language and other higher level concepts than individual commands
Get-Help about_*

Important note:  If you are having trouble determining what information to provide as parameters, or how to pipe information to a command, –full will provide these details for every parameter.  Is the parameter required?  Is it a positional parameter?  What is the default value if none is provided?  Will the parameter take information from the pipeline, and will it take the entire object from the pipeline, or by a property of that object?

#Pull up examples for Get-ChildItem
Get-Help Get-ChildItem –Examples

#Get help from a script that uses comment based help.  Show only the basic help info
Get-Help \\path\to\script.ps1

In the following function I pull details from get-help such as ‘Synopsis’ for every command in a certain module.  If you use a custom module with many commands, it can be helpful to break them down by category.  I use ‘Functionality’ from comment based help.

function Get-HelpDetails {
            <#
              .SYNOPSIS
              Get details from comment based help for specified commands
              .DESCRIPTION
              Get details from comment based help for specified commands
              .PARAMETER module
              Return details from all commands in specified modules              .PARAMETER command
              Return details from specific commands listed here              .PARAMETER properties
              Return these properties from the comment based help.  Examples: description, name, category, synopsis, component, role, functionality
              .EXAMPLE
              Get-HelpDetails -module ActiveDirectory -properties Name, Synopsis | sort Name | Format-Table -autosize
              Get the Name and Synopsis for all commands in the ActiveDirectory module.  Sort by name, format as autosized table
              .EXAMPLE
              Get-HelpDetails -module CustomModule -properties Functionality, Name, Synopsis | sort Name | Format-Table -autosize
              Get the Funtionality, Name, and Synopsis for all commands in the CustomModule module.  Sort by Functionality, then name.  Format as autosized table
              .FUNCTIONALITY
              General Command
              #>
            [cmdletbinding()]
            param(
                [string[]]$module = $null,
                [string[]]$command = $null,
                [string[]]$properties = @( "Name", "Synopsis" )
            )
            #define parameter hash for Get-Command function
            $params = @{}

            if($module){

                #Build hash table for get-command module parameter
                $params += @{module = $module}

            }
            if($command){

                #Build hash table for get-command name parameter
                $params += @{name = $command}

            }

            #Run get-command with parameters from above, only return name
            $commands = Get-Command @params | select -ExpandProperty name

            #Loop through each command and return selected properties
            foreach($cmd in $commands){
                Get-Help -name $cmd | select $properties
            }
        }

        #Run the command to view functionality, name, and synopsis for SomeCustomModule module
        Get-HelpDetails -module SomeCustomModule | sort functionality, name, synopsis

In the following example, I will return the code of the Get-HelpDetails function we just created, which can be helpful if you are curious about the inner workings of a command, or want to quickly reference code.  I use this in the Open-ISEFunction function, which opens a function in a new ISE window.  Please note that this will only work where the definition is available (e.g. scripts, functions)

Get-Command Get-HelpDetails | Select -ExpandProperty Definition

Exploring the output of commands

We have our command, and know how to use it; how do we know what we can work with when we run it?  Get-Member, Select-Object and Format-List are helpful tools for this!

A quick note:  A property is information about an object.  The name of a process.  The start time of a process. etc.  A method is a predefined way to interact with an object.  You can ‘kill’ a process or ‘stop’ a service.

#First, let's just take a look at the typical results from Get-Process; we should see properties like Handles, NPM(K) and ProcessName for each process
Get-Process

#Find out what properties and methods are available from Get-Process.  There is a huge list of other properties that we can obtain and methods we can use against these objects
Get-process | Get-Member

#Some properties can be objects or arrays themselves.  To expand and look further into a property, use the Select-Object -expandproperty <property> command.  Here, we look at modules for any processes matching PowerShell*
get-process powershell* | select -ExpandProperty modules

#We can keep going!  Let's look at everything that comes back from the first module, using get-member to see the properties and methods
Get-Process powershell* | select -ExpandProperty modules | Get-Member

#If you want to see examples of actual values for the various properties, use select -property * or format-list -property *.  We select the first process and module in these examples to limit the results
Get-Process powershell* | select -ExpandProperty modules -first 1 | select -First 1 | Format-List -Property *
Get-Process powershell* | select -ExpandProperty modules -first 1 | select -property * -first 1

#As you can see, we could keep going deeper and deeper.  Some commands produce complicated objects like this.  Others provide simpler objects.  Get comfortable using Get-Member, Select-Object and Format-List to explore the properties and methods for the objects you are working with.

Let’s use some of these properties that aren’t displayed by default, and a method.  We will open Notepad, find the most recent process opened and close it.

notepad.exe
$latestProcess = get-process | sort starttime -Descending | select -first 1

#Display the process we picked, show the name, ID and startTime.  We can show or work with any of the properties we found with Get-Member
$latestProcess | select ProcessName, ID, StartTime

#If you are satisfied with the process you picked, close it using the close method.
$latestProcess.close()

The concept of objects and the complexities of working with them can be difficult when starting out.  You don’t need to memorize the different types of objects and all the properties and methods; just know that they are there, you won’t always see them by default, and that it is easy to dive into an object to see what it contains.  Things get even more interesting when you realize you have access to the .NET Framework – MSDN is your friend.

That’s it for today! Stop by PowerShell Resources for a list of PowerShell Resources that I’ve found helpful in learning PowerShell and for day to day use.

Advertisements

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s