Learn PowerShell: Episode 5, Parameters + C# Descriptions + Overloads
Jul 24, 2021 21:46 · 5186 words · 25 minute read
Hello there everyone and welcome to another episode in the PowerShell video series.
00:04 - This video is essentially part 2 of the last one and we’re getting closer and closer to having really mastered the whole object system in PowerShell.
00:14 - And we’re also getting closer to the very last episode where we will make an entire graphical app with buttons and everything right from PowerShell.
00:24 - It’s going to be pretty exciting, but we need to understand how this stuff really works before we get there.
00:30 - Now, one thing I’d just like to say before we move on, for this video I’m going to change things up a bit, instead of directly using the PowerShell window like this, I’m actually instead going to be using an app available for Windows called “Windows Terminal”.
00:46 - It basically just slightly changes the interface you use to interact with PowerShell.
00:52 - It’s still PowerShell, it’s still all exactly the same commands and all that, it just looks a little different and a little nicer.
00:59 - So that’s why things here look slightly different and hopefully look slightly nicer too than the previous “host” as it’s called.
01:01 - Now then let’s quickly summarise what we learnt in the last video.
01:03 - We learnt that we have types, every object has a specific type, and that type says what properties and methods the object will have on it.
01:14 - So, whenever we have an object telling us about a process, that object has the type “Process”, and as such has all the members needed to represent a process.
01:25 - And of those members, we have properties, note properties and most importantly methods.
01:32 - Methods being the thing we learnt about last episode that allow us to perform actions on an object.
01:38 - Now, towards the end of the last episode, we called our first method, a method called “GetType”.
01:44 - And as I said, this method appears on every type of object in existence and it gives back, it returns a “Type” object that tells us all about the type the object we ran the method on is.
01:59 - So if I call “GetType” on a string type of object, this method will give me back a “Type” object telling me all about the string type.
02:04 - It has whole bunch of properties on it that tell us about a type.
02:05 - Like the “Name” of the type or the “FullName” of the type.
02:06 - And it also has some methods, methods that will retrieve even more details about the type.
02:12 - For example, towards the end of the last episode we ran a method called “GetProperties”.
02:16 - This is a method that “Type” objects have on them and it will give us back a whole bunch of “PropertyInfo” objects, one for each property.
02:24 - And this is a very nice way to get a list of all the properties on an object.
02:28 - There’s also a method called “GetMethods” that will give us a list of all the methods in the type.
02:33 - So, we can do something like this. We have a file object, we then run “GetType” on that file object to get info about its type, and we then run “GetProperties” on that to get all of the properties in it.
02:49 - And that’s how we find out what properties file objects has.
02:53 - And a similar thing happens for methods. Now then, I want to kick this episode off with parameters in methods because… We haven’t actually used them yet.
03:03 - So, let’s take a look at a method that has a parameter.
03:05 - We’re going to take a look at the “MoveTo” method on “FileInfo” objects.
03:10 - This method does not give back anything, but it takes in one parameter.
03:15 - And that parameter is the new place we want to move the file, it’s the new name we want to give the file.
03:22 - And this parameter is set to take in a string, so we can only put a string into this parameter, only the text to the new file name we want to give it.
03:30 - So, if I had a file object for the file “abc. txt” and I wanted to rename that file to “def. txt”, I could get a file object for the “abc. txt” using “ls” and all that, and I could then run this method, and put “def. txt” into the “new name” parameter.
03:49 - So, let’s do that. Here we are in PowerShell, in our new Windows Terminal host and all I’m going to do is I’m going to take our file object here for the file “abc. txt”, and I’m going to call the method “MoveTo” on it.
04:02 - Now, as I before, this method takes in a parameter, so how do we tell it what to put in that parameter? Well, what we do is we write what we want to put into the parameter inside the brackets.
04:16 - That’s actually what the brackets when we’re running methods represent, inside the brackets is where you tell it what you want each parameter to be.
04:24 - The reason why we left the brackets empty back when we were running “GetType” is “GetType” didn’t have any parameters, so we just wrote the brackets and didn’t put anything in them.
04:34 - But this method has one parameter, the “new name” parameter and if we try to run it without setting that parameter, without putting anything within the brackets, we’ll get an error, like so.
04:46 - This error says that it can’t find an “overload” for “MoveTo” with the “argument count” (argument count is another of saying parameter count) of “0”.
04:56 - So, in simpler terms, it’s basically saying: “I can’t find a ‘MoveTo’ method that takes in zero parameters”, which is how we’re trying to run it here because we’ve left the brackets empty.
05:08 - So, instead of leaving the brackets empty, let’s provide that parameter.
05:13 - Now, methods are a little different to commands.
05:15 - If I have a command like “Import-Csv” and I want to provide something to the path parameter, I write “Import-Csv” and then I do “-Path” and give it the path here.
05:28 - So, we choose what to put in each parameter based on their names.
05:33 - However, parameters on methods are based on order.
05:37 - So instead of writing “-Path” or “-NewName” or anything, I just put in the parameter.
05:44 - Just like that. Done. My file is now called “def. txt”.
05:47 - So that’s how we give methods parameters. Alright, but now, what if I have a method with two parameters, how do I tell it those two parameters? Well, let’s see.
05:58 - Let me give you an example of a method that takes in two parameters.
06:01 - So, on the “string” type, the type for a text, there’s a method called “Replace”.
06:06 - This method replaces a certain thing in the string with another thing and gives back the result.
06:13 - For example, if I have the string “a” comma “b”, I can use this method to tell it to replace the comma with a dot.
06:23 - And when I do that, it will return back to me a string with the comma replaced by a dot.
06:29 - This method has two parameters. The first one is a string, and this is the text you want to replace, and the second one is also a string, and this is the text you want to replace it with.
06:40 - So, essentially, if I put comma in the first parameter and then put dot in the second parameter, that basically means replace the comma with a dot.
06:49 - So, this method replaces everytime the first parameter appears in the string with what’s in the second parameter, and then gives the result back to us.
06:58 - It doesn’t change the original string, it gives back a new thing with the thing replaced.
07:04 - So, let’s run this. Here we are in PowerShell and here I have the string “A” comma “B”.
07:10 - Now, I want to run “Replace” on this to replace the comma with a dot.
07:16 - So, we’re going to take this string object here, and we’re going to do dot Replace to run the method, and then we need to put in the brackets, and this is where we’ll put the parameters.
07:26 - Now, remember, this method has two parameters, and the way it knows what thing goes to what parameter is based on what order we give them in.
07:35 - Now, for this method, the text to replace comes first, so we’re going to give it comma first.
07:41 - And now we need to give it the second parameter, what we want to replace the comma with.
07:45 - We’ve only given it the first parameter so far, but this method takes in two parameters, so if we run it now, we’ll see we get the same error from earlier.
07:54 - This time saying it can’t any method called “Replace” with only 1 parameter, because it takes in two.
08:01 - All we need to do is put a comma here and then give it the second parameter.
08:06 - So, if you look at this, we’re giving it this string as the first parameter, and then we use a comma here to tell it that we’re now moving onto the next parameter, and we give it the second parameter.
08:19 - And that’s how it works. So that’s how you call methods with parameters and methods with parameters, you just separate each parameter you give it with a comma, and the order you give them in is how it knows which thing goes to which parameter.
08:31 - And if we run it, we’ll see the method gave us back the string, but with the comma replaced by a dot.
08:39 - Amazing. And that’s how we provide things to parameters.
08:41 - Now then, let’s move swiftly along to another important thing, and this will tie into the next thing I’m going to cover.
08:47 - Every time I’ve told you about a method or a property, I’ve had to manually say out what it takes in.
08:53 - I’ve said out loud “This method takes in two parameters, one is this and one is this” and I’ve said “this method gives back something, this method doesn’t and so on”.
09:03 - But how does PowerShell describe methods? There must be some written way that PowerShell describe methods, right? Well, there is.
09:10 - And what I’m going to do is quickly introduce you to it, don’t worry it’s very simple, and we’re then going to take at some things that use that.
09:18 - Now, the way we define, the way we show what a method is and what it gives back, and what it takes in and all of that, is using this writing here.
09:27 - I know this might look a little complex but it’s actually quite simple.
09:28 - First, we say what type of object the method returns, so what type of object it gives back to us.
09:35 - If it does not give back something, then we write void here.
09:39 - So this method here does not return something.
09:41 - Then we say the name of the method, so in this case it’s called “Close”.
09:45 - And then we follow that with brackets. And inside these brackets, if we had parameters, we would put them in there.
09:51 - That’s it. So, here’s the “GetType” method that we’ve used several times now, this is how we can describe the method.
09:59 - So, we can see here that it returns, it gives back a “Type” type of object, an object telling us about the type.
10:07 - And we can see that it’s called “GetType”, and we can see that there are no parameters, because the brackets are empty.
10:14 - OK, so how about what a method with a parameter looks like.
10:17 - This method returns a “bool” type of object, which is a true or false object (we’ll learn more about all these different types in the next video), and we can see this method is called “WaitForExit”, and now when we get to the brackets, we see this method has a parameter.
10:32 - And this parameter here is an integer, it only takes in integers and the parameter is called “milliseconds”.
10:40 - And if we have two parameters all we do is just put a comma between them.
10:44 - So, this method here has a string parameter called “a” and then an int parameter called “b”.
10:51 - Fantastic, so that’s how we read method descriptions.
10:54 - So now, pause the video and tell me, here’s an imaginary method, how many parameters does this method have and what does it return? Well, you’ll see here that it’s a “void”, meaning it returns nothing, we get nothing back from this method.
11:08 - And over here we’ll see three parameters, we can tell there’s three parameters because there’s three things in-between each the commas, one here, one here and one here.
11:18 - The first parameter is an “int” object and it’s called “a”, the second is called “b” and is an “int” object, and the last is called “c” and is an “DateTime” object.
11:29 - And there you are, that is how we read method descriptions.
11:32 - Now just a little off to the side, I know you may be wondering: Where did this writing thing come from.
11:37 - Like, what is this strange way of describing methods that we’re seeing here? Well, what you’re seeing here is actually how you describe methods in the programming language C#.
11:48 - When you want to make a new method in C#, this is how you write it and this is how describe what parameters the method will have and what the method’s return type is and all of that, so that’s where this way of describing it comes from.
12:02 - And the reason why we’re using C# descriptions is because C# is a programming language built on top of. NET, just like PowerShell and C# is basically considered the definitive programming language for. NET.
12:16 - If you search up information about. NET types or methods, it will almost always be talking about them in a C# context, with C# examples and such.
12:25 - Because C# is basically the definitive language for. NET.
12:28 - In fact, most of. NET itself and most of PowerShell is written in C#.
12:34 - So that’s why in some places it tells us about methods in the same way C# describes them.
12:37 - Anyway, enough of that tangent, we also have a C# way of describing properties, and don’t worry, it’s just as easy.
12:42 - When you want to describe a property, first you put the type of object the property contains, then you put the name, and then this bit inside the “curly braces” here varies a little.
12:53 - When you see a “get” in here that means you can look at what’s in the property, and when you set a “set” in here that means you can change what’s in the property.
13:01 - So, in this case, this property has both a “get” and a “set” in the curly braces, meaning you can look at what’s in it and you can change what’s in the property too.
13:12 - Sometimes you might see a property that doesn’t have a set in it, and that means you can’t change what’s in it, you can only look at what it is.
13:20 - In other words, if there’s no “set”, you can’t set it and therefore it’s readonly.
13:24 - Anyway, why am I telling you about these things? Where do these descriptions actually appear? Well, let’s hop into PowerShell and I’ll show you.
13:32 - I’d like to introduce one of the last commands we’re going to look at for the rest of this series.
13:37 - This command is called “Get-Member”. And the way you use it is very simple, you give it an object, and it gives a nice, clear list of all the member it found on that object.
13:48 - If yo give it loads of objects, it will give us the members of the first object it got.
13:54 - And this command is a fantastic way for us to get a nice, clear list of what properties and methods are available on an object.
14:02 - Let me show you. So, we’re going to run “Get-Process”, and then we’re going to give the process objects to “Get-Member”, and this tells “Get-Member”: “I want a list of all the members you see on the first object I give you”.
14:15 - And… There they are! So, if we go to the top here, you’ll see that for each one we get the “Name”, the “MemberType” and the “Definition”.
14:24 - And as we look through, we can see we have all this stuff, “AliasProperty”s and “CodeProperty”s, stuff we don’t care about.
14:30 - And then we have some other stuff, and all that, but here are the methods.
14:35 - Here are all the actions that you can take on a process.
14:38 - So, we could “Close” the process or “Kill” the process or “CloseMainWindow” the process, there’s a lot of different methods for all the different actions you can take.
14:49 - And if we turn out attention to the right, to the “Definition” section, we can see that here we’re getting that C# description I talked about for each thing.
14:58 - So, can see that the “Close” method here gives back nothing, because this says “void” and it takes in no parameters.
15:06 - And if we go down, we can see that all the “Property”s here.
15:08 - So, for example, the “ProcessName” object here.
15:11 - And we can see that it gives back a string, it’s called “ProcessName” of course and we can only get it.
15:18 - We can’t change what it is, if we tried to change what it is, we’d get an error.
15:23 - And that does make sense. You can’t… really change the name of a process while it’s running, how does that even make sense.
15:30 - And yeah, so we get a nice list of all the members here.
15:32 - And we can go back up to the methods and we can look at something like “Kill” and we look at its definition and… Wait a second, what’s up with that definition? Look, so we have one “Kill” here, and then it talks about another “Kill”? What’s that about? Well, this brings us onto the last and final topic for this video.
15:52 - Methods can have different variants with different parameters.
15:56 - For example, remember the “MoveTo” method on file objects from earlier.
16:00 - If you’ll recall, that took in one string parameter, didn’t it? Well, guess what, there’s also a second variant of “MoveTo” that takes in two parameters.
16:10 - One parameter for the new name like we had in the first one, and a second parameter for whether we should overwrite an already existing file.
16:19 - So, there are two variants of the “MoveTo” method.
16:22 - When we run it with one parameter given, it runs the first variant, and when we run it with two parameters given, it runs the second.
16:29 - And there’s a word for this. We call these overloads.
16:33 - The “MoveTo” method has two overloads. One overload takes in one string parameter, while the other takes in a string parameter as well as a Boolean parameter.
16:45 - This actually explains one of the words in an error message we got earlier.
16:49 - Let’s rewind back in time for a second. Remember that error we got when we didn’t give the method the right number of parameters.
17:01 - Well, it said it can’t find an overload, it can’t find a variant of that method with that number of parameters.
17:09 - So now we truly understand that error from earlier.
17:11 - So, what we’re seeing here are those two variants, those two overloads of the method “Kill”.
17:19 - I could run “Kill” with no parameters, or if I’d like, I can also run it with this parameter.
17:26 - I can do which one I’d like. Alright, so, we’re nearing the end of the video, there’s just one trick I want to show you before I close it off.
17:32 - So, let’s say that here we have our process object with the “Kill” method on it, and I want to get a list of all the different overloads we have available.
17:41 - Now, I could go through “Get-Member” and go through and try to find the method deep within here and all of this, but there’s also another way I can get a list of all the overloads of a method.
17:54 - Now, as we know, when we want to call a method, we always write the variable dot the method name and then brackets, these brackets are necessary to tell PowerShell we want to run the method.
18:08 - However, if we don’t write the brackets, then PowerShell has a neat little feature where it will give us a list of all the overloads available, just like so.
18:19 - And you’ll notice that it’s telling me about the two different overloads I can do.
18:23 - This one, or this one. So yeah, that’s quite nice.
18:27 - Anyway, we’re nearing the end of the video.
18:28 - Now, I want to go back really quickly to a command we haven’t look at in a while, good old “Where” for filtering down objects to only ones that match a specific condition.
18:38 - As we’ll remember, using it goes something like this, saying one thing equals another.
18:45 - One thing I don’t think I’ve ever fully explained, however, is what it actually does, how does it actually work.
18:52 - We know how “ForEach” works, it runs the code that you give it once for each object it’s given, substituting “$_” for that object.
19:01 - And if our block of code returns something, it collects what it returned each time together.
19:07 - But what does “Where” do? Well, “Where” actually does a very similar thing.
19:11 - It runs the code we give it in the curly braces once for each of the objects we give it.
19:17 - But then what happens is each time it checks what that code gave back, and if the code returned the Boolean object “true”, it adds that object in.
19:33 - And if it returns the Boolean object “false”, then it does not add the object in.
19:38 - As you’ll remember, a Boolean is either “true”, meaning “yes” or “false”, meaning “no”.
19:43 - So, say I have four objects like so, and I use “-like”, which if you’ll remember lets us compare using wildcards.
19:51 - What “Where” does is it goes through each object one by one and runs our code, substituting “$_” for that object.
20:01 - And each time it does that, it looks at what our code returned.
20:05 - So, for the first one it runs our code, but because it does not match, the code gives back the Boolean object false, and because it gave back “False”, “Where” won’t allow this object in.
20:20 - Then we move onto the next one, and it runs our code again, and this time our code gave true because the object did match.
20:28 - So, “Where” does allow that object into the result and so on.
20:32 - So by the end you’ll have all the objects that matched in the output.
20:37 - That’s what “Where” does, it just runs code, this condition here with the “-eq”, I could write this outside the “Where”, and it will give me a Boolean object “true” if it matches and a Boolean object “false” if it doesn’t.
20:53 - Right now, there is no “$_” so, yeah, that’s definitely going to give false.
20:58 - Also, since the code is just being run inside the “Where”, this also means I’m perfectly free to do as much stuff as I’d like in here, I could get the hash code of the current object we’re checking and see if it’s something, I could do whatever I want.
21:09 - Anyway, to close off this video I have an interesting little task for you to try and do.
21:14 - Now, as you know, the command “ls” gives us a list of all the sub-files and sub-directories in our current folder.
21:22 - But let’s say I only wanted the sub-directories and not the sub-files.
21:29 - How would I do that? Well, the answer is actually quite simple.
21:32 - After a quick Google search, you’d find that all you need to do is write “ls -Directory” and this will give, well, only directories.
21:41 - However, a long, long time ago PowerShell didn’t actually have this property.
21:46 - We’re talking a very long time ago here, back in PowerShell… 2, not even the bundled version with Windows is anywhere near that old, that’s really old, but yeah, it didn’t have it.
21:55 - So then comes the question: How could we have gotten a list of just the directories ourselves if we didn’t have this parameter? There are actually a few ways, there was a property that gave it away and a few other things, but since we’ve been learning about types lately, how about we, just for practice, see if we can use this knowledge about types to do it.
22:17 - In reality, what we’re about to do, you would never actually do, because, well, there’s a parameter right there to do it for us.
22:25 - But just for the sake of practice and really getting up close to the objects and their types, let’s see if we can filter it down to just directories ourselves using the types.
22:36 - Now, I want to show you something here. So, here’s the output of “ls”, one folder, and one file, as we can see.
22:43 - And what I’m going to do is I’m going to ask PowerShell to tell us what type each of these objects are, so we’ll have a for each, and we’ll get the type on each object.
22:55 - We did this towards the end of the last episode if you’ll remember.
22:58 - And if we take a look, we can see something interesting here.
23:01 - Whenever we have a directory, the object to represent that directory is a “DirectoryInfo” type of object, whereas whenever we have a file, the object to represent that file is a “FileInfo” type of object.
23:15 - Now, I wonder if we can use this to help us filter down to only directories.
23:20 - So, here’s my idea, and here’s what I want you to try and do.
23:24 - What we’re going to do is we’re going to run “ls” and we’re then going to say where the type of that object is “DirectoryInfo”.
23:33 - Now, I’ll admit this is actually a very hard task, so I honestly would not be surprised if you struggle to do it.
23:40 - Just before you go and try it, the full name of “DirectoryInfo” is “System. IO. DirectoryInfo”.
23:45 - That’s its full name, and you need to write out this full name if you want to perhaps reference the type “DirectoryInfo” anywhere, just thought that was worth mentioning.
23:57 - There’re actually a few ways of doing it, so try and do in whatever way comes to your mind, somehow using the type of each object to help you do it.
24:07 - With that said, that’s all I’ll say, go ahead ad try it and if you get stuck (which you probably will because this is a very hard task) I’ll give you a tip.
24:15 - Remember, you need to write the full name if you ever want to get the type object for “DirectoryInfo”.
24:20 - Alright, here’s my tip. It’s going to look something like this.
24:24 - And inside the where, on the left of the equals, we want to get the type of the object we’re currently checking.
24:31 - And on the right, we want to get the type “DirectoryInfo”, so that way we’re literally saying, “where the type of the current object equals the type DirectoryInfo”.
24:45 - If you still get stuck, that’s fine and I’ll give you another tip.
24:47 - Alright, my final tip, in order to get the type of the current object in the where, there’s a certain method we can run that will get the type.
24:57 - And on the right of the equals, in order for us to get the type “DirectoryInfo” to compare with, there’s a certain square bracket thing we can use.
25:07 - Alright, here’s what it will look like. We’re going to get all the files and folders in here, and we’re going to use “Where” to filter them down to only the ones where, their type equals the type “System. IO. DirectoryInfo”.
25:25 - Just like so. And that is how you could do it.
25:28 - Of course, you wouldn’t do this because there’s a parameter to do it for you, but it’s a good way to practice.
25:32 - Doing these sorts of things are just great ways for you to play about with the object system, and see what’s going on in it, you basically know almost all there is to know now about the system itself, but the more time you spend looking at these things and trying to do achieve things, you better you get.
25:36 - Practice makes perfect after all. Anyway, enough of my motivational speech.
25:43 - If you look in the description, I have another task you can try if you’d like and I’ll see you all next time, where we’re going to look at important types that you should know about, as well as how to work them and much more beyond that, and with that said, bye. .