Two Powerful Tricks for Finding PowerShell Scripts

Two Powerful Tricks for Finding PowerShell Scripts

  • Comments 3
  • Likes

Summary: Microsoft Scripting Guy Ed Wilson shares two powerful tricks for finding Windows PowerShell scripts.

 

Hey, Scripting Guy! QuestionHey, Scripting Guy! I am wondering if you have any cool ways to help me find the scripts I have written. I have quite a few scripts in my scripts folder, but opening Windows Explorer and searching through them is slow, cumbersome, and time consuming. I am wondering if a guy like you has any cool tricks you would be willing to share to help me be more efficient.

—EB

 

Hey, Scripting Guy! AnswerHello EB,

Microsoft Scripting Guy Ed Wilson here. Last week, the Scripting Wife and I had a great luncheon meeting with Microsoft Windows PowerShell MVP Jim Christopher while we were in Charlotte, North Carolina. The subject of the meeting was starting a Windows PowerShell user group in Charlotte, North Carolina. Yes, that is right; we are going to start a new Windows PowerShell user group in Charlotte. It was a really cool meeting that ended up going on for several hours. Jim is a really great person, and he has a lot of great ideas. Right now, it looks like the first meeting will be in January, but stay tuned.

If you live in the southeastern section of the United States, you may want to be making travel plans to attend the inaugural meeting. It will be cool! I have reserved a room at the Microsoft office in Charlotte, but it only holds 200 people. So this user group meeting will definitely be on a first come, first served basis. I am certain we will also have Live Meeting set up for the event. I am really psyched. The Scripting Wife is helping Jim get everything set up, so stay tuned for Scripting Wife blog posts about the experience. This is really going to be great; I could go on and on with superlatives, but EB, I need to answer your question.

EB, I have a very cool solution to help you find and work with your Windows PowerShell scripts in a more efficient manner. It is a two-part solution. Here are the two steps:

  1. Add your script directory to the path by using $env:path. Make this addition part of your Windows PowerShell profile.
  2. Use the Get-Command cmdlet to find your scripts.

The first thing to do is to add your script directory to the path. The nice thing about using the environment PSDrive is that changes happen immediately. There is not a need to close and open Windows PowerShell. The other nice thing about using the environment PSDrive is that changes are not permanent. It is therefore possible to add the scripts directory to the path, but not make any permanent changes to the path. Each folder in the path uses a semicolon delimiter. The final folder does not have a semicolon after it. In the following figure, I first query the existing path. Next, I add the C:\fso folder to the path. The final command I use checks the path to see if the new folder appended correctly. The three commands are shown here:

$env:path

$env:path +=';c:\fso'

$env:path

The commands and associated output are shown in the following figure.

Image of commands and associated output

After I have added the scripts folder (C:\fso in this example), I can use the Get-Command cmdlet to find all the scripts in the folder. To do this, I use the Get-Command cmdlet with the commandtype of externalscript. This command is shown here:

Get-Command -CommandType externalscript

Any Windows PowerShell script from any folder that appears in the path is shown in the output. The command and associated output are shown in the following figure.

Image of command and associated output

Interestingly enough, the definition property contains the path to the script itself. The default output does not display script contents. If I want to limit the number of scripts returned by the command, I can use the totalcount parameter. The following command returns only one Windows PowerShell script:

Get-Command -CommandType externalscript -TotalCount 1

To get an idea of the information that the Get-Command cmdlet is able to return, send the output to the Format-List cmdlet and choose all properties:

Get-Command -CommandType externalscript -TotalCount 1 | format-list -Property *

The command and associated output are shown in the following figure.

Image of command and associated output

The ScriptBlock and the ScriptContents properties contain useful information. I can therefore use the Get-Content cmdlet to search my scripts that contain a function named addone. This command and output are shown here:

PS C:\> Get-Command -CommandType externalscript | Where-Object { $_.scriptblock -match 'addone'}

 

CommandType     Name                            Definition

ExternalScript  a.ps1                           c:\fso\a.ps1

 

By using aliases, I can shorten the command syntax a good deal. Here is the short version of the command (I use the alias gcm for Get-Command, and the alias ? for the Where-Object cmdlet; I also use the –c as a short form of commandtype):

gcm -c externalscript | ? { $_.scriptblock -match 'addone'}

Unfortunately, I cannot use neither an alias for the externalscript enumeration nor a wildcard character. In the following figure, I attempt to use a wildcard character to avoid typing externalscript. The command and associated error are shown.

Image of command and associated error

Because I now have the enumeration name, I can use my Get-EnumValues function from my Enumerations and Values blog post. By using the Get-Enumvalues function, I discover that externalscript has a value of 16. This is shown in the following figure.

Image showing externalscript has value of 16

Cool! Now that I know I can use an enumeration value, I can really shorten the command:

gcm -c 16

This command is short enough such that it is really easy to type. For example, if I am looking for my function that creates a new temporary file, but I am not certain of the exact name, I can use the following to find it:

PS C:\> gcm -c 16 | ? { $_.scriptblock -match 'tmp'}

 

CommandType     Name                            Definition

ExternalScript  Out-TempFile.ps1                c:\fso\Out-TempFile.ps1

EB, that is all there is to adding a folder to the path and using the Get-Command cmdlet to find scripts. Because the match operator accepts a regular expression, I have a really powerful way to search my Windows PowerShell scripts to find exactly what I am looking for. Join me tomorrow for more Windows PowerShell goodness—you will be glad you did!

 

I invite you to follow me on Twitter and Facebook. If you have any questions, send email to me at scripter@microsoft.com, or post your questions on the Official Scripting Guys Forum. See you tomorrow. Until then, peace.

Ed Wilson, Microsoft Scripting Guy

 

 

Your comment has been posted.   Close
Thank you, your comment requires moderation so it may take a while to appear.   Close
Leave a Comment
  • Hi Ed,

    this is a nice try to speed searching up!

    And it is something I didn't know: Looking for scriptblocks inside my scripts!

    In fact searching directories recusevily is quite slow in powershell due to the way .Net framework 2.0 works!

    .Net FW 4.0 has some impovements inside the bag, that may help to search faster in later PS versions.

    But it is very unlikely that adding one or some directories to the path will do.

    Usually we may have created dozens or even hundreds of directories that hold specialized scripts to categorize our work and it may be unsuitable to add each of them to our path ( slowing down the search speed anyway ). Some kind of indexing scripts and giving only a few root directories to a search function may be a way out. It would be great if the comment based help could be included in the serach algorithm to be able to find contents by keywords. personal information and dates like

    get-script -path 'c:\fso' -synapsis 'sort,unique' -parameter 'filename' -before '01.01.2010' -after '01.08.2009' -author 'schulte' -recurse

    Klaus.

  • @Klaus thank you for your comment. You are right searching through many different folders for scripts could be a problem. I love your idea about a Get-Scripts cmdlet.

  • PS C:> G37-C0mm4nd -C0mm4ndTyp3 3x73rn415crip7