How to create a PowerPack

A little while back Marco Shaw invited me to present at one of the PowerShell Virtual User Group meetings he runs regularly.  I was quite looking forward to presenting, and I was going to demonstrate how you can extend the PowerGUI administration console as well as how you can share these extensions by exporting them in PowerPacks and making them available to the PowerShell community.  Creating PowerPacks is a large part of what I do at work every day, and I get a lot of questions about how to do it, so I was looking forward to being able to answer those questions in my demonstration.

Unfortunately I had some challenges in front of me at the time and I ended up cancelling my presentation (sorry Marco!).  Still, I really wanted to show how PowerGUI can be extended and how PowerPacks are made, so I recently recorded a screencast that contains pretty much everything I was hoping to show off in my presentation.  Are you interested in learning how you can extend PowerGUI and how you can create your own PowerPacks?  You can check out the screencast/tutorial I made here.

Are there other screencasts/tutorials you would like to see for PowerShell and/or PowerGUI?  Let me know.  If comments don’t work for you, you can find my contact information in my about page.

And lastly, are there things you would like to see in the PowerPacks that come with PowerGUI?  Are there PowerPacks that you would like to see that aren’t published yet?  Let me know that as well!

Kirk out.

Share this post :

whence in PowerShell

[Update: Thanks to Joel Bennett for the comments; my original version didn’t account for external scripts and applications having the same precedence, but this revised version does]

Recently a fellow MVP pointed out that PowerShell doesn’t have a whence command readily available.  whence is a command from the Korn Shell.  When a name is provided to the whence command, it returns the way in which that name will be interpreted by the shell.

While PowerShell doesn’t have that functionality out of the box today, you can easily add it with the addition of a simple function to your PowerShell profiles.  Here’s my interpretation of the whence command in a PowerShell function:

function whence {
    param(
        [
string[]]$command,
        [
Switch]$ReturnAll

    )

    # Put any additional arguments in $command
    if ($args.Count -gt 0) {
        $command += [string[]]$args
   
}

    # Read the current path environment variable
    $path = $env:Path.Trim(;).Split(;)

    # Store an array of all command types that have equal
    # precedence
    $equalPrecedence = ExternalScript,Application


    #
Set the command precedence expression for sorting
    $cmdPrecedence = {
        if ($equalPrecedence -contains $_.CommandType) {
            [
Management.Automation.CommandTypes]`
                $equalPrecedence[0]
        }
else {
            $_.CommandType
        }
    }

    # Set the path precedence expression for sorting
    $pathPrecedence = {
        if ($equalPrecedence -contains $_.CommandType) {
            [
Array]::IndexOf(
                $path,
                [
IO.Path]::GetDirectoryName($_.Definition)
            )
+ 1
        }
else {
            1
        }
    }

    # Filter out all but the first command if appropriate
    foreach ($item in $command) {
        if ($ReturnAll) {
            Get-Command -Name $item `
                |
Sort-Object `
                    -Property $cmdPrecedence,$pathPrecedence `
        }
else {
            Get-Command -Name $item `
                |
Sort-Object `
                    -Property $cmdPrecedence,$pathPrecedence `
                |
Select-Object -First 1
        }
    }
}

This function supports retrieving multiple commands at once, whether they are passed in as an array or not.  For example, you can retrieve the commands for Get-Help and Get-Command by calling either of the following:

  1. whence Get-Help,Get-Command
  2. whence Get-Help Get-Command

It also supports retrieving all results for a specific command so that you can determine why the command you want isn’t executing when you try to call it by name.  Here’s an exaggerated example, to illustrate the value here:

PS C:\> whence Get-Help -ReturnAll

CommandType    Name         Definition
———–    —-         ———-
Alias          get-help     get-help
Function       Get-Help     begin {…
Cmdlet         Get-Help     Get-Help [[-Na…
ExternalScript Get-Help.ps1 C:\Get-Help.ps1
Application    get-help.exe C:\get-help.exe

If I had multiple executable applications, such as get-help.exe and get-help.cmd, this would return them in their precedence order.  If I was trying to execute any command here other than the alias, this would help me figure out why it wasn’t executing when I was simply calling get-help.To use this command in your PowerShell environment, simply copy the function into your PowerShell profile and it will be available the next time your profile is run.

Enjoy!

Kirk out.

Technorati Tags: ,,

Share this post :