With all of that as a way of introduction,
let me jump into PowerShell,
and let me give you some demonstrations on how you can work with objects.
Normally,
PowerShell is pretty good about figuring out the types of things
that you are working with in the console; however,
sometimes you need to give it a little help.
Let me demonstrate that.
Let me create a variable, $d,
and give it a string value that kind of looks like a date.
In fact, if I look at $d, I may think, oh that's a date,
but if I try to do something with it, thinking it's a date,
like subtract the current date from that date,
I get an error because it says, hey,
I can't do that because that is not the correct format.
So the first thing to do is find out what type of object is $d,
what does PowerShell think?
And PowerShell tells me that this is a System.String object,
so this is a piece of text.
You can see there are lots of methods,
we're going to talk about strings in the next module,
and only one property of Length.
All right, so I can't really work with this as a date because it's a string.
Well, that's not totally true.
I can recreate $d, and specifically say create this as a datetime object.
And now if I do my operation of taking $d and subtracting the current datetime,
now I get the time span object that I am expecting.
PowerShell also has some operators that we can use that
will make this process even easier.
I'm going to create $i and give it a value of 10.
Now I might try to multiply $i by itself,
and that's not what I'm probably expecting.
I'm expecting a result of 100, which is 10 times 10,
but instead what I got was the string 10,
10 times, all strung together.
When you encounter things like this, that is your clue that,
he,y something is not of the right type.
You can have PowerShell tell you if it's the right type.
So I can say, hey, is $i an int32?
No, it's not.
Then I can say is $i a string, and yes it is.
So you can use the different system types,
put them in square brackets,
and then the is operator will tell you either true or false
if the object is of that specific type.
The next thing that you can do then is tell PowerShell,
hey, even though this may not be that particular type,
see if you can treat it as a particular type.
So I can say, hey, take $i and treat it as an int32,
and then that writes that value to the pipeline.
This means that I can create an expression like this
where I can take $i as an integer, in parentheses,
and then multiply it by 3, and now I get the result that I expect.
This does not change the value of $i, it is still a string of 10,
but at least for this one moment I was able to temporarily tell PowerShell,
hey, treat this as an integer and do your thing.
You can also create things such as version numbers, for example.
Here I can take a string and say treat this as a version type,
and that's the type of object that you get,
or knowing that that's version, you can say I want to create a variable $v,
make it a version, and then give it the string,
and PowerShell can convert the string to a version,
and now $v again looks like the proper version object.
Let's go back and look at that date example we started with.
I'm going to remove the variable $d, and I'll reassign $d to that string.
Now I can do the $d as datetime, and then subtract the current date and time,
and again I get my time span.
Sometimes you're working with variables and you may need them to be one type,
but maybe you need an operation where they temporarily
need to be treated as another type.
The as operator, it's kind of helpful for that.
Let me give you a little .NET trick that you can use in place of
running Get‑Member to check the object type.
Let's take $d, right, so we can see what it looks like.
Is it a date, is it a string?
All objects have a GetType method.
This comes from the .NET Framework.
This writes another type of object to the pipeline,
and you can see the properties listed there.
Using the object notation,
which we're going to dig into a little bit deeper in a moment,
I can say get the type object, and then give me the name property.
So I can see very quickly that $d is a string.
Sometimes this is faster than piping something to Get‑Member when
all you really care about is the type name.
So because I mentioned dotted notation, let's look at this a little bit deeper.
I'm going to create a variable $p, and let's get the current PowerShell process.
All right, so I can see then the default output,
and I can see the property names.
Those are not though all of the properties of this particular type of object.
Type $p to Get‑Member, and I'm going to limit this to just the properties.
All of these properties that you see are available for you to use.
Now let me point out a few things here on the properties.
You will see properties that are listed just there as properties like,
BaseProperty, container, and so on.
These are all properties that are part of the .NET object,
and that is the type name that you see there,
our System.Diagnostics.Process.
If you were to take that type name and do a search on it,
you'll end up at the MSDN, or the Microsoft documentation,
and you'll see all these properties defined.
PowerShell, though,
wants to help you as an IT pro do more with PowerShell and
not force you to know the .NET Framework.
So many times they will do things such as adding alias properties,
so that you don't have to know the actual .NET,
you know, the C# code property name,
you can reference something that maybe makes more sense to you,
or they add shortcuts, so instead of having the type PageMemorySize64,
you can just use PM as a property name.
You'll also see, let me scroll down to the bottom here,
many times PowerShell will add script properties.
These are custom properties that are created on the fly by using .NET code.
You'll also see in some cases there might be something called a property set,
which is a group of properties as well.
So you can use all of these properties in any cmdlet that needs a
property name or does something with the property name,
and we can reference these properties when we're working with an object
like I'm doing now with $p with the dot notation.
So, if I want to see just the process ID,
and here I'm using the alias id, I get the process ID of 6044,
or I can say show me the path.
Now, even though path is not part of the default output,
I see it listed there as a script property,
and I can view the path value of this particular process.
Now here's a little trick.
Sometimes when you look at Get‑Member, and you see these property names,
they may not make sense to you.
I find it often helps to see the actual value that goes to the property name,
and here's how I do that.
I take a sample object type, pipe it into Select‑Object,
and then select all of the properties using the * wildcard.
Now I can see the property name, and I can see the value.
This helps me discover what the object looks like so that
when I'm working with it with a formatting,
or selecting properties, or doing, piping this to something else,
and I wanted to work with a property, I know what the property name is,
and I know what kind of value I can expect from that.
I use this technique all the time, and I think you will too.
And you can take this dotted notation and really run with it.
For example, $p has a modules property.
This shows me all of the modules that are
associated with this particular process.
And these are Windows modules, not PowerShell modules.
This output is a nested set of objects,
and these objects have particular properties as well.
I could pipe this to Get‑Member,
but I will scroll up here and show you that module name,
probably the property.
So what I can do is I can do $p modules,
and then just say just show me the modulename.
So now I see the module name of all the modules of $p.
There's no limit to what you can do, just keep doing object.property.
property.
If the property is a nested object,
PowerShell will just automatically expand it for you.
In fact, here's a really cool trick.
Let's take $all, and hold that for all Get‑Processes.
If I do $$all.Name, this will give me a list of all of the process names.
So that's kind of a quick and easy way if you just want to get a
list of properties from a particular object.
Now as I've kind of shown you,
don't assume that what you see by default is all there is to an object.
I'm going to run my Get‑Vegetable command from PS teaching tools,
which we've looked at earlier in the course.
I left a note in the,
I left a note in the course files telling you how you can install the module.
So if I run Get‑Vegetable, right, there's the default output,
and if you're new to PowerShell, you think,
oh, okay, I see the property names there,
so let me try this, let me try running Get‑Vegetable,
and select the name, state, and count.
Well that kind of worked, I got name and count,
but did not get anything from state.
Why is that?
This is where discovery and using things like
Select‑Object and Get‑Member come into handy.
So I'm going to pipe Get‑Vegetable to Get‑Member.
All right, so I can see the properties there.
Now there's, I don't see a value for state.
There is CookedState, which may be what I want.
The best way is to get a sample object, such as corn,
and we'll do my Select‑Object * trick, and sure enough,
CookedState is the property that I want to use.
Once I know that, then I can rerun my command.
Now I get the results that I am expecting,
or there may be more to the object that you want to work
with that isn't displayed by default.
We kind of saw that with processes, let's do this with Get_Winevent.
Let me just grab a sample object.
All right, so that's the default display,
but again, that is not all there is to this object.
I save the output to $e.
So let's just take $e, and pipe that to Get‑Member.
As you see, there are lots of properties there.
Once you discover what the properties are and the values,
then I can rerun a command, so I get the system log,
the 10 most recent events, and just give me some properties,
many of them drawn from this list.
And PowerShell gives me the result now that I am expecting.
So you can use any property that you discover here.
If I decide that I want to, for example,
group, I can group on any property that I see in this list,
so I want to group on the LevelDisplayName.
Now I can see the errors, information,
and warning from the most recent 1000 entries in the system event log.
Knowing how to use Get‑Member to discover an object's
properties is something that you really need to get in
the habit of doing all the time.
Objects also have methods,
so let me give you a taste of how to work with methods.
I'm going to go ahead and start Notepad just so I have another process here,
and I'm going to save $n to get the Notepad process.
And if I pipe $n to Get‑Member, and just look at the methods,
I'm going to use the CloseMainWindow method because that
is a way to gracefully close a process.
So I can do $n CloseMainWindow using the dotted notation.
Now when you invoke a method,
you have to include the parentheses because
sometimes a method will have parameters.
For example, in the kill method,
you can see that there is a way to use kill with no parameters,
and then there's a way to use kill that takes a boolean value,
basically true or false,
that indicates whether you want to kill the entire process tree as well.
So that's why you need to use the parentheses.
So if I close the main window,
I get a result of true because if you look at the CloseMainWindow method there,
see where it says bool,
that is an indication that the output of this method is a boolean.
If you see an output of void,
that means that the method does not write anything to the pipeline.
If I try to get the Notepad process,
I get an error message because I have closed it.
Here, let me give you another example of working with methods.
Let me create an array of names, and so the first name in this array, index 0.
remember that from our previous module, if I look at the member type,
I know that there is a member called ToUpper.
So with this, it'll take the string and make it all uppercase.
There is also another option there which we're not going to to use.
So I can take $n, and for each object,
I want to take the value of $n and make it all uppercase.
And there we go.
So I wasn't able to invoke the method using the dotted notation.
In the same way that I use the dotted notation against a
group of objects in order to get a property,
you can do the same thing with methods.
Maybe not all the time, but in this particular case, you can.
So I can say, hey, take all the entries of $n and make them all uppercase.
So it's a much faster and easier way than having to
pipe through to foreach object.
There is also a member called substring, which allows me to get
a part of a string starting at some index number, and the index
for the strings always start at 0.
So here's what I could do, for each object in $n,
I'm going to create a new string.
Now here I'm using a variable expansion.
You start seeing some things that we've been looking at
earlier in the course all come back here.
I'm using a sub expression, and I'm going to get the substring of the
first object in the pipeline, so FRED, and the substring, I'm using the
method that takes a starting index and a length.
So I'm getting the starting at 0 and going 1 character, in
essence the first letter of the name, and then I'm going to take
that string and make it all uppercase.
And then I'm immediately appending to that the substring of the current object
starting at index 1, and because I don't specify a length,
it gets the rest of the string.
So now what this has done is created a proper case
version of all of those names.
There are other ways that you could do this, I just wanted to kind of use
this as a demonstration of invoking method and also to reinforce concepts we
have looked at in this course. In the next module,
I'm going to show you other things that you can do with strings, this
is kind of a little taste of what you can expect.
It's very important that you understand what an object is,
how to use it, how to discover its properties,
how to view the properties, how to access methods.
One quick thing though about the method, don't feel that you have to be
looking for methods in order to do something to an object.
Look for cmdlets first. Many of the cmdlets are
based upon the method of an object,
so you don't have to kill a process by invoking the kill method,
there's a stop process cmdlet that you would use.
So always look for cmdlets. The methods listed there are
for cases where there is no cmdlet or you need to do something to fill a special use case.