Hello tech world this is tech thoughts and welcome to this special Tech Thoughts video series focused on learning PowerShell. This is an operationally designed video series intended to get you ramped up and using PowerShell quickly. This is video 2 in the series, working with the PowerShell pipeline. as always if you prefer written documentation the corresponding article for this topic can be found on the techthoughts.info blog which i've linked in the description below. Let's go ahead and get started. so we can start off with what is a pipeline? Well, it's not something that you really need to overthink It's just a pipeline operator that moves data from one command to another. so we can do something like Get-Process Which will return all of our processes But instead we can use the pipeline operator designated by this symbol here And instead pipe that to something like Sort-Object. So here what we're doing is we're taking all of the processes found by this cmdlet, and piping those over one at a time over to Sort-Object and we can sort by... let's say ID. So instead of sorting by name or sorting by another factor, we can sort by a different property So in this case, we can pipe that to sort object and sort by ID Notice that we are starting at 0 over to 8 And so we see this is nicely sorted by ID number now. we could instead if we wanted sort this by name and we will get a different output and now everything is sorted by the name of the process that is running. So this concept of pipeline passing works for a variety of different cmdlets. We can start demonstrating this by opening a notepad and moving that over to the right. and if we run Get-Process, and search for our notepad processes notice that we do find one notepad process because we're running one notepad over here. We can leverage the pipeline to pipe this to Stop-Process. So what's happening here and because PowerShell does work with objects, we'll pull in the notepad process object and then pipe that over to Stop-Process which should terminate this notepad window. so notice that as soon as I go ahead and click enter it immediately terminates that particular process. This is the power of the PowerShell pipeline. Do keep in mind that not all cmdlets will accept pipeline input. so, if you're not sure you can use get help as we've demonstrated in a previous video, and see if things like Stop-Process support the concept of a pipeline input. So if we do a Get-Help Stop-Process -full We'll get a lot of help information about that particular cmdlet, and we can come up to the various parameters and we can see in here that indeed if we specified the process to stop, that a pipeline input is supported. Another thing to keep in mind is that you can't do a Get-Service and pipe the name of service, bits, in to Stop-Process. This Stop-Process is expecting a process object. Whereas the Get-Service cmdlet is going to return a service object. So, if we click enter on this, this will of course bomb out and say that, hey I can't find a process with the name bits. It doesn't understand how to process that particular object. when working with the pipeline, there is one automatic variable that is critical to understand, and that is PSItem. And PSItem contains the current object in the pipeline. If you're new to PowerShell this can be a kind of an abstract concept to understand but a couple of demos real quick and you'll understand this pretty well. So if we run Get-Process that will of course return all the running processes on our system. Note though that if we pipe this to a ForEach-Object what we're telling PowerShell to loop through each object we can tell it to work only with the current item, which is PS item. So we're telling it to get all the processes and for each of the objects found in those various processes, go ahead and return the current object. So if we click enter you'll notice that we get an identical return because that's what's really happening when you run Get-Process anyway Is it's piping to ForEach-Object and writing out to the current object. Here is a simpler way to visualize this. So we can load up a very simple amount of objects. So the number is 1, 2, & 3, and pipe those two for each object Just like we did a moment ago and of course specify PSItem. So, what do you think will happen when I click enter? Let's find out. It wrote the numbers 1 2 & 3 Because we loaded three simple integer objects into this pipeline, when it went through ForEach-Object we can clearly see that PSItem contains an individual object and for each of those objects that wrote out that particular object that we loaded into the pipeline. PSItem is an important concept to understand. When dealing with day to day PowerShell and as you explore the internet for examples, you're very rarely going to see PSItem written out like this. Instead it will almost always be designated with the dollar sign underscore which is a shorthand way of writing PSItem note that if I copy this command And replace it with dollar sign underscore we get the exact same output. And this is the way you'll see most PowerShell code written. One of the primary use cases for the pipeline is just working with the data objects that you get back from a cmdlet. So we can see that if we do things like Get-Date it will return a subset of information that PowerShell thinks that we want to see .so a basic string representation of the date, but we can pipe that information, Get-Date to... for example Format-Table and this returns a table display of that same information. Tables can be a great way to easily display information but because they're a table they're limited in to the space that could be taken up on the console window. And so they will truncate some of the information that's available from particular cmdlets. If you want to see the majority of data returned by an object, another way to do this is to pipe it to Format-List. In that case we get all of the data that's returned from a particular object. Some cmdlets though return a lot of information. So let's launch another notepad window and again, we'll run a Get-Process and we'll search for notepad processes. And this the course will return some information. Again, this cmdlet is returning a subset of the properties of this object and we only get one two three four five six seven seven of those properties back from that particular object. If we pipe this to Format-List we get a different set of properties then we previously got on just running the regular cmdlet. But again, Get-Process has a great many properties that we're not seeing. So, in order to get all of them, a common tactic is to add an asterisk when piping to Format-List. Note that if we do this we get an enormous amount of information about this particular process that's running, including the name and a wealth of other information. This type of object is always being returned by the Get-Process, but PowerShell limits on what we see because it highlights the information that we're most likely to want. If you're after all of the information and the full object make sure that your piping things into Format-List with that asterisk to see all available properties. So when we pipe this to Format-List with an asterisk we got everything back, but a lot of times you'll only be interested in a very few subset of information. So we'll continue with this example of getting processes about our notepad But we'll pipe this to Select-Object and we'll choose which particular items that we would like to go after. So in this example I will select the objects of name, ID, CPU, and responding. we can see here now that only those particular properties are returned by piping this to Select-Object and specifying the properties that we would like to see. Another common tactic for working with objects is to sort them based on some criteria. So we can of course run Get-Process again and pipe that to Sort-Object and maybe we can sort them by which processes are utilizing the most CPU. And if I click enter you'll notice that in the CPU column, which is right here that some of the processes are not actively engaging that CPU as they sit at 0% But then some processes are using the CPU quite frequently. so you can quickly identify which processes are utilizing the most CPU in your system. Okay, so now we're going to tie several of these concepts together with a very powerful Where-Object. So, we'll do Get-Process and we can pipe that to Where-Object. Where-Object is a lot like Select-Object except that we can select objects based on provided criteria. I'll go ahead and type in Where-Object and we'll fall back to our of course PSItem and I'll designate where CPU is greater than 50. This may look a little confusing to you If this is the first time that you're seeing this, let's go ahead and break this down. We're of course getting our processes we've seen this several times, and we're piping this to Where-Object. Inside of these curly braces is the criteria that Where-Object will evaluate This represents the current objects in the pipeline. This will be the first process that runs on the first iteration of Where-Object. So on the first process, it will evaluate the CPU property and determine if that CPU property is greater than 50. Let's go ahead and execute this command and see the results. Notice that I have far fewer returns when I run it with Where-Object because the vast majority of those processes are not running the CPU higher than 50. Where-Object is extremely powerful way to interact with stuff inside of the pipeline, giving you the only the information that you think is necessary. Let's do another example of Where-Object where we evaluate file sizes. So this time we'll do Get-ChildItem And Get-ChildItem can find information out about the files on your system. So we'll do Get-ChildItem and we'll tell it to go to... evaluate our home drive. and we'll recursively look at all files that are found in that home path. We'll pipe this to Where-Object, and whenever I type Where-Object I typically just go ahead and open and close a couple of curly braces and then I'll go ahead and add the current object in the pipeline and I want to evaluate how large that size of that file is and that is designated in PowerShell as length. and then we'll say greater than let's say 20 megabytes ins size. we'll go ahead and execute this command. Again, let's break this down. We're pulling in all of the files that are found in the home path. We're piping the results of those objects over to Where-Object and Where-Object is evaluating the length which is designated by this property here and we're determining if that length is greater than 20 megabytes. Notice what we ran this again and change the criteria to 50 megabytes that we get no objects returned because no objects meet that criteria. Remember that it is possible to pipeline more than once so we can even pipeline this to Measure-Object to determine how many files, say... meet the criteria of being larger than 10 megabytes. So again breaking this down we're recursively evaluating all files in the home path, piping that to Where-Object is greater than 10 megabytes and then piping again to Measure-Object and we can see that nine files meet that criteria because Measure-Object is evaluating how many objects there are. So using the power of the pipeline you now have a way to count the number of large files on your system. In these few examples you may have noticed that I've used this symbol here - gt which is greater than This in PowerShell is known as a comparison operator. Comparison operators are very common in programming languages and there are a wide variety of them like greater than, less than, equal to, so on and so forth. so you can make some programmatic decisions about what you're looking for You can find a list of these comparison operators on the techthoughts.info blog which I've linked in the description below. If you've been following along in the video series you've seen a few example where I've used parameters against cmdlets. Let's take a moment to explore parameters. They're very simple to understand. So each cmdlet differs in the number and type of parameters and wll parameters really are is just a way of passing various options or arguments to a cmdlet. So notice that if we run Get-TimeZone, it returns the current time zone configuration of the device very simple Get-TimeZone has various parameters that are available to it. I'm using the intellisense of this particular console and intellisense supports auto-completion. So if I push - on this Get-TimeZone and click tab on my keyboard It will tab through the various parameters that are supported by this particular cmdlet. If I shift tab it will go backwards. So I can tab forward or shift tab back through the available parameters of this cmdlet. Again, you can always use Get-Help to determine what parameters are available for a particular cmdlet. Using our Get-TimeZone, which again displays the current time zone of the device, if we instead pass the list available parameter to this cmdlet It doesn't display the current time zone but rather displays the available time zones that this device could be configured as. I hope you found this video on the PowerShell pipeline informative. Let's close out with one last example The PowerShell pipeline is arguably the most important concept to master when dealing with PowerShell. It's what makes PowerShell so powerful! Imagine, for example, what this would do... Probably not something you would want to do in production, but an interesting thought exercise when we can of course always add a what if and just see what that I actually do. We could theoretically stop every single process on this system. That's a good point to take away in that PowerShell trust you the operator to understand the ramifications of the commands that you run. PowerShell doesn't do a whole lot of hand-holding. Don't forget that all of this information is available in written format on the tecthoughts.info blog, and if you found this video helpful, go ahead and click that like button, and subscribe for more tech thoughts videos!