Summary: Learn how to analyze Windows PowerShell script files.
Microsoft Scripting Guy, Ed Wilson, is here. This morning I am sitting around sipping a cup of English Breakfast tea. I added some peppermint, spearmint, lemon grass, licorice root, and a cinnamon stick to the pot. The result is a very refreshing cup of tea. I am sitting on the back porch with my Surface 3 Pro and playing around with Windows PowerShell.
I have a folder that I use to store miscellaneous Windows PowerShell scripts. I call the folder PSExtras and it contains scripts that I wrote for no apparent reason—I was just playing around. I decided that I would look at some of these scripts to determine a few things about the way I write scripts. To be fair, I have not added much to this folder in the last several years. Therefore, the folder is really more a picture of the way I used to write Windows PowerShell scripts three to four years ago.
One of the cool things about the Select-String cmdlet is that not only will it parse a file, but it will also parse all files in a folder. For example, if I want to see the files where I used the Write-Host cmdlet, all I need to do is write something like:
Select-String -Path E:\Data\PSExtras\*.ps1 -Pattern 'write-host' -List | select filename, line –Unique
The output produces a list of the file names and the line where the Write-Host cmdlet appeared in the script.
These days, the main reason I use the Write-Host cmdlet is because I want to display output in a different color. I always use the –ForeGround parameter when I do this. So, in how many of my scripts did I do this in my PSExtras folder? Here is the answer (this is a one-line command that is broken to fit on the website):
PS C:\> Select-String -Path E:\Data\PSExtras\*.ps1 -Pattern 'write-host -fore' |
select filename, line | sort filename -Unique | measure
Count : 204
Average :
Sum :
Maximum :
Minimum :
Property :
How many scripts did I write where I did not use the –Foreground parameter? I can easily get that by removing the –fore from my pattern. Here is the result:
PS C:\> Select-String -Path E:\Data\PSExtras\*.ps1 -Pattern 'write-host' |
select filename, line | sort filename -Unique | measure
Count : 375
Average :
Sum :
Maximum :
Minimum :
Property :
But wait! That is all the files that include Write-Host. So the answer is 375-204, which is 171 scripts that did not include a directive to change the foreground color. Today I would not do that.
What about the length of these scripts? I can get this information by using the Measure-Object cmdlet.
To do this, I use the Get-ChildItem cmdlet to find all of my .ps1 script files. Then for each of them, I get the content of the file and pipe it to the Measure-Object cmdlet where I choose the Line property. Now I pipe that to the Measure-Object cmdlet, and I choose the Average, Maximum, and Minimum properties. Here is the command (using aliases) and the output from the command:
PS C:\> Gci E:\Data\PSExtras\*.ps1 | % {get-content $_.fullname | measure -Line } |
measure -Property lines -Average -Maximum -Minimum
Count : 1347
Average : 35.7995545657016
Sum :
Maximum : 698
Minimum : 1
Property : Lines
This tells me that I have 1347 scripts in my PSExtras folder, and that the average length is 35 lines (this also includes comments and blank lines). The maximum length of my scripts is 698 lines, and the shortest one (no surprise) is a one-liner.
Most of the time, I do not save one-liners in files because I can easily re-create them (this is usually quicker than it takes me to actually locate the script file that contains the command), so this is not necessarily representative of my Windows PowerShell usage. But, I do think it is kind of interesting.
How does this compare with the VBScript files I wrote over the years? I also have a VBSExtras folder, so let's find out:
PS C:\> Gci E:\Data\VBSExtras\*.vbs | % {get-content $_.fullname | measure -Line } |
measure -Property lines -Average -Maximum -Minimum
Count : 1610
Average : 48.2391304347826
Sum :
Maximum : 1846
Minimum : 0
Property : Lines
Wow! The average file length was 48 lines long, and my longest VBScript is 1846 lines long. Note that I also have more VBScript files than I have Windows PowerShell files in my *Extras folder. This is probably because of the fact that I do not save all my one-liners.
Here is an image that shows the two commands and their associated output:
That is all there is to using Select-String and working with files. Join me tomorrow when I will talk about more cool stuff.
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