Let’s compare Powershell vs CMD. Both Powershell and CMD are command line interfaces (CLI) or shell environments for Windows. CMD is the older version, and Powershell is where Microsoft is now putting all of their development resources.
CMD
You can think of the CMD environment as the evolution of Microsoft DOS (Disk Operating System). While CMD might look a lot like DOS, it is not really the same thing. CMD was merely the shell that DOS used. Over the years, CMD has evolved and added commands. But to make any real changes without breaking backwards compatibility, Microsoft needed to create a new shell environment.
Powershell
Powershell version 1.0 was introduced in November of 2006. It uses the concepts of cmdlets and the pipeline to give you a powerful scripting language to accomplish a large array of tasks.
Each command in powershell is called a cmdlet, and the pipeline is how you pass the output from one cmdlet to the input of the next one.
As you run your various cmdlets in Powershell, you will start to notice one major distinction. Post the most part, commands in the windows cmd shell return text on the screen. Whereas powershell cmdlets return objects. We will cover that in more detail later.
Cmdlets
Cmdlets have a somewhat predictable pattern, and usually have a hyphen in the middle. For example, test-netconnection and out-file. In these examples you have something you are doing, such as a test or an output. Then after the hyphen you have a more specific command where you are testing the network connection or outputting to a file.
Pipeline
Let’s say you wanted to test a network connection, then take the output to the command and write it to a file. This is when then pipeline comes into play.
You could run:
test-netconnection google.com | out-file c:\test.txt
The above command will run a ping test to Google.com using the test-netconnection cmdlet, then pipe the commands into the out-file cmdlet, which will write the results to c:\test.txt
This pipeline functionality is not new in powershell. There was some of it in CMD as well. However, almost every cmdlet has pipeline functionality in powershell. Whereas only a few commands can really take advantage of it via CMD. For example the findstr.exe command can use pipeline input. An example of that would be:
type meh.txt | findstr x
In the above example, we use the type commands, which just writes the contents of the file to the window. Then we pipe that output into the findstr command and search for the string x.
Objects
In the previous section we talked about the test-netconnection commands and the findstr commands. In this section we will compare the select-string and findstr commands because they are more similar.
select-string searches through a given set of text just like the findstr command does. However, as previously stated, the findstr just returns text, whereas the select-string command will return an object.
Before we go further, lets describe what an object is. An object is a collection of attributes. To use a car analogy, you might have an. object called car. The car object will have various attributes such as color, make model, etc…. If you write a script and it creates an object called car, you would then be able to utilize these properties in different ways.
When we run the type meh.txt | findstr x command, it will read meh.txt, find all of the x’s, and then print it on the screen. But that is where it stops without a lot of gymnastics in parsing the output.
The equivalent powershell command is:
Select-String -Path "meh.txt" -Pattern "x"
The above command will do the same thing as findstr. It will read the contents of meh.txt, search for all of the x’s in the file, then print what it finds on the screen. However, we have the ability to save the results to a variable by doing the following:
$results = Select-String -Path "meh.txt" -Pattern "x"
The $results variable will be a collection of objects which we can then further analyze.
for example, we could run:
write-line $results[0].linenumber
and we will see the first line number that we discovered the text. Or, we could run:
write-line $results[0].path
We will see the path to the file where we found the match. This is important because by using wildcards you can scan multiple files all in one shot. Everything after the “.” are the attributes of the object. $results is the collection of objects. so the [0] is referencing which object you want to reference where [0] is the first object, [1] is the second object, etc….
We will further discuss collections in a future article.