Overview
In this PowerShell course, trainer Garth Schulte will teach you about commands, pipelines, objects, automation, scripting, and more. Garth starts with a single machine to cover PowerShell basics and works his way up to real-world scripting against a full network of Windows machines, spanning many versions of Windows.
Supplemental File
Welcome to PowerShell 4 Foundations!
Garth presents a case for PowerShell and why this is a great time to get on board with the future of configuration, management, and automation of Windows environments. We also define what PowerShell is, what it's capable of, who this course is for (everyone!), what it contains, and get familiar with our learning playground, the Virtual NuggetLab. Let's rock!
Knowledge Check
PowerShell can be used to perform which of the following?
Knowledge Check
PowerShell can be defined as which of the following? (Choose three)
Knowledge Check
Native commands in PowerShell are referred to as which of the following?
Knowledge Check
Which of the following PowerShell versions will be covered in this course? (Choose two)
Installing PowerShell 4.0
Get up to speed on the installation process for PowerShell 4, including its requirements and supported operating systems. We also walk through the process of installing PowerShell 4 on a supported legacy operating system, discuss mass deployment across the enterprise, and even write a one-liner to check the version of PowerShell across all machines in a domain!
Knowledge Check
If you're running Windows Server 2008 R2 and newer, or Windows 7 and newer, PowerShell 4.0 is installed by default. True or false?
Knowledge Check
Which command will print the installed version of PowerShell?
Knowledge Check
PowerShell 4.0 can be installed from which of the following packages?
Getting Started
Take a tour of the PowerShell Console and the PowerShell ISE, the main tools for writing commands, scripts, and interacting with PowerShell. We also define the purpose of each tool and learn how to configure, customize, navigate, and execute the commands of each tool.
Knowledge Check
The cmdlet to get information about the current host environment is _____. (Hint: cmdlets are typically in the form Verb-Noun.)
This interactive assessment is available in the full learning experience.
Knowledge Check
Which of the following do the same thing? (Choose three)
Knowledge Check
The Powershell ISE (Integrated Scripting Environment) includes all features of the Console, plus additional UI elements for building and running scripts. True or false?
Knowledge Check
Which of the following PowerShell ISE features assist in writing scripts? (Choose three)
Getting Help
Learn to use the help system and help cmdlets in PowerShell! We look at how to keep help topics updated on your client machines, save help to a file share for disconnected clients, interpret help by understanding syntax and parameter types, and walk through a demonstration to show you the many common and not-so-common ways to use the Get-Help cmdlet!
Knowledge Check
You can download full help topics in Powershell with the Update-Help cmdlet. True or false?
Knowledge Check
When viewing the syntax of a cmdlet, what kind of parameter has NO brackets around it?
Knowledge Check
Which of the following are valid parameter sets for Get-Help? (choose three)
Knowledge Check
You can omit the name of a __________ parameter, entering only the argument as long as it's defined in relative order.
This interactive assessment is available in the full learning experience.
Commands
We cover the six PowerShell command types, including how to find them using Get-Command. We also look at the process for discovering and learning a "cmdlet a day," as well as creating and using aliases.
Knowledge Check
The following are types of commands: (choose three)
Knowledge Check
When using Get-Command, the -CommandType parameter is used to filter results by the command type. True or false?
Knowledge Check
You cannot run traditional DOS commands in a Powershell script. True or false?
Knowledge Check
Which cmdlet is used to load previously saved Aliases?
The Pipeline
Garth introduces you to the basics of constructing PowerShell pipelines! We look at the process for chaining commands together, and see just how easy PowerShell makes it with its object-oriented approach. We also run through a few fun demonstrations and finish with three pipeline challenges you can try on your own.
Knowledge Check
Powershell is object-based, NOT text-based. True or false?
Knowledge Check
Cmdlets that send output to a file, array of strings, or printer, for example, start with _____.
This interactive assessment is available in the full learning experience.
Knowledge Check
Which cmdlet can you use in the pipeline to select specific properties from objects?
Knowledge Check
There is a limit of five Pipe ( | ) commands in a single Powershell Command. True or false?
Objects
We define what an object is, where they come from, how they're used, and some of the common things we can do with them in the pipeline! We also learn about another crucial cmdlet for discovering what objects consist of, get-member.
Knowledge Check
An Object is described by a template or blueprint, which is known as a:
Knowledge Check
The items of an object that describe its state are known as _______.
This interactive assessment is available in the full learning experience.
Knowledge Check
The -whatif switch parameter is great for dry-runs and testing PowerShell commands or scripts. True or false?
Knowledge Check
Pipe into this Cmdlet in order to get specific properties of a object:
Knowledge Check
Match each option:
This interactive assessment is available in the full learning experience.
Extending the Shell
Garth provides an explanation and demonstration of what modules are used for in PowerShell! We cover the process for loading and unloading, automatically importing, and creating your own modules.
Knowledge Check
Modules are preferred for the following reasons (choose two):
Knowledge Check
Modules are supplied by Microsoft only and cannot be created by users. True or false?
Knowledge Check
Which of these are ways to load a module? (Choose three)
Extending Objects
Learn how to extend PowerShell by adding your own properties and methods to types and objects dynamically. We talk about PowerShell's Adapted Type System (ADT), Extended Type System (ETS), and cover member types and methods used to extend types and objects.
Knowledge Check
Which feature allows developers to expand the properties of a Powershell object?
Knowledge Check
Use this command to permanently add a member to an object in your script.
Knowledge Check
Use this command to create an object that you define yourself from "the ground up".
This interactive assessment is available in the full learning experience.
Knowledge Check
This command updates an object definition for all future instances of an object that are created in your script:
Formatting Output
Explore how PowerShell determines what properties and formats are used when outputting objects. We also cover popular formatting cmdlets, and many ways we can use them to control how objects are outputted to the console.
Knowledge Check
Powershell will lookup format files at the end of the pipeline for output display. True or false?
Knowledge Check
Powershell format files are in which format?
Knowledge Check
Match each command and option to it's output
This interactive assessment is available in the full learning experience.
Knowledge Check
Updating the Format files is the best way to change the default output for your objects. True or false?
The Pipeline Returns
Peer inside of the pipeline and cover parameter binding to observe how PowerShell wires up cmdlets together in the pipeline! Understanding these concepts, along with custom properties and parenthetical commands, gives you utmost control over the pipeline, ensuring there's nothing you can't do when stringing commands together.
Knowledge Check
Which of the following are ways a pipeline can accept a property? Select all that apply.
Knowledge Check
Cmdlets can accept almost any object if they allow pipeline input for a <PSObject>. True or false?
Knowledge Check
Which of the following cmdlets transforms a comma-separated file (.csv) to a PS object?
Knowledge Check
Get-Content will work to send data to a cmdlet that accepts pipeline input by property name. True or false?
Providers
We cover what providers are and how they abstract any underlying data store into a standardized view accessible from PowerShell. We also walk through a demonstration to get familiar with many of the core provider cmdlets.
Knowledge Check
Providers treat datastores such as Certificates or the Registry as:
Knowledge Check
You can CD (change directory) into a Provider entry point. True or false?
Knowledge Check
Cmdlets like Set-Item or Get-ChildItem are generic ways to work with providers. True or false?
WMI & CIM
We explore WMI and CIM, technologies that are for accessing management information on a machine. Along with demystifying each one, we talk about the need for utilizing low-level information, and the cmdlets for doing so. We also look at one of the best tools for exploring and discovering instances, classes, and properties in the repository.
Knowledge Check
WMI and CIM are interfaces for working with which of the following?
Knowledge Check
Powershell cmdlets are often just a quick way to work with the WMI/CIM repository. True or false?
Knowledge Check
You can pass an instance into Get-CimAssociatedInstance to learn about things like dependent services. True or false?
Knowledge Check
Invoke methods of a CIM class with this cmdlet:
This interactive assessment is available in the full learning experience.
Remoting
Journey through the wonderful world of Remoting, which is truly the best thing since sliced bread! Get up to speed on the WinRM service and see firsthand what we can accomplish with Remoting, from one-to-one and one-to-many sessions, to persistent sessions, and even implicit remoting. The future of multi-machine management begins here!
Knowledge Check
Which of the following protocols does WS-Man use?
Knowledge Check
You can use the command Enable-PSRemoting to turn on Powershell remoting on both Server and Client Windows. True or false?
Knowledge Check
Use this cmdlet to enter a 1-to-1 remoting session against another machine:
This interactive assessment is available in the full learning experience.
Knowledge Check
Which of the following can you use Invoke-Command for? (Choose two)
Jobs
Discover how to create the many kinds of jobs for asynchronous work in PowerShell, from background jobs to remote jobs to automation using scheduled jobs... you see them all!
Knowledge Check
Types of Powershell jobs include: (choose three)
Knowledge Check
Use this cmdlet to stop a running job:
This interactive assessment is available in the full learning experience.
Knowledge Check
When receiving data from a job with Receive-Job, use this switch to prevent the data from being cleared.
Knowledge Check
Get-Job will only return background jobs that are running in the current session. True or false?
Workflows
Discover what workflows are about and how to take advantage of them in PowerShell to control long-running processes, including how to coordinate and execute parallel tasks. We also walk through a demo of how to create a process that can survive failure and server restarts!
Knowledge Check
Functions and Workflows are fundamentally the same thing. True or false?
Knowledge Check
Which of the following keywords is used to define workflows?
Knowledge Check
Which of the following are ways that parallel workflows can be designed? (Choose two)
Knowledge Check
You can mix Sequential Workflows inside of Parallel script blocks. True or false?
Scripting - Getting Started
Get started in the world of PowerShell scripting by learning the anatomy of a basic script, executing scripts, dot-sourcing scripts, security features, and execution policies. Plus, learn how to digitally sign scripts to protect them yourself!
Knowledge Check
Powershell scripts are a block of one or more Powershell commands saved in a .ps1 file. True or false?
Knowledge Check
Built-in security policies for Powershell scripts include which of the following? Select all that apply.
Knowledge Check
Persisting your variables and functions after a script ends is done with:
Knowledge Check
Scripts signed with a self-signed certificate will run on remote machines whose Execution Policy is set to RemoteSigned. True or false?
Scripting - Essentials
Garth walks you through many of the core language concepts in PowerShell. We cover variables, conditional statements, looping, error handling, and functions before bringing it all together with a fun, real-world script!
Knowledge Check
Strongly typing variables forces the values assigned to that variable to convert to that type when possible. True or false?
Knowledge Check
Use this command instead of a large series of if..elseif statements for improved readability.
Knowledge Check
Which of the following are valid looping commands in Powershell scripts? Select all that apply.
Knowledge Check
Which common property dictates how a script proceeds after running into an error?
This interactive assessment is available in the full learning experience.
Knowledge Check
Use this syntax to escape a large block of text as literal text in a script.
Scripting - The Real World
Garth walks you through two fun and useful real-world scripts! We look at how to import users into Active Directory and monitor a network of servers. We'll also cover how to debug and walkthrough scripts, an invaluable asset every PowerShell administrator needs to write bulletproof scripts.
Knowledge Check
The Powershell operator to test if two values are equivalent is ___.
This interactive assessment is available in the full learning experience.
Knowledge Check
Use this statement to gracefully recover from any errors in your Powershell script:
Knowledge Check
A do {...} while loop is a valid alternative to creating a schedule job for a Powershell script. True or false?
Knowledge Check
Write the cmdlet to pause or sleep your script for a specified amount of time.
This interactive assessment is available in the full learning experience.
Knowledge Check
Use this feature of the ISE to pause code execution at a specific line of code.
Desired State Configuration - Getting Started
Garth gets you up to speed on the basics of Desired State Configuration! We talk about the need for this wonderful declarative management platform, get familiar with the components, and look at how to utilize it to ensure the state of a machine.
Knowledge Check
Powershell Desired State Configuration (DSC) is used to:
Knowledge Check
Match each operation with its step.
This interactive assessment is available in the full learning experience.
Knowledge Check
This deployment model is when a user actively tells a machine to apply a desired state.
Knowledge Check
Write the cmdlet to push a Desired State Configuration.
This interactive assessment is available in the full learning experience.
Desired State Configuration - Making it So!
Garth covers Desired State Configurations deployment models, push, and pull. We set up an HTTP pull server, download the DSC resource kit, and even utilize custom DSC resources!
Knowledge Check
Which deployment model routinely updates any changes in configuration on a refresh interval?
Knowledge Check
What are the steps required to setup the Pull deployment model include? Select all that apply.
Knowledge Check
The push and pull deployment models can both achieve the same configuration updates. True or false?
Knowledge Check
The Local Configuration Manager uses this part of the meta file to tie a configuration to the local machine.
Tips, Tools, and Resources
Garth shows you how to use profile scripts, points out some popular tools to improve your PowerShell experience, and gives you a list of great resources to help you in your journey to PowerShell mastery.
Knowledge Check
Shell customizations, drive setup, and other routine tasks you perform on every startup are good candidate for a profile script. True or false?
Knowledge Check
From where can you launch the Add-on website tools?
Knowledge Check
Which of the following are alternatives to Powershell ISE? (Choose two)
Conclusion
I hope this has been informative for you and I would like to thank you for consuming.
View Transcript
Welcome to PowerShell 4 Foundations!
0:00Hello, my friends, and welcome to PowerShell 4 Foundations.
0:03My name's Garth Schulte.
0:04I'll be your host throughout this course
0:06where we're going to learn all about the future
0:08of administration configuration and automation
0:11here in Microsoft environments.
0:14Now is as good a time as any to get some PowerShell skills
0:16in your toolbox.
0:17Maybe you've been avoiding PowerShell.
0:19Maybe you just haven't gotten to yet.
0:20Or maybe you clicked on that little blue button
0:23in the taskbar out of curiosity and said,
0:25you know what, this is just a glorified command dot
0:27exe with a blue background.
0:29No, thanks and you go back to your GUI ways.
0:31Well, I'm here to tell you and show you
0:33that PowerShell is a big deal.
0:35Microsoft is serious about it, an employers
0:37are starting to get serious about it.
0:39And once employers really understand what PowerShell is
0:41and what it can do, they see two things, right, they see time
0:44and they see money.
0:45In these are two areas that PowerShell
0:46can give back immensely.
0:48In fact, if I'm an employer right now looking
0:50to fill administrative position, and I've got some candidates,
0:53you know what I'm going to do?
0:54In fact, let's do this.
0:55Let's say we've got Bob over here,
0:56and we've got Joe over here.
0:58So Bob and Joe are vying for the same job.
1:00What I'm going to do is I'm going to give them
1:02a common everyday task.
1:04Maybe I've got 50 users in a department
1:06that all need their password reset or some attribute
1:08changed in Active Directory.
1:10Well, I'm going to give Bob and Joe that task
1:11and say, go do that.
1:12Come back when you're done.
1:13And let's say that Joe, Joe's like Bradley Cooper
1:16from Limitless.
1:17Anybody see Limitless where he takes the smart pill
1:19and he's like a ridiculous genius?
1:20Well, let's say Joe took the PowerShell pill.
1:23Joe writes a couple commands or turns it into a script,
1:27and does it, comes back in maybe a minute,
1:29and says, oh, by the way, it's done.
1:31And I made it repeatable.
1:32Here you go.
1:33Here's the script if you ever need to do that again, Boss.
1:36Where Bob is still over there waiting for Active
1:39Directory to launch.
1:39He's farting around in the GUIs.
1:41Come on, Bob, get with the show.
1:44PowerShell's the future.
1:45And you know, obviously, who'd get hired there is Mr. Joe.
1:49So together, you and I are going to learn to be like Joe.
1:52So if you're like Bob now, no worries,
1:54because it doesn't take much to learn
1:56and become effective and dangerous in PowerShell.
1:59Now let's get to this Nugget.
2:00This Nugget, I'm going to give you more reasons
2:02to learn PowerShell.
2:03If that wasn't reason enough, we'll take a look at many more.
2:05We'll also define what PowerShell is,
2:07and then we'll get a bird's eye view of the entire course
2:09to see all the things that we're going to cover.
2:11And we'll also get you familiar with our lab and demonstration
2:14environment, the Virtual Nugget Lab.
2:15We've got a five-machine network at our fingertips
2:19ready to go that span many versions of PowerShell
2:21and many versions of Windows.
2:24I'm excited to be your host.
2:26Thanks again for joining me.
2:27Let's jump in.
2:28Let's make the case for PowerShell
2:29and start with a simple question.
2:31How do you currently perform and automate tasks
2:34across some of these common areas such as Active Directory?
2:36We just saw an example of Bob and Joe.
2:38But let's say that you were tasked
2:39with creating a bunch of users or maybe
2:41had to move users around, or migrate users,
2:43or maybe you had to change some attributes of users,
2:45or join a computer to a domain.
2:47If you don't PowerShell, the answer to all those
2:49is probably the GUI.
2:50Here's another one, the file system.
2:52How do you currently create and manage
2:54those directory structures for things
2:55like reports and backups?
2:57How do you archive that stuff?
2:58If the answer is by hand, I'm sorry.
3:01But it's not going to be after you learn PowerShell.
3:03Also another one here is for personal use.
3:05I'll give you a good example.
3:06I've got a network-attached storage device here
3:09that has 15 years worth of photos and videos
3:12from the family, right?
3:13They all have iPods and iPads and phones
3:15and any time they upload anything,
3:17my only requirement was put it in the year directory
3:19for the year that it is.
3:20So I've got 15 directories that span
3:2215 years over two and a half terabytes of data
3:24and everything has the default name, dsc9384.jpg or dot mpg
3:29or whatever.
3:30And I just let it go.
3:30I'm like, whatever, some day I'll get to that.
3:32Well, once I got some PowerShell skills, I'm like,
3:35you know what, this is going to be easy.
3:36It took me an hour to write a script
3:37to organize all that, appropriately name it,
3:39now anybody can find exactly what they're looking for.
3:42And that was a super fun one to build.
3:43What about server an operating system stuff?
3:45You know, those common everyday things
3:47that we do as administrators, like manage processes,
3:49services, event logs.
3:50Do you do that through the GUI?
3:52Probably.
3:52And you probably even do it on a machine by machine basis.
3:55PowerShell can help us out immensely in all those areas.
3:57What about-- and here's a really good one adding and removing
4:00features, roles and features.
4:02Let's say you've got three servers,
4:03and they're all going to be Hyper-V servers.
4:05How do you get Hyper-V on those?
4:06Would you log into each one individually,
4:08walk through the Add and Remove roles and Features Wizard?
4:11Probably.
4:12That sounds like half a day of work
4:13getting three Hyper-V servers up and running, right?
4:15With PowerShell you could do it in minutes.
4:17One command is literally a one-liner to do that.
4:19And you could send that command to all those machines
4:22and have them fully configured in no time.
4:23Pretty cool.
4:24Speaking of Hyper-V, virtualization
4:26is a big deal these days, right?
4:27But it's also a big time sink.
4:29If you don't know PowerShell, you're
4:30probably spinning up your environments by hand,
4:32and I can tell you from experience here
4:34being a trainer, I'm constantly spinning up
4:35virtual environments.
4:36And doing it by hand used to take forever.
4:38Doing it with PowerShell?
4:39Not only does it not take is long, but it's repeatable.
4:43So if I ever need to respin up that environment,
4:45I just run a script, boom, there it is.
4:46There's my network at the point exactly where I wanted it.
4:48And in fact, I did that for our Virtual Nugget Lab,
4:51spun up a network.
4:52Changed the computer names, brought up a domain controller,
4:54added all the machines to the domain,
4:56did a few configuration points, and now
4:57if I ever need to get us back to that starting point,
5:00I just run the script.
5:01What about server applications?
5:02How you manage and make configuration changes in things
5:04like Exchange, SQL, Systems, and our SharePoint?
5:06The list goes on and on there.
5:07The answer is probably the GUI.
5:09You're go into to the GUI, find what you're looking for,
5:10you make the change.
5:11But the problem with the GUI?
5:12It's not repeatable.
5:13What if you need to do it again, and again, and again?
5:15You're back inside of the GUIs.
5:17So PowerShell is great, because it lives
5:19outside of all these things.
5:21It's one tool to rule them all, and this is just
5:24a small example.
5:25Small small, small example of some of the things
5:27that we can do with PowerShell.
5:28How about a top 10 list?
5:30The top 10 reasons to learn PowerShell.
5:32Ready?
5:33Go.
5:33Number 10, it's easy to learn, really.
5:35It is incredibly easy to learn.
5:37Jeffrey Snover, the man and the myth,
5:38the legend behind PowerShell, somehow
5:41took the essence of the GUI and brought into PowerShell.
5:44And this is why GUIs are good, right?
5:46GUIs are good because it's what we're used to, number one,
5:49but they're also easy to learn.
5:50Once you learn something in one GUI,
5:52you can carry it over to the next.
5:53So the first time you learned how the X button to close
5:56the window, or the Minimize button or OK, Apply, Cancel,
5:58once you learn all those, you can carry it over
6:00to the next GUI.
6:01So it's efficient for learning how to learn.
6:03PowerShell is the same way.
6:05Not only will you be learning quickly,
6:07you'll be ripping off commands across your whole network
6:10in no time, but you learn how command-lines work,
6:12the structure, the syntax, the convention,
6:14you carry that information over to the next command-line.
6:17So whether you're working Windows, or SQL
6:18Server or SharePoint, it'll just be learning specifics
6:21about those command-lines.
6:22And we'll talk a little bit more about this,
6:24how it's discoverable and predictable,
6:26but just know that PowerShell is easy to learn.
6:28And CLIs get a bad rap, and that's
6:30kind of why PowerShell's a bad rap because who wants to work
6:33in a text-based environment?
6:35Nobody.
6:35But PowerShell's different as you'll see.
6:37Number nine, it can be the only way.
6:40Yeah, not every single feature is inside of the GUI.
6:43In fact, a lot of things in Active Directory
6:45and other products, you're only going
6:47to be able to access using PowerShell.
6:49Number eight, GUIs are slow and, of course, this incomplete kind
6:53of ties into number nine there.
6:54But the slow part is what I want to highlight here.
6:56No matter how good you are at doing something in the GUI,
7:00you'll never be able to do it as fast as you
7:01can do it in PowerShell.
7:03As an example, say you were tasked with creating 100 Active
7:05Directory Users.
7:06They give you a spreadsheet, here you go.
7:08What are you going to do?
7:09If you're going to do that in the GUI, at most, at the best,
7:11let's say it takes you a minute to create
7:13a user in Active Directory based on that spreadsheet.
7:15Enter all that data, you hit Create,
7:17and then you go to the next one, the next one, the next one.
7:18So if it takes you a minute, to do 100 users,
7:20that's a little over an hour and a half.
7:22In PowerShell, one line of code to import those users
7:25into Active Directory.
7:26I'm not kidding.
7:26One line, so it would take you seconds.
7:30Number seven, it's actually really fun to use.
7:34I'm not kidding.
7:35It's like you got to be careful with this stuff,
7:37because you could end up in PowerShell anonymous, right?
7:39PA.
7:40But really, once you get dangerous with this stuff,
7:43you're going to want to keep going more, and more, and more.
7:45And once you get familiar with a few commands,
7:47you get them under your belt, then
7:48you're going to want to start writing scripts and doing
7:50some incredibly neat stuff with very little effort.
7:54So it's fun to use as you'll see.
7:55It's like it's like Pringles, you know,
7:57once you start you can't stop.
7:58Once you pop, you can't stop.
7:59PowerShell and Pringles, one in the same.
8:01Number six, you can do so much with so little.
8:04These commandlets, which are native PowerShell commands
8:07that we'll get plenty into, have a lot of power in them.
8:10Combine that with something called the Pipeline, which
8:12we're going to look a lot at, which essentially allows
8:14us to connect commands together and pass data between commands,
8:18you'll be astounded.
8:19Half the time, again, you won't need a script
8:21to do something that you would normally need a script for.
8:24Number five Microsoft is baking it in to everything.
8:26Almost every GUI we use today on the server side
8:29is just executing PowerShell commands under the hood.
8:31And that trend is going to continue
8:32until eventually PowerShell is underneath everything.
8:36Number four, the time and cost savings are astronomical.
8:39We looked at this and an example of this earlier,
8:41but I mean this is the truth.
8:43Employers are going to be hiring people
8:44that have PowerShell skills over people that do not,
8:46because they're the ones that are going to help move
8:49the business forward by automating and making
8:51things repeatable.
8:52They'll never do things more than once,
8:53because they'll never half to.
8:55They do it once, they turn it in to a script or store
8:57that command somewhere.
8:58If they ever have to do it again, they just run it,
9:00so time wasted doing the same things over and over.
9:03Number three, it's enabling interactivity like never
9:05before.
9:06This is a big one.
9:08Here's why.
9:09Remember over here server apps?
9:10What if I had to create a process
9:12that did some kind of synchronization or coordination
9:17across some of these products, how would you do it now?
9:19Not easily.
9:20PowerShell makes it easy because, again, it
9:22sits outside in all of these products exposed commandlets
9:25that we can tap into from PowerShell.
9:26So now all of a sudden it becomes
9:28very easy to do cross product integration.
9:32Number two, it's the Microsoft standard for automation.
9:35Now, going forward, Microsoft's in it for the long haul
9:37here with PowerShell.
9:38So once you learn how to use PowerShell
9:41and how to automate something, you'll
9:42never need to, or even want to, do it any other way again.
9:45It's just that easy.
9:46And number one, your future is an IT professional
9:49depends on learning PowerShell.
9:51This is the skill that employers are
9:53going to be looking for in the future.
9:54So it's as good a time as any to learn PowerShell.
9:57In fact, now is the perfect time to get into PowerShell,
9:59because it's just starting to get interesting, really
10:02interesting.
10:02We're going to be focusing heavily
10:04on PowerShell Version 4.
10:06Version 4 brings a lot of stuff to the table.
10:08They've worked out a lot of kinks.
10:10They've added a lot more commandlets, which
10:11are going to give us a wider and deeper reach into Windows
10:13and beyond, and they've introduced a new feature called
10:15DSC, Desired State Configuration, which
10:18is going to, again, change the face of configuration
10:20management as we know it.
10:22So now that we know why we should be learning PowerShell,
10:24hopefully, let's talk about what PowerShell is.
10:26If I had to define PowerShell in one sentence,
10:28I would call it an object-oriented command line
10:30shell and scripting language based on the dot NET
10:32framework that gives us all those benefits, everything
10:35we need to do here from an administrative perspective.
10:37But here's the thing, this is an important keyword right here,
10:40object-oriented.
10:41Windows is an object-oriented operating system,
10:44but this term can scare a lot of people away, right?
10:46Because this is a developer term,
10:48object-oriented programming, things like classes,
10:50polymorphism, inheritance, instantiating objects.
10:53But here's the thing.
10:54We only need to know objects.
10:56Properties, methods, events, things
10:57we'll cover when we get into objects,
10:58but this is really the magic, the secret sauce
11:00behind PowerShell is it's an object-based shell.
11:03So we can create these really elegant pipelines,
11:05pass objects, and this is why we can do so much with so little.
11:08So again, the man and the mind behind PowerShell's name
11:11is Jeffrey Snover, brilliant guy.
11:12And his vision for PowerShell was
11:14outlined in something known as the Monad Manifesto, Monad,
11:17the name of PowerShell before it was actually
11:19renamed to PowerShell.
11:20But his vision was essentially to give anybody, power users,
11:23administrators, whoever could tap into PowerShell here,
11:25the power of dot NET framework and the power of a developer
11:28without actually having to do any coding or development work.
11:31The rest is history.
11:32So what is PowerShell?
11:34First up, it's a command-line shell.
11:36So it's just like command dot exe.
11:37In fact, we can run all those utilities
11:39that you're used to running, Ping, IP, config, [INAUDIBLE],
11:41all those things we can still do in PowerShell.
11:43So theoretically, you never have to open up command dot exe
11:46again.
11:46Just use PowerShell for that kind of stuff.
11:48We've got PowerShell specific things
11:49that we can do that replaces those to work
11:52with objects rather than text.
11:54And actually, that's going to be a big part of this course.
11:57We're going to learn a lot of commandlets.
11:59So think of commandlets like regular commands
12:01on steroids, because they're little dot NET utilities that
12:04send us back dot NET objects that we can work with passed
12:07down the pipeline to other commands
12:09or do all kinds of stuff with.
12:10Cool stuff that you will see.
12:11Secondly here, it is a scripting language.
12:14It's very simple scripting language
12:16once you get the hang of it.
12:16We have variables.
12:17We have control flows, so once we
12:18want to start doing more complex things,
12:21we're going to break out the scripts to do so.
12:23It's object-based rather than text-based,
12:25and this is really what sets PowerShell
12:27apart from a traditional Linux shell like Bash
12:30or even the Legacy command prompt that we
12:31were talking about here.
12:32So traditional shells output text this is the big difference
12:36right here.
12:37And that's going to make it difficult to do things
12:39like formatting and filtering.
12:40And there are tools to help us get the job done
12:42in those old school shells, like setting preferences,
12:45but it takes years to master things like regular expressions
12:47to do the heavy text parsing.
12:49So because PowerShell takes advantage of the underlying dot
12:51NET framework and uses objects to represent data,
12:54it's going to make life a lot more fun and efficient inside
12:57of the shell.
12:58PowerShell's also consistent with its syntax
12:59and conventions, and this is a big one
13:01because, again, with those Legacy shells,
13:03people build command line utilities all the time,
13:05and there's no standard.
13:06Again, some people may use dashes or slashes or whacks
13:09or whatever for their switches and there's no consistency
13:12across perimeters.
13:13Well, with PowerShell, you learn a commandlet,
13:15you learn a parameter, especially
13:17if it's a common parameter, that parameter's
13:18going to work the same across all the other commandlets.
13:20And that syntax is going to be the same across all
13:22of the commandlets, so it's is very learner friendly and user
13:25friendly.
13:26Now, this next bit is probably one of the coolest parts
13:29about PowerShell.
13:30This is a Microsoft term, are you ready?
13:31It's discoverable and predictable.
13:34Discoverable means we can easily find what we're looking for.
13:38So this happens a lot.
13:39The first time you fire up PowerShell, as most people do,
13:42they look at the screen and they go now what or what's next?
13:47Well, this is what's next.
13:48What's next is you need to find what you're looking for.
13:50So we've got a search engine on top of everything
13:53in PowerShell called Get Dash Comman.
13:55It's a commandlet.
13:56It's a very easy to use search engine
13:57to help us find what we're looking for.
13:59And PowerShell commandlets have a really consistent naming
14:03convention that goes in the form of verb, you know,
14:06get, add, remove, clear, that kind of thing, the action
14:08that you're taking.
14:09And then the noun, what research are
14:11you working with, service, event log, process, computer,
14:13so and so forth.
14:14So this is why it's predictable, because if a new set
14:16of commandlets come up for a product, you already know.
14:18You can essentially predict exactly what you're looking for
14:22based on that product.
14:22It's also flexible and extensible.
14:25So comes packaged with lots of core commandlets.
14:28But let's say we're in a Windows 8.1 machine,
14:30we have it installed, and we want to remotely manage
14:32Active Directory.
14:33Well, guess what?
14:34We can download the remote server administration
14:35tools which give us access to all
14:36those Active Directory commandlets.
14:38We import that, we work with them,
14:39and boom, now we can work with Active Directory from anywhere.
14:42And that goes for all the other server side products
14:44as well in many other areas.
14:46In fact, we can build our own modules.
14:47We can even build our own commandlets
14:49in the dot NET framework.
14:50It's literally five lines of code
14:51set up to skeleton to create your own commandlets.
14:53It's really, really neat stuff.
14:55It's dynamic and powerful as we'll
14:56see throughout the course.
14:57It's automatable and, as you'll see,
15:00it's now everywhere in Windows.
15:02So what are we going to be doing with PowerShell in this course?
15:04Well, I tell you, if you know nothing about PowerShell
15:06or if you know something about PowerShell,
15:08you've come to the right place.
15:09So we're going to start from the ground up,
15:12and then we're going to turn it up.
15:13So we'll start here immediately following
15:15this Nugget with installation.
15:16I'll show you how to install it on Legacy systems,
15:18how to install it across the Enterprise.
15:20And we'll talk about what versions of PowerShell
15:23installed by default, what's supported, and specifically,
15:26where PowerShell 4 is supported and what the requirements are.
15:28Then we'll get started.
15:29Here we're going to get familiar with our tools.
15:31We'll get familiar with the ISE, the Integrated Scripting
15:33Environment, as well as the shell itself,
15:34the old command-line shell.
15:35Those are the two screenshots we saw in the previous screen.
15:37And we'll get familiar with get command.
15:39So we're very familiar with how to use that search
15:41and define exactly what we're looking for.
15:44Then we'll get into the Help System, a very, very incredible
15:47and dynamic help system that will make it very easy to learn
15:51what all these commandlets do, everything from the syntax,
15:54to description, to examples.
15:55And we'll take a look at all different ways we can
15:57use that wonderful Help System.
15:59From there, we're going to get into commands.
16:00So here's where we're going to learn all the terminology
16:02in PowerShell.
16:03What's a command?
16:04What's a command level?
16:05What's a function?
16:05What's a script?
16:06What's an alias?
16:06So all those components that make
16:07a PowerShell, all those things we'll be working with we'll
16:09define there.
16:10We'll also get familiar with syntax,
16:11and we'll talk about some of the common commands
16:13that you'll be working with every day inside of PowerShell.
16:16From there, we'll get into objects.
16:17We'll define what an object is.
16:18We'll see why they're so critical to understanding
16:20how PowerShell functions.
16:22And we'll even look at something called
16:23get [INAUDIBLE], which allows us to interrogate an object
16:26to see everything there is to know about it.
16:28We'll get into pipelines.
16:29You've got to know objects before pipelines,
16:30because pipelines are how we're going
16:32to take data that's returned from a commandlet
16:34and pass it down the pipeline.
16:35And do some more with it, filter it, format it, sort it,
16:38transform it, or maybe just do something with it, right?
16:42So big look at the pipeline, and we've actually
16:44got a couple of Nuggets on the pipeline.
16:45One to get introduced to it, one to go deep down
16:48to understand how objects are passed around the pipeline.
16:51From there, we're going to get into providers.
16:53And providers essentially allow us
16:55to take an underlying data source
16:57and make it look like a file system.
16:58So everybody's familiar with the file system, right?
17:00You've got directories, subdirectories, subdirectories,
17:02and files.
17:03While providers abstract that underlying data source to make
17:06it look like this, so we can map a drive
17:08to things like the registry and make the registry look
17:10like a file system, which will make it
17:11very easy for us to work with.
17:13We'll also get into Windows Management Instrumentation
17:15and the Common Information Model, which
17:18will allow us to tap into the functionality of the operating
17:20system.
17:21We'll be using that quite heavily, too.
17:23It's a great way to get and extract information out
17:26from the operating system level.
17:27And, again, even tap into and utilize
17:29some of that functionality at the OS level.
17:32We'll get into remoting, which is
17:34how we're going to execute commands across the network.
17:37We've got other ways to do it, but this
17:39would be the best and most secure way of doing it.
17:41So if we want to execute, send commands,
17:43PowerShell commands, over to 100 machines, we can do that.
17:46And all those commands will get executed on those machines.
17:48And we'll get the results sent back
17:50to where we're running power, so on the client machine, really,
17:53really awesome stuff.
17:53We'll get into automation.
17:55We've got background jobs, which are
17:56way to run long running tasks in the background,
17:58as well as scheduled jobs for automation.
18:00We'll get into scripting.
18:01We've got a bunch of Nuggets on scripting
18:03to get familiar with how to write scripts.
18:04And at the end here, we're going to look at Desired State
18:06Configuration, which is that new feature in PowerShell 4
18:08that is just absolutely incredible.
18:11Jeffrey Snover called this the "make it so feature."
18:13Essentially, this stops configuration drift.
18:16Configuration drift is one of those things
18:18that happens over time.
18:19People fight fires, they change settings,
18:21and they don't put them back.
18:22And eventually you have a system that
18:24is completely different from the state
18:26that you wish it to be in.
18:28So Desired State Configuation allows
18:30us to declaratively define what a machine should
18:33look like as far as configuration, settings,
18:35features, all that stuff.
18:36And then if those ever change, Desired State Configuration,
18:39after a set amount of time, will put it back to normal.
18:42Really powerful stuff, and it goes way beyond that,
18:44and that's what we'll dig into in those Nuggets.
18:47And we'll also, at the end here, throw some challenges your way,
18:49and along the way, we'll do some really neat real-world stuff.
18:52So here's the Virtual Nugget Lab.
18:53This is the network that we're going to be working with.
18:55And you can have access to this network as well.
18:57If you're a premium subscriber, you
18:58can fire it right up from the course page
19:00right through your browser and have access
19:02to this five machine network.
19:03And we're going to be doing a lot in here.
19:05So we're going to start small just
19:06working with one or two machines,
19:07and then by the end of this course,
19:09we'll be sending commands in automating things
19:12across the entire network.
19:13We're going to do some pretty cool things.
19:15So we've got DCNUGGET.
19:16This is our domain controller.
19:17FSNUGGETs are file server.
19:19APPNUGGET is going to be kind of our everything else.
19:21We'll eventually get IS on here.
19:23We'll write and automate some tasks
19:25to run across the whole network, gather some information,
19:28create a web page, put it on IS, and we'll
19:29use Desired State Configuration to make sure
19:31that all those features stay in place.
19:33Really cool stuff.
19:33We're going to, like I said, go from zero to hero
19:36here by the time we're done with this course.
19:38And then we've got some client machines here, a Windows 7
19:40client and a Windows 8 client.
19:42Now let me introduce you to the network
19:43we're going to be working in.
19:44There it is.
19:45This is actually our domain controller here.
19:46In fact, let me bring this over.
19:48There we go, all right, cool.
19:49So here we go.
19:50Here's DCNUGGET, here's our File Server
19:51Nugget, Windows Server 2012 R2 on those.
19:53Here's our other server.
19:54So we have three servers here all with Windows Server 2012
19:56R2.
19:57And we've got two client machines.
19:58Here's our Windows 7 client and here's our Windows 8 client.
20:01So right now, we've got all the default installations
20:04of PowerShell, which means we're fine on the server
20:06side and even the 8.1 side.
20:07In fact, we can see this.
20:08Let's just fire up PowerShell here and let's
20:11just run a quick PS version table.
20:13Don't worry about this if none of this make sense,
20:15we're going to get into it.
20:16So there we go.
20:17In fact, in our installation Nugget,
20:18it will get you very familiar with PS version table.
20:20We'll do some pretty cool things with it.
20:22So PowerShell version 4 right here, so we're good there.
20:25But if we head over to our Windows 7 client,
20:28and we try that out, you can see that we're
20:30running PowerShell Version 2.
20:31So this is something, an older Legacy
20:33machine, something you'll probably
20:35come across in the real world.
20:36If you have a lot of older clients out there,
20:37you'll need to get them up to PowerShell 4
20:39if you want to take advantage of some of these cool features.
20:40So we'll look at how to do that in our Installation Nugget.
20:43In this CBT Nugget, I welcomed you to Power Shell 4
20:46Foundtions, and hopefully made the case
20:48for why we all need PowerShell skills here going forward.
20:51It's going to make us more efficient.
20:53We're going to be able to do things that we ever
20:54thought possible before we're going
20:56to be able to easily manage, configure, and automate
20:59our environments.
21:00We also defined what PowerShell is.
21:02It's an object-oriented command-line shell
21:04and scripting language based on the dot NET framework.
21:07And then we went over what we're going
21:08to cover in this course, which is all the foundations
21:11and beyond of PowerShell 4.
21:12And at the end here, we got familiar
21:14with the virtual environment that we're
21:15going to be working with for all of our labs and demonstrations.
21:18I'm extremely excited that you're
21:19joining me for this course.
21:20So again, thank you.
21:21We're going to have a lot of fun.
21:22We're going to learn a lot, and you're
21:23going to be extremely effective with PowerShell
21:25by the time we're done with this course.
21:27I hope that this has been informative for you,
21:29and I'd like to thank you for viewing.
Installing PowerShell 4.0
0:00Installing PowerShell 4.
0:02So before we can start utilizing all these awesome features
0:05in PowerShell 4, we need to get it installed
0:07across the enterprise.
0:08And that can be a challenge, unless you're
0:10one of those lucky folks whose infrastructure's always
0:13on the latest version of Windows.
0:14So your servers are all up to date with Windows Server 2012
0:17R2, your clients are all up to date with Windows 8.1.
0:19Well, number one, you're golden, because you already
0:22have PowerShell 4 installed.
0:23Number two, we envy you, because, generally, that's
0:26not going to be the case.
0:27Generally, we're going to have clients all over the place, XP,
0:30Vista, 7.
0:30We're going to have servers all over the place, 2003, 2008,
0:332008 R2, and that's going to equate to PowerShell versions
0:37all over the place.
0:38So in this Nugget we're going to talk about all things
0:40PowerShell 4 installation.
0:41We're going to cover its requirements,
0:43where you can find it, its availability.
0:44Can we even install PowerShell 4 in older versions of Windows?
0:47And we'll even talk about a couple
0:48of features that, in newer versions of Windows,
0:51are turned on rather than off.
0:52Which just goes to show that Microsoft
0:54is very serious about making PowerShell more accessible
0:57right out of the box.
0:58And finally, towards the end of this Nugget,
1:00we'll get into the Virtual Nugget Lab,
1:01and I'll give you a demonstration.
1:02We'll look at some neat commands that we
1:03can use to, again, interrogate our network
1:05to see what versions of PowerShell are out there.
1:07And then we've got a legacy Windows 7.1 client
1:10inside of our domain, that's running PowerShell 2,
1:12so we'll look at the process for getting them up
1:14to PowerShell 4.
1:15So without further ado, let's begin.
1:17All right, everything you need to know about installing
1:19PowerShell 4, here it is.
1:21So for down level installs, and I'm talking anything prior
1:24to 8.1 on the client side, and anything prior to Windows
1:26Server 2012 R2 on the server side,
1:28you'll need to first install the .NET Framework 4.5.
1:32Then we can install WMF, the Windows Management Framework
1:364.0, which is where we find PowerShell
1:38and all kinds of supporting technologies around it.
1:41Now here's the thing, WMF, when you try to install it,
1:44doesn't actually check for .NET 4.5.
1:46This is a known issue.
1:47So if you install WMF before .NET 4.5, it'll succeed,
1:51but it won't actually do anything.
1:53So if you run into troubles, you can then install .NET Framework
1:564.5, and then just run through the installation of WMF 4.0
1:59again, and it'll succeed.
2:00Now here are the components of WMF.
2:02PowerShell 4, both the shell and the ISE,
2:04a couple of tools we'll be getting very familiar with.
2:06PowerShell Web Services, this is what
2:08allows administrators to expose commandlets
2:10via a restful endpoint.
2:11So developers can tap into these APIs
2:13and execute PowerShell commandlets remotely.
2:15It also comes packaged with WRM, Windows Remote Management.
2:18Now this is Microsoft's implementation
2:20of the WS-MAN protocol, which uses SOAP over HTTP and HTTPS
2:25for communication.
2:26And it's much more firewall friendly than, say,
2:30the computer name switch, which we're also
2:31going to talk about, how we can pass in a list of computers
2:34for a commandlet.
2:35That uses DCOM and RPC, which is not firewall friendly.
2:39So again, we're going to get heavily into this
2:41when we talk about remoting.
2:42We'll uncover the details here of the WinRM
2:45service and WS-MAN, and talk about how
2:47remoting works under the hood.
2:48And it's also going to be one your post-installation tasks
2:50if you want remoting to work across your enterprise,
2:53you're going to need to configure and enable
2:54Windows Remote Management, which is pretty easy to do here,
2:57through PowerShell.
2:58So again, more on that down the road,
2:59when we get into remoting.
3:00WMF is also going to upgrade WMI so it's
3:03compatible with PowerShell version 4.
3:05And then we get that sweet new feature here,
3:08called Desired State Configuration,
3:09it's going to install the components,
3:11so we can utilize that.
3:12And, again, we're going to take a big look at DSC
3:15down the road, as well.
3:16Now let's look at PowerShell 4's availability.
3:18Is it supported, and by what operating systems?
3:20Now, again, Windows Server 2012 R2 and Windows 8.1, it's
3:23installed by default, there's nothing you need to do.
3:24It's already got .NET 4.5, it's already got PowerShell 4,
3:27so you're ready to go.
3:28Windows Server 2012, you will need to install .NET 4.5,
3:32and then, again, you can install WMF 4.0.
3:35Windows 8, it is unsupported.
3:37So the only way, if you're on Windows 8, to get PowerShell 4,
3:39is to upgrade to Windows 8.1, and then you'll be ready to go.
3:43And again, that is a free upgrade.
3:44Windows Server 2008 R2, you will need to install SP1 and .NET
3:504.5, and then you can install WMF 4.0.
3:52And the same goes for Windows 7, install SP1, then .NET 4.5,
3:57then get WMF 4.0.
3:59For everything else, you guessed it,
4:01PowerShell 4 is unsupported.
4:03Now here's another view, this just kind of
4:05gives us the bigger picture here.
4:06And this is a great chart for reference,
4:08if you ever have any questions around PowerShell 4's
4:10availability.
4:11This will give us our default PowerShell version
4:13across all the relevant versions of Windows,
4:15and the supported versions of PowerShell
4:18across all these versions of Windows.
4:20It's also going to show us our default settings, for execution
4:23policy, and remoting.
4:25These are two very important areas,
4:26because they're going to determine whether or not
4:28you can execute scripts on the machine,
4:30and if you can execute PowerShell commands remotely
4:34across one or more machines.
4:35Again, these are your two big post-installation tasks
4:38right here, setting up an execution policy for scripts,
4:41and configuring enabling remoting.
4:43Both of these we'll look at down the road.
4:44We've got a couple Nuggets for scripting.
4:46The first thing we'll do is work with execution policy
4:49and get an understanding of what all these options are.
4:51And then first thing we'll do we get into remoting
4:53is learn how to configure and enable them.
4:55But notice one thing here, Windows Server 2012 R2, yeah,
4:58remote sign-in enabled.
4:59These are on by default, which is, again, just awesome,
5:02because it makes it more accessible and easier
5:04to work with.
5:05And also notice with Windows Server
5:062012, remoting was enabled.
5:09So that's a big deal.
5:10But also notice, Windows 8.1, remoting is disabled,
5:13Windows 7, remoting is disabled.
5:14So we've got two client machines in our network
5:17right now with remoting disabled.
5:18And that's going to come in the play
5:20here shortly when we get in and do a demonstration.
5:22So how do we figure out what version of PowerShell
5:24we currently have running on our system?
5:26Well, there's a bunch of ways to do it, as is the norm here,
5:29with PowerShell.
5:30But one common way to do it is to run
5:32what's known as an automatic variable here.
5:33Think of this like an environment
5:35variable for PowerShell.
5:36PS version table.
5:37We execute that, it's going to give us
5:39back a bunch of information, but the first item
5:41that it's going to return here is our PowerShell version.
5:44You can also run dollar sign host,
5:46which will give you a bunch of host information,
5:47including the version of PowerShell.
5:49But what we want to do now is head into the Virtual Nugget
5:51Lab, and let's take PS version table
5:54and turn it into a command that we can execute
5:56across the entire network, all the machines in our domain,
5:59using remoting.
6:00This is going to be really neat.
6:01And then we'll take a look at the installation process.
6:03And we'll even talk a little bit here
6:04about how to install it across the enterprise.
6:06All right, so we're in the Virtual Nugget Lab,
6:08we are on CL8 Nugget.
6:10This is our client machine for Windows 8.1.
6:12And what I want to do first is just show you
6:15where you can find all the files here, for this course.
6:18So on FS Nugget, our file server,
6:20I have a share there called PSV4.
6:22What we're going to do is build this out as we go.
6:24So right now we're in 0.2 installation.
6:26Every command inside of here, we will put inside
6:29of commands.ps1.
6:30Unless it's a script that does a specific thing,
6:32I'll store them all inside of this.
6:33So every command we do inside of this course
6:36will be accessible here inside of these files.
6:39So there will be a folder per Nugget,
6:41and then we'll even have kind of support folder
6:43here with all the installation files that you'll need.
6:45And if you don't have access to the Virtual Nugget Lab,
6:47don't worry, upon course completion I'll wrap this up
6:49and we'll make it available via our Nugget Lab files
6:52on the course page.
6:53All right, so let's fire up PowerShell here.
6:55You always want to run PowerShell as an administrator,
6:57otherwise it won't function as you expect it to.
6:59And let's go ahead and check out the version here
7:01on this machine.
7:01So again, we're on Windows 8.1 client right now.
7:04And you can see our PowerShell version, 4.0,
7:06so we're good to go on this machine.
7:07Now what if we wanted to check out all the other machines
7:09in our network?
7:10Does that mean we have to RDP into those machines
7:12and do the same thing?
7:13No, and that's what I want to show you here.
7:15But first, before I show you that,
7:16let's do a PS version table on our Windows 7 client here.
7:19We can see that we are on PowerShell version 2.0.
7:21So this is a machine that we're going to need
7:23to upgrade to get it to 4.0.
7:24But let's head back to our 8 machine here, and watch this.
7:32Now you're probably thinking to yourself,
7:34what the heck is that?
7:35We haven't even talked about commandlets or commands yet.
7:37And don't worry.
7:38We're going to get to that in Getting Started,
7:39we'll talk all about commandlets, their structure,
7:41get familiar with their syntax and such.
7:42I just wanted to show you something cool,
7:44to give you the idea of how powerful it is,
7:46and how we can do so much with so little.
7:48So here, we're using remoting via the invoke command
7:51commandlet.
7:52We're passing it a list of computer names
7:53that we want to send this command to,
7:55and then we're using the script block parameter
7:57and passing in the actual command
7:59that we want to execute.
8:00So it's going to send this command to all these machines,
8:03get all that data, bring it back, and give it
8:05to us right here on our local machine, which is really cool.
8:08Now the one thing I want to point out,
8:09though, is remember, Windows 7 and Windows 8,
8:12remoting is disabled by default. So this could bring back
8:15some errors, and it will bring back
8:16some errors, because we didn't configure remoting yet.
8:19But DCNUGGET, APPNUGGET, FSNUGGET,
8:21those are all 2012 R2, so we should get all their versions
8:24sent back to us.
8:25So I'm going to go ahead and hit Enter,
8:26and it's going to think about it for a second,
8:28send those commands over the wire,
8:29and they're going to come back.
8:30And look at that, CL8 Nugget failed with the following error
8:33message.
8:34And then it succeeded on these three,
8:36and it's still trying to hit CL7.
8:37We'll get that error message shortly.
8:38But how cool is that?
8:41That we could sit on one machine,
8:44send a command to all those machines,
8:46and get a response back from them.
8:47And there's our CL7.
8:48So CL7 Nugget and CL8 Nugget, because remoting
8:50is disabled by default, it didn't work on those.
8:53But it did work across all of our servers.
8:55Here's another really cool one.
9:01Can anybody guess what this is going to do?
9:03Notice we took that static list of computer names
9:05that we had up here out, and then we
9:06replaced it with another commandlet
9:08called Get ADComputer.
9:09Yeah, you guessed it.
9:10This is going to read all the computers in Active Directory.
9:13Pretty cool, right?
9:14And extremely powerful for something
9:16that we're doing in one line.
9:17And if I hit Enter, there you go.
9:19It's going to go ahead and read from Active Directory,
9:21and then we're going to get the same response here.
9:23So the three servers that are in Active Directory, great,
9:25but the two clients that are in Active
9:26Directory, because remoting isn't enabled,
9:28are going to come back with an error.
9:30All right, so we know that our three servers are good,
9:32they all PowerShell version 4.
9:34We know that our CL8 Nugget is good,
9:36because we ran a PS version table right
9:37on this machine here, we know that that's OK with 4.
9:40And we know that our CL7 Nugget, which is right here,
9:44is on PowerShell 2.
9:45So the first thing you want to do on your legacy operating
9:47systems is, make sure that you have the requirements.
9:49Since we're on Windows 7, those requirements are going to be
9:52.NET Framework 4.5, as well as Service Pack 1.
9:56Now, check this one out.
10:02Can you guess what this one's going to do?
10:04Yeah, it's going to query the operating system through WMI,
10:07to see the operating system version and the service pack
10:10version.
10:11Let's hit Enter.
10:11Look at that.
10:12So we're on Windows 7 Professional, Service Pack
10:15major version 1, so we're good to go there,
10:18we meet that requirement.
10:19Now we could also query the registry to find out if we have
10:21the .NET Framework 4.5 installed.
10:23In fact, let me show you this, only through the ISE.
10:25And we could fire up the ISE down here,
10:28we could run Windows PowerShell ISE, or we just type
10:30in ISE here in the command shell.
10:32And there it is.
10:33And what I'm going to do is just open up that command script
10:34I was telling you about here.
10:36So, all right, and we'll just hit up our file server here.
10:40There we go.
10:41There is the directory for this Nugget,
10:42and there is, commands.ps1.
10:43So let's open this up.
10:44Now, again, this is PowerShell 2's ISE.
10:46And don't worry, we're going to get a nice tour of all
10:48the tools, and we'll get very familiar with PowerShell 4's
10:51ISE, which is much nicer.
10:52But here are the commands that we were just running,
10:55there's your version check, here's your operating system
10:57and Service Pack check.
10:58And here, if you want to query the registry to see what
11:01version of .NET, you could do that.
11:03But we're just going to do a like on the end of this to see
11:05if we're running .NET 4.5.
11:07So if we execute our highlighted selection there,
11:10it's going to return false, meaning we do not have .NET 4.5
11:14installed.
11:14All right, now our next step is to get the .NET Framework 4.5
11:18installed.
11:18Here is the URL, I'll give you the short URLs for these
11:20as well, for the .NET Framework 4.5.
11:22This is for the offline installer.
11:24I also have the web installer inside of our installation
11:26directory here, but we'll talk about why you'd use one
11:29over the other here, shortly.
11:30And then here is WMF 4.0.
11:32I'm going to go ahead and run through installation here,
11:34so let me go ahead and just close out of this.
11:37Head into our directory, head into installs, and here's
11:39what we get.
11:40So here's the web installer.
11:42Here's the offline installer.
11:43These are both for .NET 4.5.
11:45And when you go to the WMF page, you'll
11:46have the option to download one of these.
11:48These are the 64 and 32-bit versions for client operating
11:51systems, and then there is the 64-bit version
11:53for server operating systems.
11:55So first things first, let's get .NET 4.5 up and running.
11:58I'm just going to use the web installer.
12:00And I'm not going to make you watch me run through all this,
12:02I'll run through it really quick here.
12:06And there we go, .NET 4.5 successfully installed.
12:09Now let's do the same thing for PowerShell here,
12:11and we are on Windows 7, 64 bits,
12:13so we're going to run this one right here.
12:15So let's go ahead and run this.
12:16WMF 4.0, we'll do the same thing here.
12:18I'm going to go ahead and choose Yes for the updates.
12:20And here it is.
12:21So, again, I'm not going to make you sit here
12:23and walk through this.
12:24So I'll fast forward through all this stuff,
12:26and when we're done, we should have WMF 4.0 installed,
12:28which will have PowerShell 4.
12:29We'll do a restart, and we'll be ready to rock.
12:34And there it is, WMF 4.0 installed.
12:36So all we need to do is restart, and we
12:38should be ready to go with PowerShell 4
12:39here, on our Windows 7 machine.
12:41And we're back from our restart.
12:42Let's see if everything worked out.
12:44Let's run PowerShell as an administrator here.
12:46And we'll run our handy dandy automatic variable
12:49called PS version table.
12:50And it should say version 4.
12:52And look at that, we're on version 4.
12:54If we fire up the ISE, this should also be on version 4.
12:57You can already tell the splash screen
12:58looks a little more modern.
13:01And you can see when it opens up,
13:02it should look a lot different as well.
13:04And there it is.
13:05So here we go, we've got the latest version of the ISE
13:07on here, as well.
13:08Excellent.
13:09So everything worked out, and I should also
13:10mention that PowerShell can run side by side
13:12with other versions.
13:13But now, by default, everything is
13:14going to run through version 4.
13:16Now the last thing I want to mention here
13:18is installing PowerShell 4 across the enterprise.
13:21Let's head back to our share here, on FS Nugget,
13:23and let me show you a few things.
13:25There we go.
13:26Now here's the scenario.
13:27Let's say you've got 100 Windows 7 machines out there.
13:30You want to bring them all up to PowerShell 4
13:32so you can manage them remotely.
13:33Are you going to go and log into every one and do it?
13:35Hopefully not.
13:36Here's what you'll do.
13:38First, you'll download your installers.
13:40Put them on a network share somewhere.
13:41And this is where you'll want the off-line installer for .NET
13:444.5, just in case you have machines out there that do not
13:46have internet access.
13:47So get the .NET Framework 4.5 offline installer on a network
13:52share.
13:52Then get your WMF 4.0 installers on a share
13:55as well, for whatever architectures and versions
13:57of Windows you want to support.
13:59Then, once you have that in place,
14:01it's just a matter of choosing your deployment method.
14:03There's a lot of ways to do it.
14:03You could use System Center Configuration Manager,
14:06or a nice cheap easy free way, assuming
14:09you've already paid for Windows to do this,
14:10is using group policy.
14:13In fact, I've got a batch script in here that will do just that.
14:16So the first thing you'll do is create
14:18a group, put all those machines inside of a group.
14:20Then create a GPO, and as a shutdown script,
14:22you'll specify a batch script like this.
14:24A very simple batch script.
14:26The first thing it's going to do is query the registry to see
14:28if we have .NET 4.5 installed.
14:30So you may have some machines that do,
14:31some machines that don't.
14:33If they don't, this will install it for them.
14:35Because it'll come back with an error level of one,
14:37and then it'll run down here and install .NET 4.5 from
14:41the offline installer that share in quiet mode with no restart.
14:44Because we're doing this in a shutdown script,
14:45no need to do any sort of restarting.
14:47Then we'll check for WMF 4.
14:50If that comes back false, then it will install WMF,
14:53and it'll check the processor architecture
14:55and install the right one for Windows 7.
14:56See, we're not incorporating any servers in here,
14:59because we're saying this for a Windows 7 scenario.
15:01But this will install the 32-bit one, if we're on x86.
15:04It'll install 64-bit if we're not.
15:06And that's it.
15:07That's a great way to do it.
15:08So PowerShell does not like to update itself yet.
15:11Hopefully we'll get better support that down the road,
15:13but for now we need to resort to archaic methods
15:16to pushing it across the enterprise in one fell swoop.
15:19But if you only need to install it across a couple of machines,
15:21very simple to do.
15:22Just remember, .NET Framework 4.5 first, WMF 4.0 second,
15:27and you're golden.
15:27So there you go, everything you need
15:29to know to get PowerShell 4 up and running
15:31in your environment.
15:32I hope that this has been informative for you,
15:34and I'd like to thank you for viewing.
Getting Started
0:00Getting started.
0:01In this Nugget we're going to begin getting familiar
0:03with the tools of the trade.
0:04So we'll look at the PowerShell console, as well as
0:06the PowerShell ISE, the Integrated Scripting
0:08Environment.
0:09We'll begin by clearly defining the purpose
0:11of each one of them, and then we'll
0:12jump in and get some hands-on experience.
0:14I'll show you how to configure them.
0:15Always the first thing we should do in these tools
0:17is configure and customize them to make them comfortable.
0:19Make them feel like home.
0:21And then from there we'll look at how to navigate around
0:23in these tools, and we'll even get familiar
0:25with executing commands.
0:27Let's begin.
0:27The first tool we'll be getting our hands on in here
0:29is the PowerShell console, pictured here.
0:32What I like to call the Blue Screen of Love.
0:34Because we already have a Blue Screen of Death,
0:36now we get a Blue Screen of Love.
0:38Which is kind of funny because the first thing I do whatever
0:39I get into PowerShell the first time
0:41is change the color scheme.
0:42I'll show you how you had to do that when
0:44we get into our demos.
0:45But this console is great because it's small.
0:48It loads quick, and it's really meant for quick work.
0:52Troubleshooting, diagnosing issues.
0:54You're going to eventually have a pocket
0:56full of go-to commandlets.
0:58And whenever something goes wrong,
0:59you're going to break out PowerShell, no matter
1:01where you are, and you're going to run those commandlets,
1:03get some information, diagnose the problem,
1:04and be on your way.
1:05Or maybe expand that to multiple commandlets all piped together.
1:10Stuff we'll get into.
1:11But this PowerShell console is great for just that.
1:14Quick work, troubleshooting, not for building
1:16big, complex scripts.
1:17And the reason is because it doesn't really
1:19give us a lot of assistance.
1:20This is not a good learning tool simply
1:24because it's a chore do anything.
1:26Copy and pasting, a chore.
1:27Navigating around, a chore.
1:29But we can make it a little better
1:31here with some key strokes.
1:32By learning how to become efficient here
1:35with the keyboard and the console,
1:36you'll become a wiz in no time.
1:38The other thing I want to mention
1:39is this may be your only option.
1:41Server Core, anyone?
1:42Yeah, there's no GUI in Server Core.
1:44So it's still going to be beneficial to learn
1:45how to get around the console, and really by having both
1:49of these tools in your pocket is the ideal way
1:51to go about PowerShell.
1:52The second tool you'll be getting familiar with here
1:54is the old ISE, the Integrated Scripting Environment.
1:56Now this is a great tool.
1:57You can use a lot more than what it's intended for.
2:00Its intended to be a tool for developing and debugging
2:03scripts, but you can also use it as a learning tool
2:05because it has so many cool features built in.
2:07Productivity features, things like IntelliSense,
2:09Tab Completion, Auto Complete.
2:11It's got everything in it.
2:12And by the way, Intellisense-- one
2:14the greatest features ever-- the fact that we get it in here
2:16is great because you can easily take out all the guesswork when
2:20you're doing things like finding commandlets, or finding
2:22parameters, or finding values for parameters,
2:25it helps out immensely.
2:26And of course, it's a modern tool.
2:28It's not the command line.
2:29So it feels like a real modern experience when
2:32you're working inside of it.
2:33So this will definitely be your preferred tool
2:35for doing anything that isn't quick.
2:38Essentially anything that you don't just
2:39need to get in and get done, you'll be using the ISE for.
2:42Now if you want to get very efficient in both
2:43of these tools, I'd advise getting familiar
2:45with the shortcuts.
2:46So here are the shortcuts for the console,
2:48here are the shortcuts for the ISE,
2:50and I'll be pointing these out as we go.
2:52With that, let's jump into the Virtual Nugget Lab
2:54and give familiar with these tools.
2:55We'll get them configured, show you how to navigate around,
2:58and we'll execute some commands.
2:59Here we are in the Virtual Nugget Lab.
3:01We are on our Windows 8 client machine.
3:03Now the first thing you need to do is launch PowerShell.
3:06How can you do that?
3:06Well, if you're lucky enough to have a shortcut in the Task
3:08Bar, that's all you need.
3:09You can right click on it even, and launch the PowerShell ISE
3:12from the regular console shortcut.
3:15Just keep in mind anytime you launch PowerShell, ISE,
3:17or console, run them as an Administrator or things won't
3:21work as you expect them to.
3:23Now if you don't have this down here-- in fact,
3:25let's just go ahead and unpin this-- what do you do?
3:28Well, just do a search for it.
3:30Here we go.
3:30And if you're on Client Operating System,
3:32chances are you'll have both 32 and 64-bit version.
3:34So choose the version appropriate for you.
3:36And then right click and pin it to the Task Bar.
3:39You can even pin both of them if you'd like to.
3:41So there we go.
3:41We've go them both pinned to the Task Bar
3:42and we're ready to rock.
3:43Let's launch PowerShell.
3:44Remember, give it a right click to run it as an administrator.
3:47And we're logged in as Domain Admin
3:49here, so we didn't actually have to do that,
3:50but you can verify other way by just checking if administrator
3:53is up there in the Title Bar.
3:55Now notice the font size, extremely small,
3:57we're going to want to fix that.
3:58Color scheme, that's all a matter of preference.
4:00But I'll show you how to change that.
4:02And then I never like where it puts the window.
4:05It always puts it at 0, 0, 0, left, 0, top.
4:08I like it kind of in the middle here.
4:09So it's nice and centered, and we can see the Desktop.
4:12But notice-- this is kind of neat.
4:14Once you do this kind of thing right here,
4:15change it around, move it around,
4:17now when we go into Options, it's
4:18actually going to pick up those settings and we can apply them.
4:20So to get into the settings for the shell,
4:23just click on the Control Menu, and go to Properties.
4:25Let's just highlight some of the important ones
4:26here on the Options Tab.
4:27Quick Edit Mode is important because that's
4:29going to make copying and pasting
4:30feel a lot less archaic.
4:32You know what I mean.
4:33Without this on, you're going to be stuck going through the Edit
4:35menus to mark and copy and paste,
4:37and it's a huge time sink.
4:38So make sure that's turned on, then you can highlight,
4:40right click to copy, right click to paste.
4:42Makes it very easy.
4:42Insert Mode, we want this turned on as well, because whenever
4:45we type, wherever our cursor is, it's
4:47going to insert those character rather than overwrite anything
4:49to the right of the cursor.
4:51So those are good.
4:51Let's add to font.
4:52Let's absolutely increase the font size.
4:5416, 18, 20, whatever is comfortable for you.
4:57We'll put ours at 16 here.
4:59On the Layout Tab, the buffer size,
5:01this is how many characters are stored in memory.
5:04For the width, it's on a line.
5:06So it'll go this way until it runs out of memory,
5:09and then it'll push on to the next line.
5:11Height is going up and down.
5:13How many lines it stores in memory.
5:14Now the really important thing here comes with window size.
5:17Width and height, that's obviously just the window
5:19size that we have here.
5:20But if your widths are off, especially if your screen
5:23buffer size is larger than your window size,
5:25then you're going to get a horizontal scroll bar.
5:27And that's going to make working in here very difficult.
5:29So just make sure that your widths line up.
5:30And then all the rest of the stuff
5:32is pretty straightforward.
5:33And notice this was 0, 0, but I moved it
5:35before I came in to here.
5:36So it put our left at 211, and our top at 113.
5:39So that's good.
5:39So our window will show up right here.
5:41And finally, the Colors Tab.
5:43Here's where you can again, set up your color preferences
5:46for our background texture.
5:47If we want to make another, let's just change
5:49this to how about a 60, 60, 60.
5:50This will give us a nice, gray background here.
5:53And then for the text, let's make some orange text here.
5:55Let's go 255, 200, and let's go 110?
6:00110.
6:01Looks good.
6:01There we go.
6:02So we're good.
6:03Let's hit OK.
6:04There it is.
6:05Now if you don't like how that turned out-- like,
6:07ours a little off the screen here--
6:08you can just go back in and change them.
6:10But watch this.
6:11I like how this is, it was just positioned
6:12a little funny there.
6:13So let's move it back.
6:14Now if we were to close out of this and watch it again,
6:17it remembers the settings.
6:18It doesn't remember that we moved it here,
6:19because we didn't go back in.
6:20So if we do this, go back into Properties,
6:23head over here to Layout.
6:24And just verify it looks good.
6:26Hit OK.
6:26Now if we close out of it and relaunch it, boom.
6:28We're good to go.
6:29Now all of those settings are stored in the shortcut.
6:31So if you want to give yourself a consistent experience
6:34across all of your PowerShell installs, what you can do
6:36is set up what's known as a Profile Script.
6:38And we're going to get into Profile Scripts down the road.
6:40We got a Tips and Tricks Nugget, which
6:41will go over all those random things that'll make
6:43your life easier in PowerShell.
6:44But what's really cool here is everything we just accessed
6:47in there is actually accessible through the automatic variable
6:49known as Host, which actually maps to the commandline Get
6:53Host.
6:53So this is great because this will
6:55allow us to programmatically do anything that you just
6:58saw on there, and then some.
6:59So we could do Host.UI.rawUI.
7:02Let's go to Window Title, for instance.
7:04Window Title-- I'm just going to use Tab Completion there
7:06to find Window Title equals super PowerShell ninja.
7:11Look at that.
7:12And we just changed the title.
7:14So what's great about this is now we can create a script.
7:16And we're going to get into scripting all that stuff,
7:18so we'll see how to do all this stuff.
7:19But we can create a script that contains all of our settings.
7:22Maybe when we create our own aliases, something else
7:24we'll get into, all kinds of things that we can do
7:26to pre-configure our environment.
7:28And then any time we launch it, it'll run that script.
7:30So again, profile scripts, down the road scripts,
7:34down the road, in general, we'll show you
7:36how you can do some neat things to make your life easier.
7:37And get a nice, consistent experience then
7:39across all of your PowerShell installs.
7:41Something you want to do, because if we
7:43were to close out of this-- ooh-- and then open it back up.
7:45Look at that.
7:45Our window title is gone.
7:46But all of our settings here in the local machine
7:48are fine because anything we did through here
7:51was stored inside of the shortcut.
7:52Let's do some PowerShelly stuff.
7:54We'll get some basics out of the way,
7:55and then we'll move into the ISE and we'll actually start
7:58doing stuff with Get Command.
8:00One of my favorite commandlets here in all of PowerShell.
8:02Now the first thing you're going to do, especially
8:04if you're a GUI person, when you get to this point right here,
8:07you're going to be like, uh now what?
8:09What's next?
8:10And that's where Get Command is going to come in handy.
8:12But for now, let's just go over some basics.
8:13Let's just type in a command here.
8:15Do something awesome.
8:17Hey, that's not a command.
8:18So this is what an error looks like.
8:20Get used to seeing the blood on the screen
8:22here, and trying to understand what it's telling you.
8:24But this is pretty much saying, do
8:26something awesome isn't anything that PowerShell can find.
8:28It's not a commandlet function script.
8:30It's nothing that I can do anything with.
8:31What about this one?
8:32Dir.
8:32Hey, we know that works.
8:34Dir.
8:35Everybody know what Dir is.
8:36Directory listing.
8:37So that got us a directory listing
8:39based on our current location here, which is our profile.
8:41Administrator dot in the Nugget Lab
8:43inside of the user's directory.
8:44Watch this.
8:44How about Dir with the recurse flag?
8:46What's that going to do?
8:47Or parameter?
8:48That's going to run through all the directories.
8:50Now here's the cool thing about PowerShell,
8:52Dir is actually what's known as an alias for something
8:55called Get Child Item, which is the same thing.
8:58If we run that, same thing as Dir.
9:00Here's the thing, a lot of these commands
9:01that we're used to are just aliases.
9:03They're just shortcuts on top of PowerShell.
9:06So a lot of things are just sitting on top
9:07of PowerShell commandlets.
9:08Here's the really neat thing-- and this
9:10is why the PowerShell team is so brilliant-- they made
9:13it comfortable for Windows users to pick up and do what they're
9:16used to doing, and they made it comfortable for Linux users.
9:18LS, right?
9:19That's a Linux command.
9:20Does the same thing.
9:21Those are both aliases on top of Get Child Item.
9:23And that's a command we'll look at down the road, because it
9:25is a very good one.
9:26Let's go over some of our characters here.
9:28Now the back to character is how we do multi-line entry.
9:32So if we hit Enter here, we're going
9:33to get the double command prompt there.
9:36This means it's waiting for more info.
9:37So we could do a recursor, we could Enter.
9:39We do add more parameters there.
9:40Keep hitting Enter.
9:41When you hit Enter twice or on a blank line,
9:45it's going to finish it and actually execute the command.
9:47We're going to get into all the other ones as well.
9:50Single quote, double quote, brackets
9:53are going to be important, parentheses
9:54are going to be important.
9:55All this stuff will be more important
9:57when we get into scripting.
9:58But for now, just know the back take there allows
10:00us to do multi-line entry.
10:02Let's clear our screen here.
10:03Let's do a little CLS.
10:05Or we could do a Clear, or we could
10:07do a Clear Host, which is the actual commandlet
10:09underneath both of those aliases.
10:11Now let's look at one of the greatest features
10:13here in the console, and that is Tab Completion.
10:15If I start typing something out--
10:16let's say I'm looking for a commandlet that will help me
10:18out with services here.
10:19In fact, let's just do a get SC.
10:20I can hit Tab and one, it'll fly through all
10:22the available options.
10:23But two, if I get one that's right up
10:25to where I'm looking for, for instance, Get Serve,
10:27I'll hit Tab, and it'll complete it for me.
10:29That's the one I wanted.
10:30So that will save you a ton of typing.
10:31And this works at all levels.
10:32This actually works at the parameter level.
10:34So I can type in D and hit Tab to iterate through
10:36all the potential parameters here
10:37that start with D. Let's see, I was looking for Display Name,
10:40which I just passed.
10:41Now I can hit Shift Tab to go backwards.
10:42There it is.
10:43Display Name.
10:44And first, before we do that, let's
10:45just execute Get Service here.
10:47Boom.
10:47There's Get Service.
10:48So it shows all the services on the system sent back to us here
10:51in the console.
10:52Now I can hit Up to recall my Command History.
10:55This is going to become a vital when
10:57you are building pipelines.
10:58Because you execute your commands, see what you got.
11:01And then you can start adding onto it.
11:02So let's do Display Name here, and I hit Tab.
11:04It'll complete it for me.
11:05Let's say we wanted to see all the services in here that
11:08start with WIN.
11:09We do WIN, you use the wild card character, hit Enter,
11:12and there they are.
11:13Now let's recall that commandlet.
11:14Say that we want it to sort this,
11:15because it's kind of all over the place.
11:17It's sorted right now by system name, or the name-- not
11:19the display name, but the actual name of the system
11:22name of the service.
11:23And then we've got status over the place.
11:25So if we wanted to do that, we could do a pipe.
11:27And we're going to get all into piping.
11:29Pipelines are a critical part of PowerShell.
11:32But we're going to pipe these results over
11:34to the Sort Object.
11:35And we're going to say, yep.
11:36We want to sort by status.
11:39Boom, there it is.
11:39Now we're sorted by status.
11:41Pretty cool.
11:42Another critical one here for getting started
11:44is Control-C, which cancels the execution of a command.
11:47That's important, because how many times
11:48have you executed a command and you're just sitting there
11:51staring at blank screen?
11:52This will help you out at ton here.
11:54And especially if we did something like this.
11:56Let's say that we did this.
11:58And we forgot to put our filter in there for Display Name,
12:01so we just do a Get Service.
12:03But we're going to do it across the network.
12:06We're going to run Get Service across all
12:08the computers in our network.
12:09Let's just do two here.
12:10Get Nugget FS Nugget.
12:11This will probably still come back pretty quickly,
12:13but if it didn't, we get a Control-C. Boom.
12:15It bombs out right there.
12:16See that?
12:16Before it even got to the end.
12:17And let's let it get to the end.
12:18There you go.
12:19There's the end.
12:19So Control-C is a life saver because it can get you
12:21control of the Console Back.
12:24So there's a quick tour of the console.
12:26I think those are the really important points
12:28for getting started.
12:29Customize it, make it feel comfortable,
12:31get familiar with Tab Completion,
12:33and also some of the critical ones there as far as history
12:36goes.
12:36And by the way you can always hit F7
12:37as well to view your history.
12:39All those keywords shortcuts I showed you in a previous slide,
12:41get familiar with all of those because they're
12:43a big, big, big help, and they'll save you a ton of time.
12:46Especially all the history ones, and then
12:48Control-C, obviously being a big one.
12:50And some of the navigation ones too.
12:51Like navigating around in here, you
12:53can go-- if you'll control down, it'll
12:54bounce back and forth between the words.
12:56See that?
12:56Those are super useful too when you have a big command you're
12:59trying to navigate around.
13:00A lot better than hitting left arrow a thousand times.
13:02So get some practice in.
13:03Just fire up PowerShell, type in a few commands.
13:06If you're don't not sure what commands to type in,
13:08we'll get a ton here at the end of this Nugget.
13:09Type those in, and just go through all of those keyboard
13:12shortcuts, just to start committing them
13:14to muscle memory.
13:14You'll thank yourself down the road
13:16because you'll be so much more efficient here in the console.
13:20Let's move on to the ISE.
13:21So again, the console is great here,
13:22especially for quick things for troubleshooting,
13:25when you just need to get something done.
13:27You're going to have a handful go to commandlets.
13:29And you're going to be able to write
13:30these long complex pipelines.
13:32The console is great for that.
13:33But the real power is in scripting.
13:35Especially when we're going to start
13:36automating lots of processes and integrating products
13:39together, and doing all that kind of stuff.
13:41You're going to want to work in the ISE.
13:43In fact, we're going to be spending
13:43most of our time in the ISE just because it's more modern,
13:46and there's a lot of great productivity features in it.
13:48So let's first launch it, right down here on the Task Bar.
13:51We'll launch this.
13:52Make sure you again, you run it as an administrator.
13:54And the first thing you want to do
13:55is customize the environment.
13:56You can do that in the Tools Menu here.
13:58Going into Options.
13:59So again, here's all your fonts here for the Script Pane
14:01and the Console Pane.
14:02We'll go over all these panes in here.
14:04But what you want to do first is just increase the font size.
14:06Let's again, put ours up to 12 so we
14:08don't have to strain when we're looking at this stuff.
14:11With that out of the way, let's go over all this.
14:13So this is your scripting pane.
14:15This is where we're going to be doing a lot of our work here.
14:16Like, Get Service.
14:17Here it is.
14:18Notice right off the bat, something amazing happened.
14:20It popped up with a list of all the valid values,
14:23based on what we typed in.
14:24This is IntelliSense.
14:26This is one of the greatest features that
14:28ever hit a development environment back
14:29in Visual Studio, and now we get it
14:31in PowerShells Integrated Scripting
14:32Environment, which is great.
14:34It's just going to save us a lot of time and guess work.
14:36And it'll save us on a lot of typing too.
14:38Because we can click these things,
14:39and it will type it up for us.
14:40You can still do Tab.
14:41It still supports Tab Completion and all that.
14:43But watch this.
14:44I hit a parameter-- a dash there for perimeter--
14:46it's going to pop up all the parameters in here,
14:48and even give us the data type that perimeter expects.
14:50We're going over parameter sets, parameters, data types,
14:53all different kinds of parameters
14:54here when we get into the Nugget following this one,
14:57Getting Help.
14:57We'll go over all that stuff and syntax.
15:00But this is awesome that it pops up
15:01with all the potential parameters.
15:03So here it is.
15:04Here's Display Name.
15:05And then we can start typing, and it's
15:06going to give us a valid values, in this case,
15:08of all the display names of the services.
15:10How cool is that?
15:11If we didn't want Display Name, we wanted the System Name,
15:14we can do Name, and look at that.
15:15Here's all the System Names.
15:16How cool.
15:17So let's do Display Name again.
15:18Just type display.
15:19I'll hit Tab there.
15:20And let's do WIN with our wild card,
15:23and now I'm going to run this.
15:24And what I'm going to do is highlight this.
15:26And I'm going to hit this button right here, Runs Selection.
15:29We'll talk about the differences of those in a minute.
15:31But this is your Development Pane.
15:32This is where you'll be writing code, and this is your console.
15:34Just like the same exact console that we were just working.
15:37In fact, you can even come down here
15:39and type in whatever you want.
15:40And you still get IntelliSense and Tab Completion.
15:42We can hit Enter, and there's all the services again,
15:44on the local machine.
15:45Now the other pane we have open by default
15:46here is the Command-AddOn Pane.
15:48And this is really nice.
15:49It's just a browser for all the commandlets on the system.
15:51And it even breaks it up by module.
15:53Now watch this.
15:53Let's say we wanted to find all the commandlets
15:54on the system that have to do with the computer.
15:56They have computer in the name.
15:57We just type in computer, and they're there.
15:59Let's say we only care about Active Directory commandlets.
16:02We could drop down and choose the Active Directory module.
16:04Again, we'll talk about modules as well in a future Nugget.
16:06Once you find what you're looking for, click on it,
16:08here's all the parameters.
16:10You Can hold your mouse over these fields,
16:11get a tool tip of the type, and whether it's
16:13a mandatory or optional parameter.
16:14And then you can fill this out, you'll get an insert
16:17and it will actually write the code for you.
16:19Pretty cool.
16:20But what I like to do is close out of this
16:21because it takes up valuable screen real estate.
16:23And you can always get it back here with the last button
16:26on the Toolbar if you need it.
16:27Now the other button here next to it
16:29is called Show Command Window, and this is great
16:32if you like to use the GUI for executing commands.
16:35So you can highlight a command here, Get Service,
16:37and we can hit Show Command Window.
16:38And here it is.
16:39So here's all the parameter sets.
16:40We'll cover those in a future Nugget.
16:43And here's all the parameters then for each parameter sets.
16:45Here's Computer Name, we use that with Get Service.
16:48And here's the Name.
16:49Here's Display Name.
16:50So this is again, the system name down here.
16:51Here's the parameter set for Display Name.
16:53You can put in Computer Name to all these.
16:55But this is great for learning.
16:56Obviously, we're trying to get away from GUIs with all this.
16:58But this is absolutely great for learning
17:01parameter sets and what parameters are expected
17:04for each parameter set.
17:05And again, the types.
17:06And you can just enter the values in here.
17:08And you can get a copy, it'll write the whole thing out
17:11for you, or you can hit Run as well.
17:12So fantastic.
17:14We'll definitely get back into Show Command in the future,
17:16just because it's such a helpful learning tool.
17:18Now let's go over some these other buttons.
17:20See this here?
17:21These are how we can control our real estate here.
17:25The one that it's on by default here is stacked.
17:27So again, Development Pane up here.
17:29Console Pane down here.
17:30We can put them side by side, if you prefer that.
17:32But what I really like to do is this right here.
17:34That way we get the full real estate.
17:36We can focus on just our script and writing our commands
17:40in here.
17:40And then your best friend when you're in this view
17:42is going to be Control-R.
17:43See that?
17:43You can just flip back and forth between Control-R all day long.
17:46And any time you execute anything anyway,
17:48it's going to flip over to that.
17:48Then you can hit Control-R to get back.
17:50Retype.
17:50So this is good because it gives you a lot more real estate
17:54to work with.
17:55A couple other buttons up here.
17:56This will launch PowerShell dot exe.
17:58Now notice it didn't pick up our preferences,
18:00because this launched literally PowerShell dot exe, not
18:03the shortcut where our settings are stored down here.
18:06So that's that.
18:07This is for remoting.
18:08This is going to be super useful because you pop this open,
18:11specify a computer name, and it's
18:12just like you're sitting on that computer.
18:14So you can have lots of tabs with all your computers open,
18:16and you can fire off commands individually, or just
18:18use the power of remoting send one command to all of them.
18:21So I can't wait to get into remoting.
18:22As you can tell, I love it because it's
18:23one of most powerful features here in PowerShell.
18:25These next three are all for executing scripts.
18:28So the Run Button, which is F5, will execute the entire script.
18:32F8 is the Run Selection, which is what I was doing here.
18:35So if you have a lot of commands in here,
18:36you can just highlight a command, hit F8,
18:38and it will only run that command, not the entire script.
18:40Then you have all of your standard productivity things.
18:42Redo, undo, your squeegee here, which
18:44will clear the command line, same
18:46is executing CLS or Clear Host.
18:48Cut, copy, paste, the modern day way, much easier to do in here.
18:53And then all your standard ones.
18:55So there you go.
18:56Now let's move on here and get familiar with Get Command,
18:59because this is the first thing you're
19:00going to want to do when you get into PowerShell
19:01is play a little bit.
19:02And this is the best command for learning
19:05how to learn in PowerShell.
19:06So let's get some space here, and let's just start typing.
19:08Get c o m.
19:10It knows what we're looking for.
19:12So we can Tab Complete that, and let's just run that by itself.
19:15First I'll highlight that, I'll hit F8, and there we go.
19:18A list of all the commands and functions here in PowerShell.
19:22That does not bring back any legacy Windows commands.
19:26Anything non PowerShell.
19:27To do that, we can just pass in a wild card.
19:30And what this'll do is the same thing,
19:31except it's going to go out and it's going to get,
19:34not only PowerShell stuff, but anything
19:36that's in the path environment variable too, which by the way,
19:40is anything inside of here.
19:41We can do environment colon path.
19:44Boom.
19:45There it is.
19:45So anything in those paths, it looked into
19:48and it's going to pull out.
19:49And by the way, PowerShell, any of those legacy utilities,
19:51anything that isn't a command letter,
19:53and it isn't in PowerShell as a function or an alias,
19:55all things we'll cover, is known as an application.
19:57And that's why you see all these here
20:00are tagged as applications.
20:01Look at them all.
20:02Tons of them.
20:03But we can use Get Command to find anything.
20:05We can use it to find again, PowerShell specific things, we
20:07can use it to look for utilities, anything.
20:10In fact, say we did want to just look for commandlets.
20:12Well we've got a parameter for that.
20:15It's called Command Type.
20:16Here it is.
20:16It's base, and look at that.
20:18We can find anything here.
20:19We can find an alias, commandlets.
20:21So if you want to see all the aliases here in the system,
20:24we'll highlight it, hit F8.
20:25Look at that.
20:25There's all the aliases in here.
20:27Let's see if we can find Dir up here.
20:29And I see it.
20:29There it is.
20:30Dir.
20:30[INAUDIBLE] forget child item.
20:32Pretty cool.
20:33Delete for remove item.
20:34So that's a great way to do it.
20:36And then we could also say, we just
20:38want to see everything that's a commandlet.
20:39We can type in Commandlet here.
20:41C m d l e t.
20:43Hit F8, and here's all the commandlets in the system.
20:47Now let's say that we were looking for something specific.
20:50Like say, a service.
20:52Any commandlet that has to do with service.
20:54So let's do this.
20:54Let's type in Service with some wild card surrounding it.
20:56Highlight it, hit F8.
20:57And look at this.
20:58Every commandlet that has service in the name.
21:01Now notice something interesting there.
21:02We didn't actually type this right here.
21:04We didn't type in Name.
21:05Although this would give us the exact same result.
21:08That's because this is known as a positional parameter.
21:11Meaning it's a common parameter, as long as we
21:13put the value where it shows up in that parameter set,
21:15we don't have to specify the name.
21:17So it can save you on some typing there.
21:19Let's take this to another level.
21:20Let's say that we've got a lot of service stuff down here,
21:23but we really only care about services
21:25within Active Directory, because that's our ultimate goal here.
21:27We can type in module as a parameter, and type
21:30in Active Directory.
21:32Highlight it, hit F8, and look at that.
21:33Now we have everything that has to do
21:35with service that's a commandlet inside of Active Directory.
21:38Now let's do another one.
21:39Now commandlets as you see here, have a verb now naming
21:43convention, which is just awesome for so many reasons.
21:46Number one, it makes it predictable.
21:47Makes it easy to find things.
21:49But it also makes it easy to do a search.
21:51A Google or Bing search, because there's nothing else out there.
21:54If you search for specific command on Google or Bing,
21:56you're going to get that help just for that command.
21:58So a lot of brilliant design decisions,
22:00as you're going to see as we go through this course
22:02with PowerShell.
22:02And just makes PowerShell a pleasure to work with.
22:05But watch this.
22:05Let's do Get Command and say we want to find everything
22:08with the verb get.
22:10Highlight it, hit F8, and look at that.
22:11There's everything with get in it.
22:13We could also do everything then with a noun of let's say
22:16service.
22:17Hit F8, and there it is.
22:19We've got one Get Service.
22:20That's the one we were looking for,
22:22and that's the one we were using up top there.
22:23Let's say we wanted to find all commandlets that have
22:26the computer name parameter.
22:28We can say parameter, computer name.
22:31Highlight, hit F8, and look at that.
22:33Here's everything that supports the computer name parameter.
22:35So you can see this is a very versatile a little
22:37search engine inside of PowerShell.
22:39Get Command.
22:40It's your friend.
22:41And remember, one of the things you
22:43can do when you're first learning this is just
22:45highlight it, hit Show Command.
22:47And now we can see all the parameters.
22:49These are both the parameter sets here,
22:50one for searching for commandlets, one
22:51for searching for everything.
22:53Here's all the parameters that we can use.
22:55Pretty cool.
22:56So we used up parameter name right there.
22:58You can even go to parameter type.
23:00Earlier we used a module.
23:01We used noun, we used verb.
23:02So we used a good amount of all the parameters
23:05here inside of the commandlets set parameter set.
23:09So that's a good way to get you started here.
23:11Just jump in, start playing with Get Command.
23:13You can do it either here in the console, or do it in the ISE.
23:17But do it in the ISE because you'll just get a lot of help
23:20with IntelliSense, and it makes it just a lot easier
23:23to work with and learn.
23:24In this CBT Nugget, we showed you
23:25how to Get Started with PowerShell, where we covered
23:27the tools that we're going to be spending all of our time
23:30in here, the console, and the ISE.
23:31We saw how to configure them, navigate around, and even
23:34execute some commands.
23:35I hope this has been informative for you,
23:37and I'd like to thank you for viewing.
Getting Help
0:00Getting help-- this is another one
0:02of those incredible features in PowerShell.
0:03The help system is great from so many perspectives--
0:06from installing it and keeping it updated to using it.
0:10It's comprehensive.
0:11It's simple.
0:11It's flexible.
0:12And if you're new to PowerShell, this Nugget
0:15is for you because this is how you're
0:16going to teach yourself how to learn everything
0:18there is to know in PowerShell.
0:20So in this Nugget, we're going to go over
0:21all of the things you need to know about the help system,
0:24and it's all wrapped in three commandlets-- Update-Help,
0:27Save-Help, and Get-Help.
0:28We'll even talk a little bit about syntax here,
0:30so we'll get familiar with parameter sets, different kind
0:32of parameters that commandlets support,
0:34and even talk a little bit about data types.
0:36And then we'll jump into the Virtual Nugget Lab,
0:37and we'll look at lots of demos to see the common ways to use
0:40help, and I'll even show you a couple of cool things
0:42you can do with the help system.
0:43Let's do it.
0:44The first commandlet we're going to look at here is Update-Help.
0:46Now, this is something that should
0:47be high in your post-installation checklist.
0:49In fact, the first thing you should do when you fire up
0:50PowerShell for the first time after installation
0:52is run Update-Help, and that's because PowerShell
0:55comes installed with minimal help information, just
0:57the bare bone information for all the topics,
1:00for all the modules here in PowerShell.
1:02And this is another brilliant design decision
1:04by the PowerShell team because by wrapping
1:05all of the operational side of help into a commandlet,
1:08they give us the power and flexibility
1:10to choose when and how we want to keep these help files
1:13updated.
1:13And it also obviously makes the download and installation
1:16much, much shorter.
1:17And because help is constantly changing, why wrap
1:19all that into the installation?
1:21So what Update-Help does is it will download all the latest
1:24information, all the latest help topics for all
1:27of the commandlets and the conceptual topics, which
1:30we'll talk about here shortly, in PowerShell.
1:32It's really cool how this works.
1:34This will actually do version checks for all the help topics
1:36and only download the differentials-- only
1:38the things that have changed since the last version
1:41for that help topic.
1:42Now, because Microsoft is hosting these help files,
1:45they do put some limitations in place,
1:47and that is, by default, Update-Help will only run once
1:51per 24-hour period on the machine
1:53that you run Update-Help on.
1:54So if you run it multiple times, any subsequent requests
1:56will be ignored.
1:57And there's also one-gigabyte limitation
1:59per uncompressed module.
2:01And, then of course, the other one
2:02is it does version checking.
2:04You can overwrite all three of those
2:05by using the force parameter in Update-Help.
2:07That will ignore version checking.
2:09It will ignore the one-gigabyte uncompressed content
2:11per module and the once-per-day limitation.
2:14Now, just to show you how easy this is,
2:16let me bring up a PowerShell command prompt.
2:18And I'm on my local production machine.
2:19This is not a machine that's in our virtual Nugget lab,
2:21so we'll do this again when we get into the virtual Nugget
2:22lab.
2:23But if we run a Update-Help, that's it.
2:25That's all you need to do.
2:26And I've already ran it on this machine-- today, in fact.
2:28So it's not actually downloading anything.
2:30It's doing version checking and moving on,
2:32and this will be very fast, see that?
2:33But if I were to run that with a force parameter,
2:35now it's going to go and actually download everything.
2:39So this would actually take a while to do
2:40because it's-- and these help topics are small for each
2:43commandlet, but it's still going to go out and download
2:44everything for every single module.
2:46So that's Update-Help.
2:48Now, the next we're going to look at here is Save-Help.
2:50So Save-Help is great because it allows
2:52us to save the help topics to the file system
2:55or to a file share somewhere.
2:57And this is going to be great for a couple of use cases,
2:58but the big one here is if we have client machines out there,
3:01say machine one and two here, that have restrictive internet
3:03access.
3:04Maybe they're behind a firewall or no internet access.
3:06We can still keep those machines' help topics updated.
3:09Actually, using the Save-Help commandlet is a breeze.
3:12We're going to call save-help.
3:13We can use the destination path parameter
3:15to specify exactly where these help files are going
3:17to get downloaded to, and then when we run Update-Help,
3:19well, they're going to use the source path parameter,
3:21pass in the share, and it will update that installation
3:25of PowerShell's help topics from the help in that share.
3:28Now, here's another great use case,
3:30and I would recommend setting up this process,
3:32because it's great for both connected and disconnected
3:35clients, and it centralizes all of your Update-Help operations.
3:38So let's say we've got a server out there
3:40that does have internet access.
3:41We could set up a PowerShell Java on that server
3:43to run Save-Help once a day, store it inside of a file share
3:47somewhere.
3:48Then, from our connected and disconnected clients,
3:50we could put an Update-Help pointing the, to that share
3:52inside of their profile script.
3:54So once a day, or any time when they
3:56launch PowerShell-- of course it will only happen once a day.
3:58But when they launch PowerShell, it'll
3:59go and get all the latest and greatest help,
4:02and that'll keep everything in sync
4:03across all the PowerShell clients in your network.
4:06We'll take a look at the script that does this from the server
4:08side, and we'll look at the profile script that does that
4:11from the client side once we get into, again,
4:13jobs and scripts later on in the course.
4:15On to the big one, Get-Help.
4:16So whether you're new or experienced with PowerShell,
4:18this is going to be your best friend,
4:19because this is how we're going to learn
4:21how to learn in PowerShell.
4:22Get-Help followed by the command will return the help topic
4:25for that command.
4:26We can also use help and man, which
4:29are aliases for Get-Help, but these pipe
4:31their other output, the help topic,
4:33to more, which will give us a paged view,
4:35rather than just spit out the entire topic
4:37and scroll us to the bottom.
4:38So when you're dealing with large help topics,
4:40it will help to use these, because we can go line
4:42by line through the topic
4:44Commandlet-?
4:45is the same as Get-Help for a specific commandlet,
4:47and it works the same as Get-Help.
4:49It just brings the whole topic, so it doesn't pipe it to more.
4:51You can also pipe Get-Help and commandlet to more,
4:54but help and man are great for that
4:56because they do it automatically.
4:57We also have about topics.
4:59These are great because it's essentially
5:00the documentation around all the core functionality
5:02and mechanics here in PowerShell.
5:04So I'll show you how you can find those and use them.
5:06And finally, you can use Get-Help as a search engine.
5:08So we just call Get-Help with a keyword,
5:10and it'll scan all of the full help topics
5:13and return us back things like commandlets and help files
5:16where that keyword shows up.
5:17Now, in order to become an effective learner PowerShell,
5:19we need to know how to interpret the help, and a lot of that's
5:22going to come down to understanding how
5:23to read syntax.
5:24The first thing you're going to do when you're learning
5:26a commandlet-- you want to know how to use it-- is you're
5:28going to look at the syntax to see what kind of parameters
5:31it supports.
5:31And understanding the different kinds of parameters
5:33and understanding perimeter sets will go a long way there.
5:36So let's start right there with parameter sets.
5:38Each commandlet has a number of ways that you can use it.
5:41Some of them have one or possibly more.
5:44Take Get-Help for instance; there's actually six or seven
5:46different parameter sets.
5:47I just included three in here.
5:49But a parameter set defines a specific way
5:51that we can use that commandlet.
5:53So here's how this works.
5:54Each parameter set has something unique about it.
5:56For instance, Examples has this example switch parameter.
5:58We'll talk about switch parameter shortly.
6:00But if we were to write a command that had the examples
6:01flag in it, for instance, get-help name of the help topic
6:04dash examples, we would be locked into this parameter set,
6:07and that's the functionality that we would get.
6:09If we were to write a very generic command,
6:11say get-help and followed by the name of the help topic, well,
6:14which one is PowerShell going to choose?
6:15These all have name in it.
6:16It would choose the first parameter set.
6:19And the All Users view for Get-Help,
6:21kind of think of it as the default parameter set.
6:23Because if we don't use anything specific in all
6:25the other parameter sets, then it's
6:27going to default here to the All Users view.
6:29It's also worth noting that you cannot mix and match these
6:31unique parameters across parameter sets
6:33because PowerShell won't know how to resolve the parameter
6:35set that you want to use.
6:36And just to give you an example of that,
6:37let's bring up PowerShell here.
6:39Let's say we wanted to get-help for say get-command.
6:42There's get-help for get-command, right?
6:44Let's say we wanted to see just the examples.
6:46I'm going to pipe this to more-- same as using
6:48Help rather than Get-Help.
6:49Now it's going to do it one line at a time, see that?
6:51So there's all the examples.
6:52I'm going to Control-C out of this.
6:53And let's say we wanted to add parameters in there.
6:56Now, we know this isn't going to work, right?
6:58Because we're mixing unique parameters
6:59across these parameter sets, so that should be parameter.
7:01And what parameter do we want to search for?
7:03Let's just put anything here.
7:04It doesn't matter because it's going to error out anyway
7:06and say the parameter set cannot be resolved using
7:08the parameters that we supplied.
7:10So those are parameter sets, and any time you launch Help,
7:13that's going to be the first area.
7:14Underneath Syntax, it's going to list all the parameter sets.
7:17In fact, let me just bring up PowerShell real quick
7:18once again.
7:19And let's do a help for Get-Help.
7:21Look at that.
7:21So since we did a Help, it's going
7:23to give us the paged approach starting from line one there.
7:25We can hit enter to go line by line through the help topic.
7:28But check this out; look at all these parameter
7:30sets in here-- lots of different ways to use Get-Help.
7:32And one thing I like about the online help-- notice back here
7:35I have these labeled with just one-word descriptions
7:39for these parameter sets.
7:40Well, let me Control-C out of this
7:41and add the online switch parameter to this command.
7:45It's going to launch a browser and take
7:46us right to the online documentation for Get-Help.
7:49And it's even going to launch us into the version
7:51that we launched it from.
7:52Look at that?
7:52It knew we were PowerShell Version 4,
7:54so it gave us the help topic for V4.
7:55If we were to launch this for Version 5,
7:57it would have taken us to this one.
7:58But here's what's cool about this.
7:59It actually adds the description for the parameter set.
8:02So we just used this one right here online.
8:04We used that unique parameter to this parameter set,
8:07so we were locked in to all these parameters,
8:09and that's what happened.
8:10Then it fired up the help topic here.
8:11We got that functionality.
8:13So this is great because it just allows you to quickly see
8:15what parameter set you'll need to use
8:17for whatever functionality you're looking for.
8:19Let's dig a little deeper into parameters.
8:21So parameters are how we pass data into a commandlet
8:24so it can perform its function.
8:25And when you're looking at syntax,
8:27you're going to see the name of the parameter, followed
8:28by the data type, the kind of data
8:30that you're going to pass into that parameter.
8:32And there's lots of data types out there-- strings, integers,
8:35dates, times, longs, Booleans, all these things
8:38that we'll see as we go throughout the course.
8:39But the most common one you're going to see by far here
8:41is the string parameter-- just passing in character data.
8:44But you may also see these open and closed brackets
8:46at the end of the data type.
8:48And that just tells us that this is accepts an array.
8:50It accepts multiple values.
8:51Take the computer name parameter, for instance,
8:53that we've used in previous Nuggets.
8:55We're going to specify the computer name parameter
8:57and specify computer name comma computer name comma computer
8:59name.
9:00That's specifying a list, a comma-separated list,
9:02that it's going to use to operate on all those machines.
9:05Now let's talk about the different kinds of parameters
9:07and all these brackets.
9:08Notice we have brackets over the place.
9:10We have brackets around just the parameter.
9:11Sometimes we have brackets around both the parameter
9:13and the data type.
9:14Sometimes we're missing brackets entirely.
9:16So let's start with positional parameters.
9:20You're going to see positional parameters are going
9:22to be the parameters that are going to be the most commonly
9:24used, and they're going to have brackets
9:25around just the name of the parameter--
9:27not the entire parameter, but just the name of the parameter,
9:30like name, for instance, with Get-Help.
9:32This means we don't have to actually supply
9:33the name of the parameter, and we've already seen this.
9:35We used this quite a bit here in PowerShell
9:37by just doing a get-help get-command.
9:40Notice that we didn't specify the name parameter.
9:44That is equivalent to this right here.
9:47So there it is.
9:48We can use either one of these.
9:49This, we're using it positionally.
9:51This, we're using it as a named parameter.
9:53So it's not a positional parameter,
9:55it's a named parameter.
9:56Every parameter is going to be one of those.
9:58And again, you're going to see name parameters for the most
10:00common parameters, and it's good because it saves you
10:02time, especially when you're just writing commands inside
10:05of the shell.
10:06As a best practice though, always
10:08specify names of parameters inside of your scripts,
10:11especially if you're working with other people.
10:13It just makes it much easier to work with, and it's very clear.
10:16Also worth mentioning, position the parameters are relative.
10:20Meaning, we can do this right here.
10:22Let's go back to our positional parameter,
10:25and let's just throw the example switch right here.
10:28First, notice we're using that first
10:29and then we're doing get-command.
10:31Yeah, it's still going to work because get-command-- or name,
10:34I should say-- is positional.
10:36So it was the first positional parameter that we used,
10:40and that's why it was OK to use.
10:42If we had other positional parameters inside of here,
10:45they would need to go in that order.
10:47So we would need to ensure, no matter where we put it,
10:49that the name parameter.
10:51If we didn't specify a name, would have to be first,
10:52and then so on and so forth.
10:54And I'll show you, when we get into deeper into the help
10:56topics here, how you can identify the position
10:58of a positional parameters.
11:00So that's positional parameters.
11:01It just simply means we do not specify the parameter name.
11:04So just a little great time saving
11:06feature there, especially either when you're fighting fires
11:09or when you're doing things like this, getting help.
11:10Who wants to type the dash name help topic
11:12every time they want to get help?
11:13Wouldn't it be better if we could just
11:14to get-help commandlet name?
11:15There you go.
11:16All right, so the next one we have here
11:18are mandatory parameters, and these
11:20are parameters that do not have brackets around anything.
11:25So, examples, for instance, is a required parameter inside
11:28of this parameter set.
11:29Parameter is a required parameter inside
11:30of this parameter set.
11:31So that's all mandatory parameters are,
11:33are ones that do not have any brackets around them.
11:36We also have optional parameters.
11:37Those are ones where you have bracket
11:39around both the name of the parameter and the data type.
11:42So full brackets around the whole thing
11:44just simply means it's optional.
11:46And we also have switch parameters,
11:47and those are parameters without a data type.
11:49That just simply means on or off.
11:50If you specify that parameter, it's on.
11:53By default, all switch parameters are off.
11:55Let's make sure we have this down.
11:57I'm going to quiz you, ready?
11:58Say it with me now.
11:59What is this right here?
12:01This is what?
12:02It is an optional positional parameter.
12:05It's positional because we have brackets
12:06around the name of the parameter,
12:07but it's also optional because we have brackets
12:09around the whole thing.
12:11Now, what about category?
12:13What's that one?
12:14That is a named parameter.
12:16That also accepts an array as a data type,
12:19so we can pass in multiple categories.
12:20But remember, if it's not positional, it is named.
12:23What about, let's do this one right here.
12:25What's that?
12:26That is a mandatory named parameter.
12:30What about this one right up here?
12:32Right, that's an optional switch parameter, cool.
12:34Now, there's one more parameter types
12:35that I want to mention here, and that's
12:36called partial parameters.
12:38This is another one of those time-saving features.
12:41So again, best practice, don't do this,
12:43especially if you're in scripts-- type everything out.
12:45But if you're just troubleshooting,
12:46you want to get things done quickly,
12:47or you know commandlets really well,
12:49this will save you some time.
12:50Partial parameters mean that we only
12:51need to type the parameter name up to the point
12:53that it's unique and PowerShell will know which one we mean.
12:56Just to give an example here, let's get back into PowerShell.
12:58If we were to do a get-service and we
13:00want to specify the computer name,
13:01usually we do this, right?
13:02We type the whole thing out and then pass
13:04in our list of computer names.
13:06We don't need to do that because there's only one parameter that
13:08starts with C. So we can do that,
13:10and we'll get the same exact effect.
13:12And here, just to show you how you
13:13can find that, let's do a help on get-service, and let's
13:17do a P. Look at that.
13:19I'm already using partial parameters.
13:20If we look down here, there's a-- oh, no, there's two.
13:23That wouldn't work.
13:24Look at that.
13:24There's path and parameters.
13:25We'd actually have to do par.
13:27There we go.
13:28Par is for parameter.
13:29And then let's just do a C*.
13:31We're wild card searching the parameters here
13:34for get-service, and it's only going to return one-- just
13:36computer name.
13:37That's it.
13:38So those are partial parameters.
13:39So that's interpreting Help.
13:40Understanding the syntax in all these different parameter
13:43types will help you immensely in teaching yourself
13:45how to learn PowerShell.
13:46And kind of my workflow, whenever
13:48I see a new commandlet, is I'll go to the Help topic for it.
13:50I'll look at all the different parameter sets,
13:52and then I'll start digging into the parameters themselves
13:55to understand what they all do and then look at some examples.
13:57It's a great workflow for learning how
13:59to use all these commandlets.
14:00With that, let's jump into the virtual Nugget lab.
14:02I want to show you how to use Update-Help, Save-Help,
14:03and the many cool things that we can do here with Get-Help.
14:06Welcome back to the virtual Nugget lab.
14:07Let's bring up the ISE here and let's open up our PowerShell
14:10file containing all the commands for this Nugget here, 04,
14:14getting help.
14:14So we'll open that up.
14:15Here's all the commands we're going to be working with,
14:16and we're going to start with updating help.
14:18Now, before we even run Update-Help,
14:19let's run Get-Help against Update-Help
14:21to see what we've got here.
14:22We'll run that selection, and you
14:23can see we just get the basic help topic here,
14:25a nice quick synopsis.
14:27We get our parameter sets listed here and a description.
14:30So we look at the differences between these parameter sets.
14:32Once has source path.
14:33That's what's unique to this one.
14:34So this is how we will run Update-Help
14:36against a copy of help that's been
14:38locally downloaded or downloaded on a file share somewhere.
14:41And then our second one here, the difference is literal path.
14:44So that's the difference.
14:44So we could get more information on those parameters
14:47by adding the detailed switch here,
14:49and we'll go over what all these mean here shortly.
14:51But detailed will give us the parameter description.
14:54So if we scroll up here, as well as examples,
14:56here are all the parameters.
14:57So now we can see here's our literal path.
15:00So this is different than the source path parameters
15:02because the value of literal path parameter
15:04is used exactly as it is typed.
15:06Then you can come down here and see the source path parameter
15:08as well.
15:09So that's Update-Help.
15:10Let's go ahead and run it here on this local machine.
15:12We'll highlight that.
15:13I'll hit F8, and that's going to go ahead and run Update-Help.
15:15So this is going to get our help,
15:17update it to all the latest content
15:19here on this local machine.
15:20So that's how we can Update-Help from the internet.
15:23What if we wanted to save help locally and then
15:25update it based on that path?
15:27Here's how we can do it.
15:28If we open up the directory here-- I
15:30made a directory inside of our Nugget lab files called Help,
15:32and right now it's empty.
15:34So if we run Save-Help and specify a destination
15:37path pointing to that directory on our file server,
15:40it's going to download help locally.
15:41So I'm going to hit F8 to run that.
15:43It's going to do pretty much the same thing we just saw.
15:45The difference being it's loading up this directory
15:47with all of the help topics.
15:49So now we could go ahead and run Update-Help and specify
15:52the source path parameter pointing to that directory,
15:55and it will Update-Help on that machine based
15:58on those help topics save there on the file share.
16:00Now, I mentioned the common thing to do
16:02is to automate this process, and there's
16:03a number of ways to do it.
16:04But the examples for the Update-Help help file
16:07actually show you how to do this.
16:09It's really cool.
16:10So let's just type in the example switch on Get-Help,
16:12and this will show us just the examples for Update-Help.
16:14And I'll show you a better way to navigate around here.
16:16It's painful doing this in the shell.
16:17Because if you click anywhere, you'll go back to the bottom,
16:19and it's just painful to find things.
16:21But example number four up here will actually
16:23show you how to Update-Help automatically using a job.
16:26So here's a job that will Update-Help for this everyday
16:30at 3:00 AM.
16:30And example number five shows you
16:32how to do it from a file share-- Update-Help
16:35on multiple computers from a file share.
16:36So it does a Save-Help, specifying
16:38the destination path-- exactly what we just did there.
16:40And then it uses remoting invoke command, computer name,
16:43passing in a servers.txt, which is just a text file that
16:47has a list for every computer that you want to update,
16:49and then the script block Update-Help at the source path,
16:51like we just did as well.
16:53So turning all that into a job on one machine
16:55will take care of everything you need.
16:56It will download the help file to your file share
16:59and then send the Update-Help commands to all the machines
17:01that you want to keep updated-- really nice
17:03simple way to do it.
17:04Let's move on to Get-Help.
17:06Remember I said you could use Get-Help as a search engine?
17:08Yes, it's very easy to do-- Get-Help
17:09followed by your keyword.
17:11Wild cards are supported here.
17:12If it doesn't find any specific commandlet to display help for,
17:16it'll display anything with that keyword in it,
17:18because this is going to scan all of the help topics
17:21for that keyword.
17:21And if I just run this selection here, check it out.
17:23So here's all the commandlets with variable
17:25in it, all the help files.
17:26This is a great way to find those conceptual about topics.
17:30So say we wanted to learn what automatic variables are all
17:32about.
17:33We could just do a help about_auto,
17:35and this also, by the way, supports tab completion.
17:38There we go.
17:38And I can hit Enter, and here it is--
17:40everything we need to know about automatic variables.
17:42And again, this is a huge topic, so scrolling
17:44will be quite painful.
17:45But if we get to the top here, you'll get a short description,
17:48and then the long description will
17:49list all of the automatic variables
17:51that PowerShell supports and what they do.
17:53So if we scroll down here, we can find host.
17:55We've used that one before, right?
17:56It contains an object that represents the current host
17:58application, and it allows us to control the properties
18:02of the host-- very, very cool.
18:04Now, here it is again, this time piped to more.
18:06The reason I wanted to show you this
18:08is because the more function is unsupported in the ISE.
18:10It'll always take you down to the bottom.
18:12But I'll show you how we can fix that when
18:13we get into functions.
18:14We'll write our own function that will paginate the output.
18:17What you can do in the meantime, though,
18:19and this is just great all around, is you show-window.
18:22Show-window is just fantastic because what it'll do
18:25is pop open the help topic in a separate window
18:28where we can find what we're looking for.
18:30So now we could easily find that host.
18:32Hit Next-- hey, there it is.
18:33There's host, and there's everything it does,
18:35and it'll highlight everything inside of here.
18:37So this is just awesome-- a great way, especially when
18:39you're learning, because this window will stay on top,
18:41so you can go over here and develop all day long,
18:43and you'll have the help topic right here
18:45to search through and find what you're looking for-- very,
18:47very, very handy feature there.
18:49Let's look at the many ways that we can use Get-Help.
18:51So let's say we want to learn all
18:52about the Get-Service commitment.
18:54We could run help get-service just by itself there,
18:56and this is going to give us very basic information-- just
18:58a synopsis, the syntax, a description, related links,
19:01commandlets, and remarks.
19:02If we wanted to get a little more detailed information,
19:05we could add the details switch, which
19:06is going to include parameters and examples-- just very
19:09basic parameter information.
19:10So let me scroll to the top here.
19:12We get, again, synopsis, syntax, description,
19:14but just basic information about each parameter, basically
19:16a description as well as the data type.
19:19And then if we scroll down, we get all the examples as well.
19:22So that's a great one.
19:23Let's see, what else do we got here?
19:24If we just want to see examples, as we saw,
19:26we can just run it with the example switch.
19:28And if we wanted full help, meaning detailed parameter
19:31descriptions, examples as well as notes
19:33and input/output types, we could use the full switch.
19:36And this is going to give us very, very detailed information
19:39here.
19:39And if I scroll down from parameters,
19:41you can see not only does it give us the description,
19:43but each parameter will have these five properties on it.
19:47This is a required parameter-- mandatory.
19:49Is it positional?
19:50If it's not positional, it'll be named.
19:51If it is positional, it'll have the number of position
19:54that it needs to show up relative to all
19:56of the other positional parameters.
19:58Default value-- see computer name here?
20:00If we don't type in anything, computer name
20:01will always default to the local machine.
20:03If it accepts pipeline input-- we'll
20:05talk about this more when we get into pipelining.
20:07And then if it accepts wild card characters--
20:09so great information here around each parameter.
20:11Not only does it tell us what the parameter does,
20:13but it gives us those properties around that parameter.
20:15If we scroll down here, let's see if we
20:17can find one that's positional.
20:18There it is.
20:19Look at that.
20:19Name, it's a positional parameter
20:21in the first position.
20:22Another really useful one here is the parameter parameter.
20:24This is a great way to discover what parameters are supported
20:28by a commandlet, and you can use wild card searches
20:31against this.
20:31So let's say let's see all the parameters that start with D
20:34for the get-service commandlet.
20:35I'll hit F8, and you can see we have two
20:37of them-- dependent services.
20:38This will only give the dependent services for whatever
20:41service you're looking for, and then display name,
20:43and this is we can specify the display name, rather than
20:45the system name of the service.
20:47Let's finish this up with a real world
20:49look at how to use Get-Help.
20:50So here's kind of the flow I go through when
20:51learning a new commandlet.
20:52The first thing I'll do is pop open
20:54that commandlet in show window.
20:55So now we have a nice Help window over here
20:57to the right, everything we know about that commandlet,
20:59and we still have our scripting pane over here on the left
21:01that we can use to play.
21:02And what I want you to do next is reverse
21:04engineer this command for me.
21:05Can you tell me what parameter set this command is
21:08using for Get-Service?
21:09We've got three over here in our help topic.
21:11Which one is this using?
21:12Well, the first parameter we're passing in
21:14as a positional parameters, so that's kind of a dead giveaway.
21:16Because if you look at these three,
21:18there's only one that supports positional parameters,
21:20and that is the first one.
21:21So we're using this, passing in a system name
21:23using wild card characters, and we're
21:25going to say, give us all the services that start with BI
21:27across both of these machines.
21:29So let's do that, and there they are.
21:31We've got two.
21:32But here's the thing, and we're going
21:33to get a little ahead of ourselves here
21:34because I want to do a little pipelining,
21:35but this is really neat stuff to get you moving forward
21:38and thinking about the future.
21:39Here's the thing, which machine are these running on?
21:42They're both stopped.
21:43What if one is running and one was stopped?
21:45How would we identify what machine is stopped
21:47and which one's running?
21:48Well, this is where pipelining can become very, very powerful.
21:52So we're going to pipeline that to
21:54the select-object commandlet.
21:56Again, we'll talk a lot more about this in the future.
21:58But I want to extract the machine name,
22:00and here we're pulling out what are known
22:01as properties of the object.
22:03This get-service is going to return us two objects.
22:06We're going to pass those objects over to select-object,
22:08and we're going to say, we want to pull out extra information
22:10that isn't in the default view.
22:12And that's going to be machine name status and, let's say,
22:14display name, just like so.
22:17And let's hit F8 to run that, and there it is.
22:19Now we have machine name.
22:20It's formatted a little funky, and here's status and display
22:22name.
22:23But we could fix that as well.
22:24Watch this.
22:25Let's go ahead and add to the end of this.
22:27Let's pipe all of that to the format-list commandlet.
22:31And now we get what we're looking for-- cool.
22:34So we're going to get all into objects and all
22:37into pipelining here in future Nuggets.
22:39Let's take that one step further.
22:41Let's say we want to do something
22:43with those two stopped services, like, how about start them?
22:46Well, thankfully, because of PowerShell's
22:48awesome verb-noun naming convention,
22:49we know if there's a get-service,
22:50there's probably a start-service.
22:51So let's bring up the Help inside of our Help window.
22:53Here we'll just do a Show Window Help on Start Service.
22:56So I'm gong to go ahead and execute that, and there it is.
22:58It loads up our Help here with Start service-- perfect.
23:00Now, there's three different ways to use this.
23:02One, is to pass in an input object.
23:05Hmm, that's interesting.
23:06Input object as a service controller also
23:10a positional parameter.
23:12So this is the data type here-- service controller,
23:14and we can pass in multiple services,
23:16and it just so happens that get-service returns service
23:19controller objects.
23:20So that's what we're doing right here.
23:22We're just running a get-service to get those two services, just
23:25like we did above, and we're passing those
23:27over to the start-service commandlet.
23:28So we're using this parameter set,
23:29and that's going to start those services for us.
23:31If we run this, and then we can head back and let's
23:34just run our previous get-service command here.
23:37Look at that.
23:38Now they're both running, as opposed to being
23:39stopped previously.
23:41What about the second way we could have done this here?
23:43Right here, by using display name,
23:45that's our second parameter set here is display name.
23:47It accepts an array of strings.
23:49Meaning it probably supports wild card characters.
23:52If we looked at the details for display name,
23:54we could scroll down here, find display,
23:56or we could just search for it.
23:57It probably would be a lot easier to do, right?
23:59Display name-- there we go.
24:00And we can see right-- here it is.
24:02Right here, one of the first ones--
24:04accepts wild card characters, true;
24:06position, named-- so everything we
24:08need to know about the parameter right there.
24:10And so we're just specifying the whole name,
24:12but this'll be the same thing.
24:12Also notice we're using a partial parameter for computer
24:15name because it is the only parameter that starts with C,
24:17but this would accomplish the same thing
24:19across those machines.
24:19It would start those based on their display name,
24:21rather than passing input objects.
24:23And the final one is pretty much how
24:24we've been using get-service, by just passing in the name,
24:27wild card character included, and that is, by the way,
24:30the default parameter set there.
24:31And if you were to do an online instead of show window,
24:34that would show us the exact same thing.
24:36It would show us these three parameter sets,
24:38only we'd get that nice name for each one.
24:40That's known as the default one when
24:42you work on the system name.
24:43Here's the input object parameter
24:44set that we were using, and here is the display name.
24:47So that's Help.
24:48Pretty cool, right?
24:49It can really help you learn how to use PowerShell.
24:52So my advice anytime you're learning anything
24:54in PowerShell, especially when you're learning commandlets,
24:56get into the Help, do a show window, and just start playing.
24:59Play with all the different kinds of parameter sets,
25:01get familiar with all the different kind of parameters,
25:02and definitely go through the examples
25:04because those can give you a nice head start on how
25:06to use commandlets.
25:07In this CBT Nugget, we saw how to get help in PowerShell.
25:09We covered the three help commandlets-- Update-Help,
25:12Save-Help, and Get-Help.
25:13We saw how to interpret the help by understanding
25:15syntax and parameter sets and different kinds of parameters
25:18out there.
25:18And we even did a demonstration in the virtual Nugget lab
25:20to show you how to use all three of those help commandlets.
25:23I hope this has been informative for you,
25:25and I'd like to thank you for viewing.
Commands
0:00Commands.
0:01In this Nugget, we're going to define what a command is.
0:03We're also going to go over the six different kinds of commands
0:06here in PowerShell, such as commandlets, applications,
0:08aliases, functions, scripts, workflows.
0:10So we'll define what all those are, and then
0:12we'll get into the Virtual Nugget Lab
0:13and we'll do some fun and useful things.
0:15I'll show you how to use Get-Command to search
0:17for commands of a specific type.
0:19We'll also get into aliases.
0:21Show you how you can use aliases,
0:22discover aliases, and even create your own aliases.
0:25At the end of this Nugget, I'm going
0:26to throw three challenges your way.
0:28Level 1, 2, and 3.
0:30Now that we're starting to build up
0:31that base of foundational PowerShell knowledge,
0:34I think it's a good time to start honing
0:36those problem solving skills.
0:38So at the end of Nuggets going forward,
0:39I'll give you some challenges.
0:41You can do them on your own.
0:42I'll also provide the solutions here in our Nugget Lab files,
0:45all right?
0:45So this will be a lot of fun, and it'll
0:47be a good way to get you involved,
0:48and start getting hands-on with PowerShell.
0:50Let's begin.
0:51Let's talk about commands.
0:52So in PowerShell we have six different kinds of commands.
0:55And command is really just a term used very loosely
0:58in PowerShell.
0:58Just think of it as an umbrella term
1:00that could be referring to any kind of command.
1:02Could be referring to a commandlet, an application,
1:05an alias, a function, a workflow, or script,
1:06and those are the six different kinds
1:08of commands that we have here in PowerShell.
1:10Let's start here with commandlets.
1:11Commandlets are the heart and soul of PowerShell.
1:14They are native PowerShell commands.
1:16They're internal, and specific, to PowerShell.
1:18Under the hood, commandlets are just simply compiled .NET
1:22framework binaries, such as .dll files.
1:24In fact, if you're a developer, or know a developer,
1:26they can easily write their own commandlets.
1:29So they'll use their favorite programming language,
1:31such as C# or Visual Basic, inside of their favorite
1:34development environment, such as Visual Studio.
1:36Build a commandlet compile it, give it to us.
1:38We can import it and then use it inside a PowerShell.
1:41The reason PowerShell is so awesome is
1:43because of commandlets, and the reason commandlets are
1:45so awesome is because of the .NET framework.
1:47And that's because everything is an object.
1:50Windows, it's an object oriented operating system.
1:52Visual Basic, C#, those are object oriented programming
1:55languages, and the .NET framework is an object oriented
1:58runtime of the deep type system.
1:59And if none of that makes sense, it will.
2:01We've got a Nugget dedicated to objects down the road.
2:04For now, just think of objects as these rich data structures
2:07that we can also do things with.
2:08And just to give you an example, I don't get too deep into this
2:10because we're going to get deep into it,
2:12but let's take Get-Service.
2:13We've actually used this commandlet many times.
2:16The Get-Service commandlet, if we
2:17were to call that and get back four service objects,
2:20we can then take those objects and pass them
2:22to another command.
2:23We can query those objects to get their state,
2:25those are known as properties.
2:27We can look at things like the name, the status, the machine
2:30name that they're running on.
2:31And then we could even do things with them right?
2:33We could start them, stop them, resume them,
2:35that kind of thing.
2:36So that's why commandlets are awesome,
2:38because they return objects that we can then do something with.
2:41So those are commandlets, and the more commandlets you know,
2:43the more you'll be able to accomplish in PowerShell.
2:45So my advice would be to try to learn
2:46at least one commandlet a day.
2:48Just read through the help file, get familiar
2:49with the syntax, the parameters.
2:51Go through a couple of examples and you'll
2:53be well on your way to mastering PowerShell in no time.
2:55The next command type we have here are applications.
2:57These are external commands.
2:58So all those utilities you were used
3:00to working with in the legacy command line, things
3:02like traceroute, ipconfig, ping, nslookup,
3:05those are all still accessible here inside of PowerShell.
3:07So there's very few, if any, reasons at all
3:10to go back to this old legacy command
3:11line Sure, we can still run ipconfig there, but guess what?
3:14We can come in to PowerShell and do the exact same thing.
3:17Very cool.
3:18In a lot of cases, some of these have better versions
3:21of commandlets.
3:22Ping is a good example.
3:22We now have Test-Connection, which
3:24gives us many more options.
3:25And of course it's object based, which means
3:27we can do a lot more with it.
3:29We also have aliases.
3:30Aliases are fantastic, right?
3:32These are named shortcuts to commands,
3:33and they serve a number of purposes.
3:35The obvious one is that they're going to save us on typing.
3:38The verb-noun naming convention is
3:40fantastic for so many reasons.
3:42But about the only reason they're not good for
3:44is typing, because they result in long names, even
3:47the short ones.
3:47Like Get-Content is still quite a bit of typing.
3:50So that's why we have aliases, number one,
3:51to reduce the amount of typing we have to do.
3:53But number two, this is how people could just
3:56jump into PowerShell and do what they did before.
3:58They were instantly comfortable because they could still
4:01do a dir.
4:02Or if they're from Linux, they could do an ls.
4:04These both map to the commandlet Get-ChildItem,
4:06a commandlet we'll be getting very familiar with.
4:08So aliases are great.
4:09I'll show you how we can use them, how we can discover them,
4:12how we can find them based on the command name,
4:13or how we can find commands based on alias names,
4:16and I'll even show you how we can create them here,
4:17later in this Nugget.
4:18We also have functions, which are a named
4:20grouping of commands, and they're
4:21extremely useful when you see yourself
4:23doing a lot of the same thing over and over across scripts.
4:26You can wrap that similar functionality into a function,
4:29and then call it by name, and that will give us code reuse.
4:33On top of that, it'll ensure that if we
4:35need to make a change we're only changing it in one spot,
4:37not in multiple scripts.
4:38Here's an example of a function, by the way, that I just threw
4:41together called Get-NewImages.
4:43Any idea what this does?
4:44Don't worry if not.
4:44We've got Nuggets down the road dedicated
4:46to writing scripts, and functions, and workflows,
4:48and all this code oriented stuff.
4:49But this is just going to get all the images, JPG images,
4:53in the user's profile for the last month.
4:56So it's going to take today's date, subtract a month from it,
4:59then store inside of a variable, called images,
5:02all of the images that live inside of, again,
5:04the user's profile directory, and all directories underneath
5:07that that have .JPG as a file extension.
5:10Then it's going to pipe that list into the Where-Object,
5:13which is going to pull out only the images that
5:15have a LastWriteTime that are greater than that start
5:18date, which is less than 30 days ago.
5:19And since I created that function,
5:21now I can use Get-Command with the command type of function,
5:23and it'll show up in the list.
5:25And then we can just call it by name.
5:26I created one image in there called lolcat, put it in there,
5:30and that's what it returns.
5:32If your head just exploded, no worries.
5:33We haven't even talked about half this stuff yet.
5:36Variables, pipelines, all this stuff we're going to get into.
5:38I just wanted to give you a quick idea
5:40of what a function looks like.
5:41Now we also have a command type known as workflows.
5:44Another very, very cool thing.
5:45So if you're familiar the Windows Workflow Foundation,
5:47think of it as kind of an execution engine
5:49here, that we can use to control processes.
5:51We can have them execute in sequence or in parallel
5:54across a number of machines.
5:56That's what-- kind of the power that we have brought
5:59into PowerShell here, natively.
6:00And it's absolutely incredible that we can now take commands
6:04and we can have them run all at the same time on a machine,
6:06or multiple machines, or we can sequence them across machines.
6:10It's going to make things very easy when
6:11you have an order of operation that you need explicitly
6:15defined inside of your scripts.
6:17And here's a really simple example here, actually.
6:19Workflow, called it parallelism, that's
6:21how we would call it then, as we do down here.
6:23And then we define a parallel group of commands.
6:26Meaning, these are going to execute at the exact same time.
6:29So if we execute it 10 times, chances
6:30are we're going to get different results.
6:32One's going to finish before the other one.
6:34Finally, we have scripts.
6:35This is really just a bunch of commands stored inside
6:37of a .ps1 file.
6:38But it's obviously a lot more than that,
6:39because this is where we're going to all the big stuff.
6:42Whenever we need to incorporate logistics, or control
6:45the flow of execution, we need variables to store data.
6:47We need to use lots of different commands.
6:49Maybe we need to do things across products.
6:51This is how we're going to get it done.
6:52Here's an example of when and how you would use a script.
6:55This one imports Active Directory Users
6:56from a CSV file.
6:57And it's not complete.
6:58We'll get in and clean this up down the road
7:00and make it actually work.
7:01But just to give you a general idea here,
7:02we've got a couple of variables here.
7:04One to store the domain name, one
7:05to import those users from a CSV file into a variable.
7:09Then we loop through each user for each record inside
7:13of that CSV file, and then we create an Active Directory User
7:15account.
7:16We set up some more variables inside of our loop,
7:18we call the New-ADUser command line, here,
7:20which will actually create the user.
7:21Then we set the password never expires to true on this user.
7:24Then finally, we enable the account.
7:26So it'll run this loop once for each user inside of that CSV
7:30file.
7:30We save this as a .ps1 file, and then we execute it through
7:34PowerShell.
7:34Pretty straightforward.
7:35Again, all stuff that we'll get into down the road, just
7:37want to give you an idea of what it looks like.
7:39Now that we're familiar with all the different command
7:41types in PowerShell, let's jump into the Virtual Nugget Lab
7:43and do a couple of demonstrations
7:45around commandlets, applications, and aliases.
7:47All right we're back in the Virtual Nugget Lab.
7:49Let's do some work.
7:49The first thing I want to do is show you
7:50how you can find commands of a specific type.
7:52So let's do a help on Get-Command
7:54here for the parameter of CommandType.
7:58So what this is going to do, is this parameter on Get-Command
8:01allows us to choose what we want to look for.
8:03Do we want to look for commandlets, aliases, scripts,
8:06workflows, functions, or all?
8:10So this all, by the way, is the same as doing Get-Command*
8:14which will give us everything.
8:15Just doing a Get-Command without specifying a command
8:18type, as you see, the default value down here
8:19will get commandlets, functions, workflows, and aliases.
8:22So what this means, here, is we could do something like this.
8:24If we wanted to find all commands that started, or let's
8:28say that had proc in it, for process,
8:30for the command type of say, commandlet.
8:34There we go.
8:34That's going to show us all just commandlets that
8:37have proc inside of the name.
8:39So here's all of our process commandlets.
8:41What about applications?
8:43Let's clear the screen here.
8:44So let's do something similar here.
8:45Let's do a Get-Command.
8:46Let's find everything starts with p that is of the command
8:49type, how about, application.
8:52Remember, applications are external commands,
8:54and there they are.
8:54Look at them all.
8:55Tons of them.
8:55And look at--there's ping in there.
8:57And by the way, this is going to search everything
8:59in the environment variable, inside of your path environment
9:01variable, which is right there.
9:03If you look inside of there, here are all the paths.
9:05You can add your own to it, as well.
9:06But that's going to search all of those
9:08for all the external commands that start with p.
9:11How about functions?
9:12Let's do the same thing here.
9:13And let's do a Get-Command.
9:15And let's search for all functions
9:17that start with cl that are of the CommandType function.
9:21There we go.
9:22All right, let's head back to commandlets.
9:23And what I want to do is just give you
9:24a nice, easy workflow for learning a commandlet a day.
9:27Here's how I do it.
9:27So the first thing we want to do is
9:29figure out what we want to learn about.
9:31Maybe today we're going to learn about all the different things
9:33we can do with services.
9:34But before we even go there, because
9:36of the whole verb-noun naming convention,
9:38verb dash noun is how commandlets
9:40are named, which makes it very easy for us to discover.
9:42Wouldn't it be helpful to get a list of those verbs?
9:44Well you can.
9:45Get-verb.
9:45Here's a new command that we haven't looked at yet.
9:46Check this out.
9:47All of the verbs that Microsoft uses
9:49across all the commandlets.
9:51So here's all your common ones-- add, clear, close, copy,
9:53enter, exit, find, format.
9:54So on and so forth.
9:55So just by looking at this, you could
9:56say, oh if I want to see everything
9:58that we can do formatting, we can just do a Get-Command -verb
10:02format.
10:02And that'll show us all the commandlets
10:04that have format as it's verb.
10:05Pretty cool, huh?
10:06Great.
10:07So that's that.
10:08Now the next step.
10:09Let's say that, again, we wanted to find all the things that we
10:11could do with services.
10:12Let's do a Get-Command.
10:13And this time, let's do a noun for service.
10:15Look at that.
10:16There's all of our service commandlets.
10:17We can do a Get-, New-, Restart-, Resume-, Set-,
10:19Start-, Stop-, Suspend-.
10:20Let's say that we wanted to create a new service.
10:23What are we going to do next?
10:24Probably look at the help topic, right,
10:25to get an understanding of what it does,
10:26its parameter sets, the parameters within those sets,
10:29and some examples.
10:30So we can do a help on new-service.
10:33And let's just do a -showwindow because it's always a good idea
10:36to get this help up here in a new window,
10:37so we can search for what we're looking for.
10:39And it's just a much easier way to learn
10:41about this specific topic.
10:43So we can see that there's one parameter set.
10:44We could dig into all the parameters in there.
10:46But let's say we-- now comes a time where
10:48we kind of understand what this does,
10:49we know what we want to do.
10:50Well what about actually writing the command?
10:52This is where show-command is extremely helpful.
10:55Let's do show-command new-service.
10:57It's going to pop up a GUI here that we can then
11:00use to have it write the command for us.
11:02This is so nice for learning how the parameters should
11:06be structured, and formatted, and how we could really
11:09structure the command, right?
11:10So let's type in a binary path here.
11:12What we're going to do is make Notepad run as a service.
11:14Silly, pointless, but it proves the point,
11:17here, inside of the demo.
11:18So let's do a c colon backslash system 32, I believe it is?
11:22It is.
11:23Notepad.exe, there it is.
11:25This is the system name.
11:26Let's just do np for the system name.
11:28For the display name, let's do Notepad,
11:29and let's give it a description, here.
11:31How about Notepad as a service.
11:34Awesome.
11:35Now, don't hit run.
11:36What you want to do is hit copy, close out of this,
11:39and then paste it in here.
11:40Remember Control-V won't work.
11:41Right-click is your copy with Quick Edit mode turned on.
11:45And there it is.
11:45It wrote the command for us.
11:47New service, there's the path to Notepad.
11:49There's the system name, there's the description,
11:51there's the display name.
11:52If we hit Enter, there it is.
11:53It's actually going to return back to us,
11:55and now we have Notepad running as a service.
11:57It stopped, but it's there as a service.
12:00In fact, if we just go into Services, here, just
12:02to show you in the GUI that it is, in fact, there.
12:04And we head down here to the Ns-- where are you?
12:07There it is.
12:08Look at that, everything we specified.
12:09There's the name, the display name, description,
12:12and if we go into it here, we can also
12:13see the system name, or the service name right there.
12:16Pretty cool, right?
12:17We just created our own service.
12:20Unfortunately, if we go back to Show-Command here,
12:24or Get-Command I should say, there's no remove service.
12:28There's nothing there.
12:30So we're not going to be able to use any built
12:33in commandlet for doing that.
12:35Probably a good thing there's no commandlet for Remove-Service,
12:37though.
12:37That sounds kind of dangerous if it was that easy, right?
12:40So I'm going to use WMI and an actual method on the object
12:45that it returns to do.
12:46So again, this may not make sense,
12:47but it will down the road.
12:54So we've got a PowerShell commandlet here
12:56that is going to go and get all the services filtered
13:00by the system name, or the service name of np.
13:02So this is going to return one object.
13:04It's going to return that object.
13:05So then we're going to directly call
13:06the Delete method of that object, and there it is.
13:09It's gone.
13:09Now if we do a Get-Service for anything that starts with np,
13:13we're not going to get anything because Notepad's gone.
13:15All right, let's move on to aliases.
13:17So how do you think we can find every alias in the system?
13:20There's actually a couple ways.
13:21We could run Get-Command with the command type of alias.
13:23That's one way.
13:24There they are.
13:25The other way would be, you guessed it, get-alias.
13:27There they are.
13:28Now let's say we're always using dir.
13:30We're always using ls.
13:31And we want to find out what commandlet
13:33these are actually executing.
13:34There we can run a get-alias, and just pass in dir.
13:36Or pass in ls.
13:38And we can see these are both mapped to get to Get-ChildItem.
13:41So what if we wanted to do the reverse of that?
13:43We wanted to find out all of the aliases associated
13:45with Get-ChildItem.
13:47Well here's where we could use the -definition parameter
13:49and pass in Get-ChildItem.
13:51There we are.
13:52Three of them.
13:53Dir, ls, as well as gci.
13:54You'll see all of the commandlets
13:55have built in aliases, as well.
13:58So get-process is gps.
14:00Get-Service is gsv.
14:01That kind of thing.
14:02Now let's say that we wanted to create our own aliases.
14:05How do you think we could go about doing that?
14:07You guessed it, New-Alias.
14:08So let's just look at the help file for this real quick.
14:10You can see we have one parameter
14:11set, two positional parameters in your name and value,
14:13those are going to be the most common ones.
14:15So New-Alias, your alias name, followed by the value.
14:18Which, if it's a commandlet, it's
14:20going to be the name of the commandlet.
14:21If it's an external application, it's
14:22going to be the path to that external application.
14:25So let's just do a New-Alias, and let's say, you know what?
14:27Let's say that we're sick of typing out right here, Notepad.
14:30Let's say we wanted to shorten that to np.
14:32We'll do a New-Alias, we'll call it np,
14:35and we'll say Notepad.exe.
14:36There you go.
14:37Now we can fire up Notepad just by doing that.
14:40Pretty cool.
14:40Now here's the thing with aliases.
14:42They're only going to last for as long as our session lasts.
14:45So if we close out of this and reopen it,
14:47np will no longer work.
14:48This is where Export-Alias comes into play.
14:51So let's just give us the path here,
14:52and let's just type in my-aliases.csv.
14:55And let's say we only wanted to export our np
14:58alias that we created, not all the system ones.
15:00We can do that.
15:01And now, it's safe and it's stored in there.
15:03And now if we close out and come back in, and type in np,
15:06you'll see that it no longer works.
15:08So what are we going to do?
15:10We're going to do an Import-Alias,
15:11and pass in the path to our file there.
15:13There it is.
15:14And now, Notepad will work.
15:15In fact, let's just Notepad my-aliases.csv just to check it
15:19out.
15:20And there it is.
15:21There is our alias for this machine.
15:24Cool.
15:25So that's aliases and that's how they work.
15:27Now last thing I want to do is show you some challenges,
15:30or give you some challenges, I should say.
15:31And also show you where you can find all these commands
15:33that we were just working with.
15:34In fact, here, if we just hit open, right inside
15:37of the directory for this Nugget in Nugget Lab Files,
15:39here is commands.
15:40So here's all the commands that we were just working with.
15:42So there's those for reference.
15:44And then if I open up challenges here,
15:47here are your challenges for this Nugget.
15:49Level one, display all services running on the local host
15:51to have a display name beginning with the letter
15:53B. We've done that one before.
15:54That should be relatively straightforward.
15:56Level two, display a list of commands
15:58that are commandlets in any module that
16:00starts with Microsoft.
16:01We've done that one before, too.
16:02That should be pretty straightforward.
16:03The third one here, we have not used this commandlet yet
16:06in this course.
16:06So I wanted to throw something out there
16:08so you could discover and use the help
16:10files to learn on your own.
16:11Copy the contents of a directory,
16:13including subdirectories, from one location to another.
16:15Follow these steps.
16:16It'll help you out along the way.
16:18It'll also get you familiar with some things
16:19we did in this Nugget, such as aliases.
16:21All right?
16:22Now the solutions, at least my version of the solution here,
16:24are underneath these regions.
16:25So you expand those, and it'll show you my solutions.
16:29To access this, again, all these Nugget Lab Files
16:31are available on the right hand side of the course page.
16:34You can download them.
16:35So just log in, head to the course page, download them,
16:37and you'll get access to all the commands
16:39that we've used throughout all these Nuggets,
16:41as well as the challenges.
16:42So good luck.
16:44In this CBT Nugget we defined what
16:45commands are in PowerShell.
16:47We covered the six different kinds of commands.
16:49We saw some of the neat things we could do with Get-Command.
16:52Went through some workflows for learning new commands.
16:54Learned all about how to use and create aliases.
16:56And at the end here, I gave you a couple of challenges.
16:58I hope this has been informative for you,
17:00and I'd like to thank you for viewing.
The Pipeline
0:00The PowerShell pipeline.
0:02So this is where things start to really get interesting,
0:04and this is where PowerShell begins to separate itself
0:06from the pack.
0:07Piping is how we can chain commands together.
0:11So we can take a command, get the results of that command,
0:14and pipe it as the input to another command.
0:17So this is what allows us to do so much with so little,
0:20without having to resort to things like scripting,
0:22because we can get a lot done by just stringing together
0:26commands in a pipeline.
0:27So in this Nugget, we're going to get
0:28all the basics of the pipeline down,
0:30we'll learn how to chain commands together,
0:32and by the end, we'll be doing some pretty cool things.
0:34Let's begin.
0:34So PowerShell allows us to chain commands
0:36together using the pipe symbol, which may
0:38look like this, or this, right?
0:41And what that allows us to do then
0:42is connect commands together, where the output of one command
0:45becomes the input for another command.
0:47Now, here's the big difference, and this
0:49is where PowerShell separates itself from the pack.
0:51It's very easy to construct PowerShell pipelines,
0:53because we don't have to worry about parsing text.
0:55Chain of commands is nothing new, in fact,
0:57it's been around for a very, very long time.
0:59But what is new is that PowerShell
1:01utilizes objects, not text.
1:04Anyone watching with experience in other shells
1:06will really appreciate this, because oftentimes,
1:09constructing pipelines in other cells meant
1:11that if you need to get something specific,
1:13you had to do string parsing.
1:14And it meant a lot more steps, and it
1:17equated to these extremely long and complex pipelines.
1:20So it takes hours and days to construct in older shells,
1:23it takes seconds and minutes here in PowerShell,
1:26due to these beautiful data structures, known as objects.
1:29Everything in PowerShell is an object,
1:30so commandlets return objects as output,
1:33and can accept objects as input.
1:35So here's how this works.
1:36Let's take a conceptual view of this first,
1:38and then we'll look at some real commands,
1:39and they'll actually get in do this stuff.
1:41So the first thing you're going to do here
1:43is you are going to run a getter, right?
1:45A getter, like get service, for instance.
1:47Here's the alias for get service, GSV.
1:49And let's say get service retrieves
1:51eight services, right?
1:52Maybe we put a filter on there to give us
1:54services that started with w or whatever.
1:56And these servers are going to come back
1:57and they're all going to be objects, right?
1:59Objects that describe that specific service.
2:01So we have a representation of that service here as an object.
2:04And let's say we've got three running services
2:06and a couple of stop services.
2:07Now, let's say we want to pipe this,
2:08here's where the pipe symbol comes into play.
2:10We want to take those objects and send them
2:12into the pipeline, because maybe we want to do something with.
2:15We want to transform them, maybe do
2:16some filtering, some sorting, some formatting.
2:19Whatever we want to do, we've got lots of commandlets
2:21here that we could send these objects to.
2:23So let's say we pipe them to something called Where-Object,
2:25and we're going to get into lots of this commandlets that
2:28allow us to operate and transform
2:30things in the pipeline.
2:31But Where allows us to put a filter, so let's
2:33say we want to filter out anything that isn't running,
2:36so we could do Where status equals running,
2:39and that would then give us just these three objects.
2:42It would throw anything that's stopped out of the pipeline.
2:44And these three objects then we could pipe to another command.
2:47And let's say we want to do something else,
2:49like use the Select-Object command, which allows us
2:52to pull out other properties.
2:53Whenever we've done GSV in the past,
2:55we only get those three default properties,
2:58which are name, status, and display name.
3:00Well, Select allows us to dig into the object to pull out
3:03all kinds of other properties.
3:05And once we get into objects, we'll
3:06actually see how to interrogate an object to discover
3:09what those properties are.
3:10Let's say we wanted to pull out not
3:12just the name and the status, but maybe the machine name,
3:14so we would do that.
3:15We would get those three objects,
3:16and we would pull out those specific properties,
3:18and then maybe want to pass it down the pipeline again.
3:20So we pass these three objects to,
3:22how about something like Sort, there's a Sort-Object.
3:25And let's say we want to sort it by their display name.
3:28This would actually line them up and just
3:29sort them by display name.
3:32Then we could take these and pass them further
3:34down the pipeline, to do even more with them.
3:36And once you get to the end of the pipeline,
3:38we could do something like send them
3:39to the stop service commandlet which
3:43would stop these three objects.
3:44Or we could send them to a format commandlet, which
3:47allow us to format the output.
3:48Maybe we want to format them as a table,
3:50or format them as a list, or maybe you
3:53want to send them to a file.
3:55So they're going to stay objects in the pipeline
3:57until the very end.
3:57And at very end, we're either going
3:59to do something with them like perform
4:00an action on those objects, again,
4:02something like self service.
4:03Or if we don't do anything, PowerShell
4:05is going to attach the out default commandlet to them,
4:08which will extract the default properties
4:10and display them on the screen.
4:11In fact, here's a list of a lot of the common commandlets
4:13you'll be using to operate on objects when you're
4:16in the pipeline, and we'll be going through many of these
4:18over the next few nuggets.
4:19So we've got some formatting commandlets,
4:21which allow us to control how the results of the pipeline
4:24are displayed.
4:25We've got some out commandlets, which
4:26allow us to send those results to things
4:28like files and printers.
4:29We've got a whole bunch of things
4:31that we'll be utilizing inside of the pipeline,
4:34so selecting, filtering, grouping,
4:36measuring to get counts in mins, and averages, and max.
4:38Tease, if we want to take the objects that
4:40are in the pipeline and send them to a variable or a file,
4:43while also leaving them in the pipeline.
4:45Sorting, comparing, and then for each,
4:47which allows us to loop or iterate over objects
4:50inside of pipeline.
4:50Again, we'll be getting familiar with many of these,
4:52especially when we get into our objects Nugget.
4:54And then we've got some commandlets here
4:56for converting to HTML, CSV.
4:58We've also got exporting and importing commandlets, so
5:00all kinds of things that we can do inside of the pipeline.
5:03Let's look at a couple of real examples,
5:05and then we'll get into the Virtual Nugget lab
5:07and see this stuff in action.
5:08So let's say we wanted to get a listing of files greater
5:10than a hundred megabytes, sorted by length,
5:11and then formatted in a nice list.
5:13Sounds like a lot of work doesn't it?
5:15Well thankfully in PowerShell, it's not.
5:17So the first thing we need to do is run our getter,
5:19to get a bunch of objects.
5:20And what could we do to get a listing of files?
5:22You guessed it, we can run Dir, which is an alias for get
5:25[INAUDIBLE].
5:26We'll run it with the recurse switch
5:27and that's going to set us up by returning
5:29a lot of files as objects.
5:31Now, the next step is to set up a pipeline
5:34and send those objects down, but before we do that, let's fire
5:37up PowerShell.
5:38Actually follow along with me.
5:39If you've got PowerShell, just open it up
5:41and run Dir with the recurse switch, just like so, right?
5:44There it is.
5:45There's our big listing of files.
5:46Those are all objects.
5:47It's a collection of objects.
5:48I'm going to Control c out of that,
5:49because it would go on forever.
5:50But what happened there is we just
5:53ran a Dir with recurse switch.
5:54And what happened is, everything's
5:56a pipeline in PowerShell, so PowerShell actually
5:58appended a pipe to that, and sent it to
6:00out default, which is a commandlet that
6:01sets up the default formatting, which in this case was a table,
6:04and pulled out the default properties of that object,
6:08which in this case was the mode, the creation
6:11time, the length, and the name.
6:13That's going to be important once we get into objects
6:15and advanced pipelining.
6:16I'll show you how we can control all this stuff,
6:17but that's a good set up.
6:18Now, we only want to get files that are greater than 100
6:23megabytes, so here's where we can pipe those objects
6:26to Where-Object's.
6:28Objects.
6:28So we'll set up a pipe here, which
6:30will send those objects down, and we're
6:32going to use Where-Object to filter out
6:35any objects that do not have a length greater than 100
6:37megabytes.
6:38So this is going to take a lot of those objects that we
6:40just saw in the output, and kick them out of the pipeline.
6:43So let's do that.
6:43Let's head back here to PowerShell,
6:45and we already added the pipe.
6:46Now, we're going to do a Where-Object,
6:49and now we're going to specify the property that we want
6:51to filter on, let's say name-- or excuse me,
6:53length is what we want here.
6:55Length, and we're going to say greater than 100 megabytes,
6:58and let's hit Enter.
7:00And I should only have a few of them in here, and I do.
7:02There they are.
7:03So that was the next step in the pipeline.
7:05We took that down to just five objects.
7:08Now, the next step, let's add another pipe
7:09and let's say that we wanted to sort them by length,
7:12because right now, they're not sorted by length at all.
7:14So here, we're going to set up another pipe,
7:16and then we're going to use the Sort-Object commandlet,
7:18and say we want to sort them by length,
7:20and by default, it will sort them ascending.
7:22So let's recall our last command, which
7:24is just awesome by the way.
7:25That helps in constructing these pipelines,
7:27because you can run a command, see the results,
7:29set up your next command, see the results, so on and so
7:31forth.
7:32So let's add a pipe, let's do a Sort-Object,
7:34and we want to sort it by length, and let's hit enter.
7:37And now, we're going to get the same results,
7:38only now they're going to be sorted by length ascending.
7:41Check that out, pretty cool.
7:43Now, once again, it attached the out default commandlet
7:45to the end and gave us the default format
7:47and in default properties there.
7:49But let's finish this up by formatting it as a list.
7:51Let's just say we want to take those objects
7:53and we don't want the table format,
7:54we want to see them in a list, so let's do that same thing.
7:57Let's recall our last command, let's add another pipe,
7:59and let's just format that as a list.
8:02And now, instead of the table view,
8:03we get them all separated out in list format.
8:07Pretty cool.
8:08So that that's how powerful the pipeline is, and how easy
8:11it is to construct a pipeline.
8:12Let's do one more example.
8:13Let's say that we wanted to get all the services that
8:16were stopped.
8:16Pull out specific properties, sort it by the name descending,
8:20convert it to HTML, and then create an HTML file
8:23with all that data in it.
8:24Sounds again like a lot of work, but it's really not.
8:27We'll start with a Get-Service, which
8:28is going to get us, again, a bunch of Service-Object's, all
8:31of them, because we didn't put a filter.
8:32So this will get us all the services on the system.
8:35Then we can filter out anything that isn't stopped,
8:38so we'll do a Where-Object.
8:40The property we want to filter on here is status,
8:42word equals stop.
8:43So that's going to kick out anything that isn't stopped,
8:45and just give us a handful of services.
8:47Then we're going to use the Select-Object to pull out
8:49specific properties.
8:50Say we don't care about display name,
8:52we just care about the name and the status.
8:53Well, we could do Select-Object, name, and status,
8:56that will just get us those properties for those objects.
8:59Then we want to sort them by name,
9:01only this time descending, so we can use the descending switch
9:03on the Sort-Object commandlet, which will sort them
9:06in reverse order.
9:06And then we can convert the output to HTML,
9:09send that to the out-file command,
9:11which will then generate an HTML file with those results.
9:15Look at that, that's a nice little pipeline there using
9:17many commandlets to take the services that we want
9:21and a specific data we want, convert it to HTML,
9:23and store it inside of a file.
9:24All right.
9:25I think you get the idea, right?
9:26Pipelines are powerful.
9:27Let's jump into the virtual Nugget lab
9:29and see some of the neat things we can do with them.
9:30All right.
9:30Welcome back to the virtual Nugget lab.
9:32We are on our CL8 Nugget machine.
9:34Let's bring up the shell, and let's just
9:36do some work in here.
9:37Let's get service.
9:38What's the alias for Get-Service?
9:39GSV.
9:40And let's say we want to get all the services on the system,
9:43but we want to sort them, because the default output
9:45here, it is sorted, but it's sorted
9:47by the name, the system name.
9:49See that right here?
9:50It's sorted by the actual service name itself.
9:52So let's say we wanted to sort it by display name.
9:55You see that's not sorted by display name.
9:56We've got a, and then we got Windows here,
9:58and so on and so forth, it's all over the place.
10:00So let's sort this by piping this to Sort-Object.
10:03And by the way, sort is the alias for Sort-Object.
10:06And let's say we want to sort by display name,
10:08so we can do display name.
10:10There we go, now we're sorted by display name, pretty cool.
10:13Now, let's build on that.
10:14Let's say that we wanted to send the output to a tool
10:17that we could use interactively, and that is out-gridview.
10:22Out-gridview is awesome, because it opens up this tool
10:25that we can then filter and do all kinds of things
10:27inside of here.
10:27But there is same results, they're
10:29just inside of this nice great gridview inside of PowerShell.
10:32Cool.
10:33Now, what else could we do here?
10:34Let's say that we want to select all the properties, not just
10:36the default properties.
10:37Well, here's where we could add on to this a select.
10:40So let's add a select right inside of here,
10:42and let's do a select, which by the way
10:44is Select-Object, but select is the alias here.
10:47And let's say we wanted to select everything,
10:49we could put an asterisk in there.
10:50And this is actually to pull up all the properties
10:52of the object and put them here instead of a gridview.
10:55Check it out.
10:55Here's all the properties of our Service-Object right here.
10:58Pretty cool.
10:59So can pause and continue, can shut down,
11:00can stop, as well as all the required services
11:02that it depends on.
11:03And again, we still get the display name, the name,
11:05we get the status over here, and some other things as well.
11:08Machine name that it's running on and so forth.
11:10So there you go.
11:12All right.
11:12Let's take that to the next level.
11:13Let's say we wanted to run Get-Service
11:14against all the servers on our network
11:16and do some fancy things in the pipeline
11:19to pull out specific data.
11:20Well, on our share, on our ps4 share here on our file server,
11:23I created a directory called files.
11:25And in here, I've got servers.txt.
11:27Here's a list of all our servers,
11:28DCNUGGET, APPNUGGET, FSNUGGET.
11:30So we want to read those servers in as the computer name
11:32parameter for Get-Service, and then
11:34set up a pipeline to operate against those services.
11:37Let's do it.
11:47So here's what we're doing.
11:48We're going to run Get-Service.
11:49Let's just pull out the Bit-Service, rather than
11:51all the services.
11:52We're going to specify the computer name parameter,
11:53and then we're going to use Get-Content
11:55to pull all of those names, those servers,
11:57out of servers.txt stored on our file server.
11:59Then we're going to sort them by name,
12:02then we're going to do a Select-Object, name, status,
12:04machine name, and this is because machine name isn't
12:07in the default output for the object,
12:09so that's where we're going to pull out
12:10that specific property.
12:11And then, we're going to format it as a list.
12:13Let's see what we get here.
12:14So if we hit Enter, it's actually going right now
12:16across all those services to pull that Bit-Service back,
12:19and then it's going to pull out those specific properties,
12:22and give us a nice formatted list.
12:24And there it is.
12:25We've got a list, we get the service name,
12:27we get the status, and we get the machine
12:29that it's running on.
12:30Very cool.
12:31Let me show you something else neat we can do.
12:33So at the end of the pipeline this time,
12:34rather than displaying it to the screen here,
12:36let's output all that to a csv file and take a look.
12:39So let's run GSV here for Get-Service.
12:40Let's just grab all the services that start with win,
12:43and then let's pipe that to only get services
12:46that are currently running.
12:47So we'll do a Where-Object here, and we're
12:49going to do status, which is a field name, equals running.
12:53And we're going to pipe that to Export-Csv.
12:57Give it a name here, services dot csv, and there we go.
13:00Now, let's fire that up.
13:01Let's just do a notepad here on services dot csv,
13:04and there it is.
13:05So instead of putting those objects to the console,
13:08we exported them, all those objects and their properties,
13:11to a file.
13:11Let's do another one.
13:12Let's say that we wanted to create a web
13:13page of all these services.
13:15We'll see the same thing here, only this time
13:16let's export it to HTML.
13:18Now, there is no Export-HTML commandlet,
13:20so we first need to convert it.
13:22So we can do a convert to HTML, and then we're
13:25going to take the results of that, which will be HTML.
13:28And by the way, if we just did this,
13:29it's going to display the HTML on the screen.
13:31But we want to actually export it out to the files.
13:33We can do an Out-File, and let's call
13:35this one services dot HTML.
13:37Cool.
13:38Now, what we can do is Start-Services dot HTML,
13:40which will launch it in its default application, which
13:42should be Internet Explorer in this case,
13:44and there are all the services stored inside of a web page.
13:48So that you have a good taste of how to construct pipelines,
13:51and what piping is all about.
13:52Remember all of these commandlets return objects,
13:54and we could take those objects and pass them
13:56as input to other commandlets.
13:58And it makes it very easy to construct these elegant,
14:01easy to work, with pipelines.
14:02Let's finish this Nugget up with some challenges.
14:04So I'm going to fire up the ISC here, and remember,
14:07you can access the commands that we just
14:08worked with here inside of the directory
14:11in the Nugget Lab files for this Nugget, as well as challenges.
14:14So here are the commands we just worked
14:16with, and then over here, I opened up our challenges file.
14:19So here are the challenges for this Nugget,
14:21the PowerShell pipeline.
14:22Challenge number one, write a pipeline
14:24that returns only running services,
14:25and then sort the results in descending order by display
14:28name, something we did there.
14:29Challenge number two, write a pipeline
14:31that retrieves a list of files over one gigabyte on the system
14:34drive, and save the results to an HTML file.
14:36We did those across a couple of commands there.
14:38You should be able to figure that one out.
14:40And the big one, challenge number three,
14:41write a pipeline that retrieves the name, synopsis,
14:44and module name properties from Get-Help
14:46for all get commandlets in the Microsoft module,
14:49then output the results to a grid for interactive analysis.
14:52This is kind of a tricky one, so I gave you some help here.
14:54Number one, use Get-Command to retrieve
14:56all the get commandlets in the Microsoft modules.
14:58We've used this in previous Nuggets.
15:00Pipe those results to get help, and then you
15:02select to pull out the name synopsis
15:05and module name properties from those Help-Object's, and output
15:07the results through a gridview.
15:09The end result be a nice gridview containing
15:11all of the help that you need for all the get commandlets,
15:14right?
15:15It'll have the name, quick overview, and the module
15:17that they live in.
15:18Good luck.
15:19Remember, just expand these regions here in the challenges
15:21file to see the solution for these challenges.
15:24In this CBT Nugget, we started digging into the pipeline.
15:26We saw that the pipeline is really
15:28just a way that we can chain commands together using
15:30the pipe symbol.
15:31We can take the output from one command
15:33and use it as input for another command.
15:35And the beauty of PowerShell is that everything
15:38is object based, objects are flowing
15:40through the pipeline, which makes it very easy to work
15:42with, and this is how we get so much power out of just writing
15:46commands, rather than scripts.
15:48Until next time, I hope that this has been informative
15:50for you, and I'd like to thank you for viewing.
Objects
0:00Objects.
0:01This is it right here.
0:02This is what makes PowerShell PowerShell
0:04and what makes it stand out from all the other shells.
0:06In order to become an effective PowerShell IT pro,
0:09we need to understand what an object is
0:11and the role that it plays.
0:12And one of the great, great things about PowerShell
0:14is it's uniting sys admins and developers across the world
0:17because they need to speak each other's language.
0:20Developers need to understand how administrators perform
0:23their task so they can build commandlets
0:25that will help them automated.
0:27And administrators need to speak the language of developers.
0:30We need to understand what types are, what objects are,
0:33maybe even what classes are.
0:34In fact, that's all PowerShell really is.
0:36It's the .NET framework for administrators.
0:38So in this Nugget, we're going to dig into objects,
0:40see what they're all about and by the end of this Nugget,
0:42you will be able to your developer friends
0:44and say, hey, I know what you do all day.
0:46You create classes, you instantiate objects,
0:49and then you use them and pass them
0:51around all the layers of your application.
0:53Let's begin.
0:54So what is an object?
0:55To really answer that and to fully
0:57understand what an object is, it's
0:58going to help to take a step back and delve
1:00into the mind of a developer.
1:01So the first thing a developer will
1:03do when they're building a new application
1:05is take the real-world parts of that application,
1:08all those data points that we need to represent and transform
1:11it into its digital counterpart.
1:13Let me give you an example.
1:14Let's say that we wanted to build an application
1:16to track employees.
1:17How are we going to do that?
1:18How are we going to transform an employee-- a real person that
1:21works somewhere-- into an object that we
1:23can represent digitally?
1:24Well, they're going to do this through something
1:26known as a class.
1:28A class is just a template.
1:30It's just a blueprint.
1:31That's it.
1:31This is where we're going to make objects from.
1:33Classes are kind of like little factories.
1:35We're going to use them, it's going to return us an object
1:38that we can work with.
1:40Now, a class contains three main parts here.
1:42It contains properties, which are just
1:44data points that define the state of that object.
1:47So we'll have property for a first name, last name,
1:49maybe the address they live at, their position,
1:51their department, their salary, that kind of thing,
1:54all those data points we need to track
1:55that describe the employee.
1:57It also has things like methods.
1:58Methods are the actions that this employee can perform.
2:01What kind of actions can employees do?
2:03Well, we could promote them.
2:04There would be an action.
2:05They could call in sick.
2:06They could get paid.
2:07So those are all actions that we could
2:09take on the employee pass.
2:10The third one here is known as events.
2:13And events are things that can happen to our objects.
2:16So our employee object, for instance, employees,
2:18when they get fired, could trigger the onFired event
2:20or we could have an onHired event.
2:22We can have an onGotPaid and events just give developers
2:24a way to respond when certain things happen to their objects.
2:28So that's all a class is.
2:30It's just a definition of what objects should look like.
2:33It's where objects come from.
2:34So once we have a class in place,
2:36now we could start creating employee objects
2:39and these are going to have state.
2:41They're going to have all their properties fill in.
2:42If we were to call methods of these objects,
2:44they would apply to that specific employee
2:46and that's where objects come from.
2:48Now, when a developer is done modeling their classes,
2:50they'll have many of them in here.
2:51Some of them may have dependencies and relationships
2:54to other classes inside of here, but they'll wrap all of that
2:57and compile it into a DLL and that's
3:00one of the huge benefits of object oriented programming
3:02is now if a developer or other developers in the company
3:05want to build applications that are going to need to represent
3:07an employee, they can tap into that one DLL
3:09rather than creating their own version of it.
3:11And now I'm starting to go deep into the rabbit hole,
3:13so I'll stop.
3:14But if you want to continue on further and get
3:16a real good understanding of how object oriented programming
3:17works, I did a micro Nugget many,
3:19many years back called "What is Object Oriented Programming."
3:22I'll give you the link to that.
3:23Check that if you want to know more.
3:24So now we should know where objects come from.
3:26They come from these blueprints known as classes.
3:29Classes just contain the definition.
3:31Where we create objects, those definitions get filled in.
3:33Now, let's do a little exercise here
3:35because this will really help just
3:36to make sure they're all on the same page.
3:38Look around you right now and pick something out.
3:40Can you describe a couple of properties of that object?
3:42Maybe a couple of methods?
3:44I'm looking out my office window.
3:45I see a parking lot full of cars,
3:47so that's why I have a car here.
3:48And if I look at any one of these cars,
3:50I can list off the make, the model, the color, the height,
3:54the width the weight, that kind of thing.
3:56So all of those properties combined
3:58describe that specific object.
4:00What about methods, the actions that cars can perform?
4:04They can start, they can stop, they can go, they can brake,
4:06that kind of thing.
4:07So you get the idea.
4:08Everything in the role world is an object.
4:09Everything in PowerShell is an object.
4:11These commandlets, when we execute them,
4:13they return .NET objects and that's what gets passed down
4:16the pipeline.
4:17And they can also accept objects as input.
4:20Objects as we just saw, contain properties and methods
4:22and they are of a specific type.
4:24Think of a type as really just the name of the class,
4:26but it's a lot more than that.
4:27It actually forms part of the name space,
4:29which helps us uniquely identify that specific kind of object.
4:34So here's where Get-Member comes into play.
4:36Now, we know that objects are obviously
4:38important because they get passed down the pipeline
4:39and we can do things with them, but how
4:41do we know all of the properties that that object contains
4:44and all the methods, all the things
4:45that we can do with that object?
4:47Because by default, if we were just
4:48to run something like Get-Service,
4:49we would just get name, display name, and status back,
4:53but there's a lot more properties in there
4:55that we can work with and that's where
4:57Get-Member comes into play.
4:58This is really the final piece of the puzzle
5:00when it comes to the commandlets you should know first.
5:03We have Get-Commands, which helps us find commands,
5:06Get-Help, which allows us to get help,
5:07and then we Get-Member, which allows
5:09us to look at what that object exposes in terms of properties
5:13and methods.
5:14So Get-Member is going to display
5:15the members of an object.
5:16Member is just a fancy term for, you guessed it,
5:19properties, methods, and events.
5:21And it's going to be useful for discovering everything
5:23we can do with that object.
5:25From a method perspective, we can call methods directly
5:27on these objects and for extracting or working
5:30with properties that aren't necessarily exposed
5:32in the default output.
5:33And to it, we can just pipe objects to Get-Member
5:36just like we're doing here.
5:37We're doing a Get-Service and we're piping that to Get-Member
5:40and that's going to give us everything we
5:42need to know about that object.
5:43Let's jump over to the Virtual Nugget Lab
5:45see the kinds of things we can do with Get-Member
5:47and also some of the neat things we can do with objects.
5:49Welcome go back to the Virtual Nugget Lab.
5:51Let's fire up PowerShell here.
5:52So remember the whole point of objects and why
5:55they're so awesome is because they're this nice,
5:58simple-to-work-with data structure that we can easily
6:01pass around and work with the properties of these rather than
6:05text.
6:05Because if we were to go to command.exe and type in dir,
6:08that's not dirt.
6:08Yeah, that's pretty much what the old command line is now.
6:11It's dirt.
6:12But if we were to type in dir, this is all text.
6:15It's all text.
6:15So if we wanted to pipe this to another command,
6:17we would have to extract specific text out of here
6:19to pass over there.
6:20But with PowerShell, we don't have to do that.
6:23PowerShell, we run dir.
6:25All of these are properties of that object.
6:28So that's why we can easily pipe this to other command lists
6:32to work with objects and to work with and pull out
6:34specific properties.
6:35So now, we could easily do something like this, dir,
6:38and we're going to pipe that to select.
6:39I want to pull out specific properties of this object
6:42and let's say I wanted to pull out name, maybe
6:44full name, and maybe extension.
6:47Here we go.
6:48Now, there's no full name and extension
6:50in that default output.
6:51You didn't see it up here.
6:52But down here, look, name, full name, which is the full path,
6:56and the extension, which will show up if it's a file.
6:58So how did I know that this object had full name
7:01and extension?
7:02How did I knows those were even properties
7:03that we could work with?
7:04That is where Get-Member comes into play.
7:06So let's pipe this to Get-Member.
7:08Now, look at that.
7:09Now, this is actually going to return two types because dir,
7:12or Get-ChildItem, item, can return directories and files.
7:15So it's showing us here objects could
7:18be of directory type, directory info type,
7:20or they could be a file info type and both of them
7:22have a different set of operations
7:24and a different set of properties on them.
7:26So there we are.
7:27There's extension and there's full name.
7:29These are properties of the file info
7:32class, which are the objects that we're
7:34going to get returned to us.
7:35So we can also see the definition otherwise known
7:37as the signature here, which is how
7:39these properties are defined inside of that file info class.
7:43So we can see the data type that these returned.
7:45These are both strings that get returned back to us.
7:48Now, watch this.
7:48Let's clear the screen here.
7:50So let's run Get-Service-- remember
7:51GSV is the alias there-- and let's pipe this to Get-Member.
7:54GM, by the way, is the alias for Get-Member.
7:56And look at all this juicy information.
7:58We get the type name.
7:59It's a service controller and then we get all of its methods
8:02and all of its properties.
8:03Remember when we run Get-Service,
8:04we only get the status, the name, and the display name.
8:10And also notice name is actually an alias
8:11on top of service name.
8:13Required service is an the alias property on top of service
8:17service is dependent on.
8:18Now we're going to get more into all the different kinds,
8:20but note that .NET classes are really just properties,
8:23methods, and events.
8:25PowerShell is extremely extensible
8:27and so there's a way to extend that and add properties
8:30on top of properties and there's also the same thing
8:32with script methods.
8:33We can add our own methods on top of this.
8:36And we'll get more into this.
8:37We've got a Nugget on extending PowerShell.
8:39We'll get into extending objects as well as importing modules
8:43and things of that nature.
8:44But for now, just know this is how
8:47we look inside of an object.
8:48Use Get-Member because it will show us all the things
8:50that we can do and all the data points that we can pull out.
8:54Let's check out the help topic for Get-Member.
8:56There it is, pretty straightforward.
8:57It's gets the properties and methods of an object.
8:59There's two ways we can use it.
9:00We can just pipe an object to Get-Member
9:02or we could use the input object parameter to get.
9:05But here's the thing.
9:06See this static switch here?
9:07This is really interesting.
9:08So classes.
9:10can also contain what are known as static members, meaning,
9:12you don't actually have to create an object in order
9:16to use it.
9:16It actually says it right here, to return
9:17information about static members, members of the class,
9:20not of the instance.
9:21So whenever we create an object from a class,
9:24it's known is instantiation.
9:26You instantiate the object.
9:28And that just means creating the object from a class.
9:30Well, watch this.
9:31Let's take the math class, for instance,
9:33and let's just pipe this to Get-Member.
9:35Check out this math class.
9:36Lots of things we can do with the math class
9:38and let's say we wanted to get just the static properties.
9:40Here we go.
9:40These are all the static properties and methods,
9:42meaning, we don't actually need an object.
9:44So we can do something like this.
9:45Let's look at the math class and lets look at pi.
9:47See that right down here?
9:48And if I hit Enter, I didn't type in math all the way.
9:52There we go.
9:53Check it out.
9:53There's pi right there.
9:54And see all these static methods?
9:56Yeah, we can use these as well.
9:57In fact, let's take a look at the Min method.
9:59If you just type it in without actually calling
10:01with the names of its parameters,
10:03it's going to show us all of the different overloaded
10:05definitions, all the different ways that we can call it,
10:08and there is lots of different ways
10:09that we can call it using data types,
10:10but you're going to pass in two values.
10:11So we're going to do this.
10:12We're going to pass in value 1, how about 100,
10:14and value 2, 10,000.
10:16What's the min of those two?
10:17100.
10:18Right?
10:18So that's it.
10:19We're calling these methods directly on the class.
10:23We're not using any sort of commandlet to do it.
10:25So I just wanted to show you that because that can actually
10:27be very powerful as you'll see when we get into scripting.
10:29There's some pretty cool things you
10:30can do to take advantage of things like this.
10:32If you need to do any mathematical operations,
10:34you could just go right against the static members of a math
10:36class to do so.
10:38Let's see how we can work with properties and methods
10:40directly on these objects and then
10:41we'll look at some common things we'll be doing
10:43with objects in the pipeline.
10:45So let's do this.
10:46Let's do a dir with the directory switch here
10:48and let's pipe that to Get-Member.
10:49We know this is only going to return this time the directory
10:52info type.
10:54And if we look inside of here and look
10:55at some of the properties, we can pull out full name.
10:57We looked at it before but watch this.
10:59Now, we can do something like this.
11:00Let's just wrap this in parentheses.
11:02This means execute this first and we're
11:04going to need that because we need objects
11:06before we can start working with their properties.
11:08But if we do this, look at this.
11:10It's just going to pull back the full name.
11:11We worked right against that object directly
11:13to pull that property out.
11:15We do the same thing with methods here
11:17and there's a method actually up here--
11:19let's take a look-- called CreateSubdirectory.
11:21Look at that.
11:22There's a method right there.
11:23All right.
11:23Let's take a look at that.
11:24We can do that one by doing the same thing only we're going
11:27to say .CreateSubdirectory.
11:31There we go.
11:32And then we're going to pass in the name of the directory,
11:33but if I were to run this right now,
11:35we would have to create whatever directory
11:36we decided to name it in each one of these directories.
11:38So let's just do one for the desktop here.
11:41We'll just type in desk asterisk and that will just
11:43create the subdirectory name.
11:44How about Test?
11:45Here we go.
11:46Hit Enter and now we created it.
11:48If we look on the desktop when we minimize this, there it is.
11:51There's that directory we created.
11:52So that's how we call a method directly on that object.
11:56How about another one?
11:57Now, I'm going to introduce you to one
11:58of my favorite commandlets because it's just so extremely
12:00useful and in so many things you'll be doing.
12:02Its Get-Date.
12:03If we run Get-Date, it's going to return back
12:05the default property for Get-Date, which is today.
12:08Now, let's do something crazy here
12:10and we're going to get into all kinds of this stuff later.
12:12But I'm going to create a variable
12:13and I'm going to store inside of that variable
12:15a Get-Date object.
12:17So now we've got an object inside of that variable.
12:20In fact, now we could pipe that variable today to Get-Member
12:23and what's it going to do?
12:24It's going to return back our date here.
12:27system.datetime is the type and look
12:29at all the juicy information we can do here.
12:31We can do all kinds of awesome things, add days, hours
12:35milliseconds, minutes, months.
12:36And on the property side, we can extract the day, the year,
12:39the month, the minute, the millisecond, just all kinds
12:42of great information.
12:43In fact, now we could do something like this.
12:44Today dot-- let's get the day of the year that it is.
12:48Boom.
12:48It's day number 286 out of the year.
12:52Let's call a method.
12:53Let's say we want to know what six months from now
12:55is going to be.
12:56We could do add months, pass in six.
12:59There you go.
13:00There's six months from right now is April 13, 2016.
13:05Let me show you one more useful thing when it comes to types
13:07and then we'll jump into the ISE here
13:09and I'll show you some neat things we can do with objects
13:11and give you your three challenges for this Nugget.
13:13So Get-Service.
13:14If we just run Get-Service, what's that?
13:16It's all the services on the system.
13:18What type are those?
13:19Let's find out.
13:20Let's pipe that to Get-Member.
13:21All of those, each one of those was a service controller
13:24object.
13:24So every service that came back was a service controller object
13:27and all those services together are
13:28known as a collection of service controller objects.
13:32Now, here's something really interesting.
13:33Watch this.
13:34Let's pipe all that to Stop-Service.
13:36Now, I don't actually want to run this
13:37because it will probably run to the system, completely useless.
13:40So I'm going to add the switch WhatIf, which is just
13:42an awesome parameter that means it's
13:44going to give us the result as if it did it without actually
13:46doing it.
13:47So if I hit Enter, Stop-Service would have worked.
13:49How did that work?
13:50Well, if we look at the help her for Stop-Service,
13:52we're going to see in that first parameter set,
13:54look at this, we've got a positional parameter here
13:56called InputObject that accepts service controller objects,
14:00in fact, an array of service controller objects.
14:02So that's how this was able to work because GSV, Get-Service,
14:06returns a list of service controller objects
14:10and we just pipe those directly into,
14:12in this case, Stop-Service or any other commandlet that has
14:15us perform actions on services.
14:18And what does this do under the hood?
14:19Yeah, it calls the Stop method on all of these objects
14:23when they get to that commandlet.
14:24Isn't that neat?
14:25So that will hopefully give you a little insight
14:27into how this stuff works under the hood.
14:29All right.
14:29Let's fire up the ISE here.
14:30I'm just going to type in ISE right there.
14:32Boom.
14:32Another way to fire it up.
14:34Let's open up our Commands file here for this Nugget07 objects.
14:38And the top half here is what we were just working with.
14:40They're in the console.
14:41What we're going to do is just get you quickly
14:43familiar with a couple of the more common object commandlets
14:46that you'll be using.
14:47A lot of these are very powerful and any time
14:49you construct a pipeline, you'll probably
14:51be using one of these to some degree.
14:53But just a Get-List of all the object commandlets,
14:55we can run a Get-Command with the noun of object
14:57and here they are.
14:58So some of the ones that we're going
15:00to be here ForEach, Select, Sort, and Where,
15:03by far the most popular ones.
15:05So Where object is first and this
15:06is what allows us to filter out objects from the pipeline
15:10so we can toss them on out of there.
15:11In fact, here's an example.
15:12We're going to run Get-Service, which is going to give us
15:15all the service objects.
15:16So we'll pass that collection over here to Where object
15:19and we're going to say, you know what,
15:20we're going to filter out anything that isn't running.
15:22So we'll say, only keep the objects
15:24in the pipeline where the status is equal to running.
15:26And this syntax here is property comparison operator value.
15:31And by the way, check out the About topic
15:33for comparison operators.
15:34You can get a list of all the different operators out there.
15:36There's a lot of neat things you can do.
15:38But in this case, it's equal.
15:39So if we run this, just highlight it all
15:41and hit F8 on the keyboard.
15:42There it is.
15:43There are all of services that have a running state.
15:46So all the ones that were stopped
15:48got booted out of the pipeline.
15:49Now, the second one is interesting
15:51because this is actually functionally
15:53equivalent to the first one.
15:54It's the same exact thing, just how we
15:56use it is a little different.
15:57So this is known as comparison statement syntax up here.
16:01It's a little more natural and human readable.
16:03The second one is known as script block
16:05syntax and this one is a little more programmary,
16:08but it's also more powerful.
16:09You can do more with it.
16:10So you'll use this comparison statement
16:12syntax for simple stuff.
16:15But we need to start adding in multiple conditions,
16:17for instance, say we wanted to do an And in here, and this
16:19is another beautiful thing about IntelliSense
16:23is that we can see that And isn't even
16:25an option in the list, so we know it's unsupported.
16:27If we go to the script block and do an And, look at that.
16:29It's there.
16:30And now we can add more onto it just like we have down
16:33where we're adding the Boolean property,
16:35can stop only, meaning, true or false.
16:37The other major part of this I want
16:39to point when it comes to script block syntax
16:41and you're used to this especially when you
16:43get into looping and such, is this dollar sign underscore.
16:46This is a special variable.
16:47It's really just a placeholder that
16:48means this and this in programming languages
16:50means the current object.
16:52So this is really just a reference to those service
16:54objects and in fact, if we use the dot after that,
16:57we're going to get IntelliSense here
16:59to give us a list of all the properties and all the methods,
17:02just like Get-Member.
17:04So here's where we can just come down to the property and start
17:06typing and it will scale it down for us and that's what we want.
17:09So we can click on it.
17:10There it is.
17:10Very cool.
17:11So that's Where object.
17:12It allows us to create filters and conditions
17:14and there's a couple of different ways to do it.
17:16Now, Select object is how we're going
17:19to pull out specific properties and here's a neat little trick
17:22here.
17:22If you pipe any of your objects to Select
17:25object and run an asterisk or a star, then
17:28it will actually give us back all of the properties
17:31and their values.
17:31Look at that.
17:33So that's useful to use with Get-Member because Get-Member
17:35will show us all the properties and their data types.
17:38Running this will actually show us the data inside of there,
17:41so that's extremely useful for troubleshooting
17:43and even developing.
17:45But what we'll really be using Select objects for
17:47is to pull out specific properties of the object.
17:49So here we're pulling out machine name and service
17:52type, for instance, which is in the default output,
17:54so that will allow us to do things with those properties
17:56here in the pipeline.
17:57We also got some interesting switches here, parameters.
17:59We have the first and last parameters,
18:01so we can pull back x number of objects.
18:04And this can be useful too for creating those top 10 lists
18:07especially combined with Sort.
18:08We can sort something descending by a numeric value
18:11and pull back the first 10 and that
18:12will give us our top 10 list.
18:13There's also unique parameter if you only
18:15want to work with unique objects, so running this
18:18will give us the top five objects.
18:20Now, we didn't do any sort, so it's just
18:21going to give us the top five objects from A on downwards.
18:25Now, this next one is really interesting.
18:27We're going to step it up a notch here.
18:28So we're going to run Get-ChildItem
18:29against our Installs directory on our PS4 share on our FS
18:33Nugget file server and then we're
18:34going to use Select to pull out name and length.
18:36Now, up to this point, pretty standard stuff, right?
18:38If I run this, it's going to give us
18:40the name and the length, which is in bytes.
18:42But this last bit here is known as a calculated property.
18:47We're adding our own property into the pipeline on the fly
18:51and it's a calculation.
18:52So here's how this works.
18:53This is actually called a hash table.
18:55A hash table is really just a bunch of key value pairs.
18:58So we're defining our hash table at the ampersand and inside
19:00of the script block here, the name, key,
19:03is going to be the name of the property
19:05and then that's the value then is megabytes.
19:07And then the expression is going back
19:09to the value for this property.
19:10So our expression here, we're utilizing an existing property
19:14on the object length and we're dividing it by 1 megabyte.
19:16And it's very cool that PowerShell supports
19:18the megabytes, and the gigabytes, and the kilobytes,
19:21and so on and so forth.
19:21That way we don't have to do all of this manual calculation
19:24on this stuff.
19:24But what this will do then, if we run this,
19:26is that our own custom properties
19:27to the end, that's calculated.
19:29It's dividing this by a megabyte and that gives us the megabytes
19:32rather than the bytes.
19:34We also have Sort object and this is obviously
19:36going to be useful because we can
19:37sort the objects in the pipeline by their properties.
19:40We've got some good switches here.
19:42If you want to sort descending, you
19:43can add the switch parameter to descending.
19:44If you want your sort to be case sensitive,
19:46you can add the case sensitive switch,
19:48so this will just simply then sort it by length.
19:52There it is.
19:52Everything is sort of now by a length.
19:54See that?
19:54And we specify descending so it's going highest number down.
19:58The last one I want to get your familiar with here is looping.
20:00The ForEach object allows us to integrate over
20:03the objects in the collection one
20:05by one so we can do something to that object.
20:08And this is really powerful stuff
20:10that we can do this in a command.
20:11We don't have to resort to scripting to do this
20:13although we can do this in scripting as well, which we'll
20:15look at down the road.
20:16But here's a very simple example.
20:17We're going to take 1, 2, 3, and 4.
20:19Here's four objects, which are just integers
20:21and they're just numeric values and we're
20:23going to pipe this to ForEach and then inside of this script
20:25block here, it's going to process those one by one.
20:28And again, we're referencing the current object.
20:31So the first object that's going to go in is 1.
20:33It's going to get multiplied by 100, then 2, then 3, then 4,
20:36and watch the results of this.
20:38There it is, 100, 200, 300, 400.
20:39So that should give you a good idea of how ForEach works.
20:42It just iterates over each object in the collection
20:45and we do something with it inside of our script block.
20:47Now, let's take that to the next level.
20:49Let's say that we wanted to get a list of all the exe's
20:54on a machine that were created this year
20:57and log them to a file.
20:58That's what we're going to do here with this command.
21:00So we're just going to run a dir against the system
21:03drive for all the exe files and we'll recurse it.
21:05Then we're going to pipe all of those objects,
21:07there will be a ton of them, to our Where object
21:10and Where is obviously, the [INAUDIBLE] there for Where
21:13object.
21:14Then we are going to say, only give us objects, only exe's,
21:20that were created this year.
21:21And this is really cool because what we're doing is,
21:23we're doing this based on the creation time of that file,
21:27but because it's a date time object, as we saw earlier
21:29with Get-Date, we have access to a lot of underlying properties
21:32on that object such as year, month, day, second, minute,
21:37millisecond, so on and so forth.
21:38So we're just going to extract the year property of that
21:41and do an equality comparison against the current year.
21:44So this is going to kick anything out of the pipeline
21:47where the creation year is not this year.
21:50Then we're going to use the percent sign here.
21:52This is the alias ForEach object.
21:55And then we're going to have a begin, a Process, and an end.
21:57So we BeginOnly happens once before the loop occurs.
22:00EndOnly happens once after the loop is done.
22:03Process is this right here and that is
22:06the positional parameters here.
22:08This is why we didn't have to specify Process.
22:10But Process is what is actually going
22:12to get run for each object inside of the pipeline.
22:14And in this case, what we're going to do is,
22:16we're going to send each object to the Outfile commandlet,
22:20we're going to store it inside of exe-log.txt,
22:23we're going to append to it because if we don't do that,
22:25we'll only get one object, the very last one on the pipeline
22:27since it will just keep overriding,
22:29and then we're going pass as the input object here the full name
22:32of the file, which will just give us the path.
22:35So the end result will be this huge log
22:38file full of paths to exe's that were created this year.
22:42And by the way, these begins and ends
22:43are great for pre processing, post processing,
22:45and in this case, we're just going
22:46to mark the time so we'll know exactly how long it
22:48took to run this command.
22:50All right.
22:50Here we go.
22:51Let's highlight this whole command and let's
22:53just run that selection.
22:55And you can see it started there right now.
22:57So here was our Begin parameter, just spit out the current date.
23:02And now it's running.
23:03We've got a couple of errors in here.
23:04I'll show you how to deal with errors in the future.
23:06We've got a couple of access denied errors here
23:08on specific paths.
23:10But notice one thing.
23:11It's running right now in the background
23:12because we didn't hit that end yet.
23:14And we'll know it's done when we get a time
23:17stamp down here at the bottom.
23:19All right.
23:19Now, it's done.
23:20So it took about 34 seconds to run.
23:21So now we can start the name of our log file here and that was
23:24exe-log.txt.
23:27And there it is.
23:28Look at that.
23:28All of the files, all the exe's that were created
23:33on this machine in this year.
23:34Now, while we're on the topic of pipelines,
23:36I wanted to show you a very, very useful parameter here
23:38called passthrough.
23:40A lot of the times when you do something to an object
23:42and you don't actually output it like we
23:44did here where we actually sent that information to a log file,
23:47it didn't output anything except the beginning and the end.
23:50Well, the same thing is going to happen here.
23:52What's going to happen is, we're going
23:54to get a listing of all read-only text files
23:56and I made two of them here, by the way.
23:57I got one inside of documents called SomeData and I made one
24:01in the Test directory we made called TestData.
24:02These are bookmarked as read-only files.
24:05So if we just run this, it should just
24:07return those two files.
24:08So then what we're going to do is,
24:09we're going to pipe those files to RenameItem because we're
24:12going to rename all the read-only files on our system
24:14tag them with -ro.
24:15So RenameItem, we're going to specify
24:17new name and the new name is going
24:18to be whatever the current name is plus add ro.txt
24:21on the end of it.
24:22Now, if we run this without passthrough,
24:24what's going to happen is it is going to run.
24:26It's going to rename those files, but look,
24:28we don't get any results back, so we
24:29don't know which files were changed
24:30and that's where passthrough is incredibly useful.
24:33Because if we do that same thing,
24:33it's going to do it again.
24:34It's just going to append another ro.
24:36In fact, let's just see if that worked.
24:37Yeah, it did.
24:37There we go.
24:38There's a -ro on it.
24:39But if we do this again only this time specify passthrough,
24:41we're going to actually get to see those results because it
24:44kept those objects in the pipeline.
24:46So once they hit the end of the pipeline,
24:48the default out formatter brought them to the screen
24:52here.
24:52So that's where passthrough is useful.
24:53When you're troubleshooting and developing pipelines
24:55and you still want to see the objects that
24:57went through the pipeline, add passthrough to it.
24:59You'll be able to see it.
25:00All right.
25:00Let's move on and take a look at our challenges for this Nugget.
25:03Number 1, examine the object members
25:05returned from Get-Process.
25:06That should be pretty straightforward.
25:08Number 2, write a pipeline to get processes
25:10where CPU utilization is greater than 0.
25:12Return properties not shown in the default view
25:15and sort the results by CPU descending.
25:18That one shouldn't be too bad either.
25:20Number 3 though, this one's a little tricky.
25:21So write a pipeline to find all GPG and PNG
25:24files created on a drive in the last 24 hours.
25:28Copy them to another directory named Backup.
25:30A lot of steps involved here.
25:32That's why I give you a little help with these steps.
25:34But you'll be using Get-ChildItem as well as Where,
25:36as well as ForEach to loop through.
25:39So good luck.
25:40The answers are, again, underneath the regions
25:42and you can find all these files and challenges inside
25:44of the Nugget Lab files, downloadable
25:46on the right-hand side of the course page.
25:48In this CBT Nugget, we covered objects.
25:50We saw that objects are really just a live representation
25:53of something.
25:54They contain properties, which describe
25:56the object, that's the data stored for that object.
25:59They have methods, which are operations
26:00the object can perform and they have
26:02events, which are things that can happen to that object.
26:05We also saw that commandlets return objects as output
26:08and can accept objects as input and it's how PowerShell passes
26:12data across the pipeline.
26:13I hope this has been informative for you
26:15and I'd like to thank you for viewing.
Extending the Shell
0:00Extending the Shell.
0:01In this Nugget, we're going to take
0:02a look at how to get more functionality
0:04in the PowerShell.
0:04So how do we get access to more commandlets, providers,
0:07functions, all these components in PowerShell?
0:09The answer is modules.
0:11So we're going to take a big look at modules, what they are,
0:14the different module types, how we can even create and import
0:17modules into our PowerShell sessions.
0:20Let's begin.
0:20So we know PowerShell is pretty good out of the box.
0:22We have a lot of core commandlets
0:23that we can do quite a bit with.
0:25But what if we wanted to manage a specific product?
0:27Say, maybe, SQL Server.
0:29Maybe we wanted to manage our hyper-v environment,
0:31or maybe exchange, or maybe Active Directory.
0:33None of those commandlets come with PowerShell by default.
0:37And how we're going to get them is
0:39by working with modules and snapins.
0:42Modules are really just a package of PowerShell commands.
0:44Commands being everything.
0:46Right?
0:47Commandlets, functions, variables, providers,
0:49all that stuff.
0:50So Microsoft and third-party vendors
0:51can package up all this functionality into a module,
0:54usually targeting a specific product or functionality.
0:56Microsoft, for instance, will look at, again,
0:58how to do hyper-v and Active Directory.
1:00But VMware has modules to manage their products.
1:03And we can even build our own modules.
1:05And then a couple of good use cases
1:06there is if you find yourself writing the same code over
1:10and over.
1:10Maybe you're managing all the disks
1:12across all the machines in your network,
1:13and you're constantly writing the same WMI and SIM commands.
1:16Why not package that up in a module?
1:17That will also give you the added benefit
1:19of being able to share your code with others,
1:21so they can then import your modules
1:23and work with that as well.
1:24So in this course, in going forward,
1:26our focus is going to be on modules.
1:28There's also the concept of snapins.
1:29These are essentially what we had before modules, still just
1:32a package of commandlets and other things.
1:34But there's a lot more manual intervention involved in order
1:37to get these into PowerShell.
1:39They needed to be installed and registered with the system.
1:42So they weren't as easy to distribute as modules are.
1:44Modules are self-contained.
1:45You can literally just get them and copy and paste them
1:48into a directory, and you're done.
1:49No installation, no tie-ins with the system.
1:51So that's why modules are preferred.
1:52And that's why snapins have been going away.
1:54In fact, modules are so easy to distribute and work with,
1:57once we acquire them, we can just copy and paste them
1:59into one of the directories referenced here
2:01in the PSModulePath environment variable.
2:04We'll go over these directories here shortly.
2:06And then, as long as they're in there, whenever
2:08we do one of these three things, they
2:10will get automatically loaded.
2:11Get command against one of the commandlets inside
2:13of that module.
2:14Get help against one of the commandlets inside
2:15of that module.
2:16Or we can use a commandlet that's in that module.
2:20And PowerShell will automatically load it.
2:22And by the way, that automatic loading
2:24is done through an environment variable called PS
2:27module auto-loading preference.
2:29And there's really very few situations
2:30where you'd want to turn that off.
2:32Here are those directories referenced inside
2:34of the PSModulePath by default. And yes, you
2:36can add your own to this environment variable as well.
2:38But here we go.
2:39We've got two of them here.
2:40These are considered user directories.
2:42So you've got home, Documents, Windows PowerShell, Modules.
2:46Pop them in there.
2:47Run a commandlet, or get help, or get
2:48command of that commandlet inside of that module,
2:50and boom.
2:51It will automatically load it for you.
2:52And by the way, the first path here
2:54is for PowerShell version 3 and before.
2:56The second one is for PowerShell version 4.
2:59So Program, Files, Windows PowerShell, and Modules.
3:02They moved the module directory for version 4
3:04for a desire to take configuration purposes.
3:07And by the way, that was put in place
3:08so the Local Configuration Manager component inside of DSC
3:11can access the resources in modules
3:14here on the system, which it may not
3:15have access there if it's stored inside of the user's profile.
3:18The system directory, as we call this one,
3:21is stored in pshome, Modules.
3:22And I'll show you where that translates to here when
3:24we get into a demonstration.
3:26So pop your modules.
3:27Copy and paste them into either of those areas.
3:29And PowerShell will automatically
3:30load them when we do one of these three things above.
3:33The other scenario here is, what if we download our modules,
3:37put them on a file share, put them inside
3:38of some directory that isn't stored in PSModulePath?
3:42In that case, we would need to use the import module
3:46commandlet to bring that module into memory, in which case
3:49that module will be available for that PowerShell session,
3:52or unless somebody explicitly removes it from memory
3:55using remove module.
3:56So we've got a handful of commandlets
3:58here to work with in PowerShell.
3:59We've got Get-Module.
4:01Get-Module by itself will show us
4:02all of the current modules loaded in your session.
4:05You can also use the list available
4:07switch parameter here, which will give you
4:09all the available parameters, loaded or not, in your session.
4:13We can also use Import-Module, as we see.
4:15That's what we'll use to load modules up manually.
4:17We can create our own New-Module.
4:19This is going to create a dynamic module, which
4:22only exists in [INAUDIBLE].
4:23And we'll talk about that one shortly.
4:24And then we also have Remove-Module,
4:26which is going to unload it from the current session.
4:28Now, there are different kinds of modules out there.
4:30Let's go over the ones that you're
4:31going to come across out there in the wild.
4:33So we've got the script module.
4:34This is actually a PSM1 file extension.
4:37And this is just a module built using PowerShell code.
4:40So it's going to be great for, again,
4:41code reuse and code sharing.
4:43And I'll show you how we can create our own module using
4:46PowerShell code, import it into our session, and work with it.
4:49The second one we have here is a binary module.
4:51And again, this is what developers
4:52are going to build using the dot net framework.
4:54So they'll compile all that code into what
4:55we call an assembly, which is, more often than not,
4:58going to take the shape of a DLL file,
5:00that we can then put into one of these directories,
5:02and load up, and use those commandlets inside
5:04of PowerShell.
5:04We also have something known as a manifest module.
5:07Now, this is a PSD1 file.
5:09And that stands for PowerShell Data File.
5:10It's literally just a text file with a hash table
5:13of keys and values.
5:14And what this is going to allow us to do
5:16is describe the contents of the module
5:17and give us a little control over how
5:19that module is processed.
5:21And just to give you a few examples,
5:22we can describe it by specifying an author, a company, copyright
5:26description, all those fun things.
5:28But we can also set up system requirements and dependencies.
5:31So we can specify the minimum version
5:32of PowerShell, the minimum version
5:34of the dot net framework.
5:35And we can also customize users' environment.
5:37There's actually a key in there called scripts to process,
5:40where we can pass in a bunch of scripts that will get processed
5:42prior to importing the module.
5:44And there's a bunch of other things
5:45you can do in here as well.
5:46But I also want to mention, in order to get specific features,
5:48you will need to define a manifest module.
5:50So if you want to support updatable help, for instance,
5:53then you'll have to have a manifest module associated
5:55with your module.
5:56And by the way, you can generate these using the New hyphen
5:59Module Manifest commandlet.
6:00There's also a Test hyphen Module Manifest commandlet
6:03that you can use to test them out.
6:04The last type of module we have here is a dynamic module.
6:07And this is a module that is, again,
6:09created entirely in memory.
6:10So there's nothing persistent it is, no physical file to manage.
6:13And it's, again, created from the New-Module commandlet.
6:15Now, these will be good if you still
6:17want some kind of code reuse, but you don't necessarily
6:20need to share that code with others.
6:22We can wrap some of those utility functions
6:24inside of a module, load it up in our session,
6:26and call it from multiple places.
6:28With that, why don't we jump into the Virtual Nugget Lab?
6:30And you can get some hands-on experience
6:32working with modules.
6:33Welcome back to the Virtual Nugget Lab.
6:34Now, the first thing I want to do
6:35is just get you familiar with some module basics here
6:37in the Shell.
6:38And then I'll show you how to install new modules, where
6:40you can find new modules.
6:41And we'll even create our own module.
6:43So we have ourselves a fresh PowerShell session here.
6:46And what I want to do is just start by running Get-Module.
6:48Again, this shows all the currently
6:49loaded modules in the system.
6:50There's only one right now.
6:51And it contains all those core commandlets.
6:53You can see this is actually a manifest module.
6:56Now, let's do something like run Get-Service.
6:59Hey, that worked.
7:00So we know that it's loaded.
7:01But you want to know something interesting?
7:02If we still run Get-Module, we can
7:04see we have the same exact module loaded.
7:07And now, if we run a Get-Command on Get-Service, watch this.
7:11Look at the module name, Microsoft
7:12dot PowerShell dot Management.
7:14Name, Microsoft dot PowerShell dot Management.
7:16And so we know that Get-Service lives inside of that module.
7:18All right.
7:19Let's clear to screen here.
7:20Let's run Get-Module.
7:21Only this time, let's use the list available switch.
7:24So what this will do is show us all the modules
7:26available in the system that PowerShell
7:28can see inside of those directories
7:30that we were talking about.
7:31And look.
7:32It's got access to all kinds of modules in here.
7:34In fact, look at that, Active Directory.
7:36Now, this wouldn't be in a standard installation,
7:38because I actually added Active Directory myself.
7:41And I'll show you a couple of ways to do that.
7:43But as we scroll down here, we can
7:45see we've got a lot of modules available to us on the system.
7:47Where do they live?
7:48This is where the environment variable PSModulePath
7:52comes into play.
7:53So if we look at this, here are those paths
7:55I was talking about.
7:56So here is my profile, Documents.
7:58Here is the Program Files, Windows PowerShell, Modules.
8:02So this is the version 4 directory.
8:04This is the version 3 directory.
8:06And then here is the system directory, Windows System 32,
8:08Windows PowerShell, v1.0, Modules.
8:10Pay no attention to v1.0.
8:12It's always been like that.
8:13All right.
8:14Let's pick one out of this list that's available
8:16and watch the auto-loading magic work.
8:18So let's take-- SmbShare, here we go.
8:21Let's do a get-smbshare to see all the shares on this machine.
8:25There they are.
8:26Now, let's run a Get-Module.
8:28Hey, hey.
8:28Look at that.
8:29SmbShare is now loaded.
8:30Pretty cool.
8:31Right?
8:31Now, what if we wanted to unload modules?
8:33Let's do a Get-Module.
8:34Remember, that's all the currently loaded modules.
8:37And let's just pipe that to Remove-Module.
8:39Boom.
8:39And now, if we do a Get-Module, we've
8:42got absolutely nothing loaded.
8:44But what if we do something like this?
8:47Run it again.
8:48It's loaded now.
8:48How come?
8:49Because the last time we ran Get-Module
8:51it loaded this module up in order
8:54to display all the currently running modules.
8:56Cool.
8:57All right.
8:57I think you get the point.
8:58Now, one more thing.
8:59Just a little quiz for you.
9:01What are the three ways that a module will get auto-loaded?
9:04Remember, that PS module auto-loading preference must
9:07be on, which it is by default. So no worries there.
9:10But the three ways, again, were to run help
9:11against any commandlet in module.
9:13So we could do help get-adcomputer, for the Active
9:16Directory module.
9:18That's one way.
9:19The other way was Get-Command.
9:20Right?
9:21So get-command, again, get-adcomputer.
9:24We'll do the same thing.
9:25And then the third way was to just use the commandlet.
9:28So get-adcomputer.
9:30Now, just because we already did a couple of those,
9:32we can do a Get-Module.
9:33And guess what's loaded.
9:34There it is, Active Directory.
9:36So the big question, how did I get those Active Directory
9:38commandlets inside of my PowerShell session?
9:41And the answer is for things that
9:43are built into the operating system, like hyper-v
9:45and Active Directory, on the server side,
9:47you generally just go to the Roles and Features Wizard.
9:50On the client side, you can just go to the Windows features
9:53on and off area and enable them.
9:55And just to give you an example here, we're in Windows 8.1.
9:58So let's just do a search here for Windows features.
10:00Here we go to Turn Windows Features On and Off.
10:02And we'll head down through here.
10:04Actually, here we go.
10:04Hyper-v, right there.
10:05If we expand this, expand management tools,
10:07there it is, the hyper-v module for Windows PowerShell.
10:09So if we check this and hit OK, what would happen
10:12is it would plant and install that module right
10:15into PowerShell's home directory, the system directory
10:18there that we were looking at, which
10:19means we wouldn't have to do anything but do this,
10:21and then just do a Get-Command to find
10:23some hyper-v commandlets and run a help
10:24on one of those commandlets.
10:25And that module will be automatically loaded
10:27and available.
10:29And if we scroll down here to Remote Server Administration
10:31Tools on a client OS, there it is.
10:34And you can see here under Role Administration AD DS and AD
10:38LDS, there it is, Active Directory
10:39module for Windows PowerShell.
10:40It's already installed.
10:41So that's what I did.
10:41That's all I did to get that Active Directory functionality
10:44here in PowerShell is installed this.
10:46And I should mention, if you're on Windows 7,
10:48you will need to explicitly download RSAT for Windows 7.
10:52Just do a Google search for that.
10:54Download, and install that.
10:55Then go into Windows Features, turn it on,
10:56and you will have the Active Directory
10:58module available to you on your Windows 7 PowerShell installs.
11:01Now, on the server operating system,
11:02let me show you where that is.
11:03Let's go over to FS Nugget.
11:04This is our file server.
11:06Pop open Server Manager.
11:07Drop down Manage here.
11:09Add Roles and Features.
11:10And let's just rip through this wizard real quick.
11:13But if we head down to Features here,
11:14let's go ahead and find Remote Server Administration Tools.
11:17They're somewhere in here.
11:18Here they are.
11:19There they are.
11:20There's AD DS.
11:22And there is the Active Directory module
11:23for PowerShell.
11:24So this is how you can do it on server OSs.
11:26So that's good for things that are built into Windows.
11:28Right?
11:29But what about things that are outside of Windows?
11:31Now, for the most part, just executing a simple Google
11:33or Bing search for whatever you're looking for
11:36will get you in the right direction.
11:37But just to give you a couple of places to get started,
11:40here are some common resources for finding modules.
11:43gallery.technet.microsoft.com is a great place.
11:46If you scroll down on the left here to Tags,
11:47just hit PowerShell.
11:48Look at that, 2,700.
11:49There's also lots of PowerShell scripts.
11:51But if you hit this there's tons of modules and scripts
11:56and code snippets and everything.
11:57So here's a Windows Update PowerShell module,
11:59for instance.
11:59And you can see there's lots of good ones in here.
12:02Another one is poshcode.org, a user-driven repository.
12:05You can even upload your own stuff here
12:06and get the same results.
12:07In fact, they actually give you a PoshCode module here.
12:11So if you right-click on this, save the link as,
12:13you'll get your PSM1 file.
12:14In fact, let me just click on this and open it up.
12:16And this will give you a couple of commandlets here
12:19for upgrading, for getting PoshCode,
12:22search for and download code snippets, new PoshCodes,
12:24so you can upload your own, and then
12:26Get-Webfile to download specific ones.
12:28So those are some good ones there to get you started.
12:31Now, what about creating and importing our own modules?
12:34Let's go over it.
12:35It's pretty straightforward.
12:35Just a couple of gotchas here that I
12:37want to walk you through.
12:37So let's minimize the console here.
12:39And let's head into the ISC.
12:40I've got our commands.ps1 file opened up,
12:42all the commands we're using here in this Nugget.
12:44So we just went through all this stuff here.
12:46Now, we're going to go through some of the bottom ones here.
12:48And let me just show you where these
12:49are in our NuggetLab files.
12:51So let's head over to our file server here, psv4.
12:54Here is the directory containing all of our code here for this
12:58Nugget, 08 extending shell.
13:00And we've got commands.
13:01We've got our challenges.
13:02And then we've got our module.
13:04So the big trick here with creating your own modules
13:06is they must exist in a directory that
13:08has the same name without the dot PSM1 file extension.
13:12So we've got our car directory here ready to go.
13:14And I've got our cars.psm1 file open.
13:17So I saved this as a dot PSM1 file.
13:19And that is telling PowerShell that this is a module.
13:22And here we just have a couple of simple functions
13:24with no implementation in them.
13:26We've got new car with some parameters here-- Get-Car,
13:28Set-Car, and Remove-Car.
13:29And we're also exporting the module members.
13:33These are all functions.
13:34So we use the function switch here and specify
13:37which ones we want to export.
13:38So this is going to make them visible-- in other words,
13:41usable-- from the module.
13:42When we import this module and try to work with these,
13:45and we run a Get-Command, it's not
13:47going to show these other car commands-- New and Remove.
13:51We'll consider these private functions.
13:53So only we'll be able to use these inside of the modules.
13:56These we're exposing to the outside via export module
13:59members, the gets and sets here.
14:00All right.
14:01So we've got our module.
14:02And we've got it sitting in our file server.
14:05So how could we automatically import this module?
14:08You guessed it.
14:09We would need to copy this directory here
14:11to one of the locations in PSModulePath.
14:14So let's head to our commands file here.
14:16And the first thing I want to do is just show you
14:17how to do it automatically.
14:18And then I'll show you how to do it manually using
14:20Import-Module.
14:21So what we're going to do first is copy item, which
14:24is going to copy this directory from our file server, our car
14:26directory that contains our car.psm1 module,
14:29over to our user directory, Program Files,
14:32Windows PowerShell, Modules.
14:34So let's just copy it over.
14:35Just hit F8 to run that.
14:37And let me just go into that directory
14:39here just to show you and double-check that it did,
14:42in fact, go in there.
14:43So Program Files, PowerShell, Modules.
14:46There's our directory, car.psm1.
14:50Now, what if we run a Get-Command?
14:51We know that module's in there, so automatic loading should
14:55happen, because our preference, by default, is on.
14:58So let's execute this line.
15:00And look at that.
15:00It found it.
15:01And now it should also be loaded,
15:02because if we do a Get-Module here, look at that.
15:05There It is, our car module loaded up and ready to go.
15:09We can also do a Get-Command.
15:11And we can pass in the noun of car.
15:14And we should get both of them.
15:16Let's do that the manual way.
15:17So what we're going to do here is remove the module.
15:19It's unloaded from memory here.
15:21So now if we do a Get-Module, it's not in there.
15:23No more car.
15:23And then let's just remove that item completely
15:26with the recurse parameter.
15:27That way, it'll remove the directory as well as
15:30our module.
15:31It's gone.
15:31Now, let's say that we wanted a module directory
15:35living in our file server where all our modules are.
15:37And we wanted that to stay there.
15:39A couple things we could do.
15:40Number one, we could add this path to our PSModulePath.
15:44So it would get auto loaded.
15:46Or we could run an import module and do it manually.
15:49Now, if we're going to do any sort of importing of modules,
15:52you need to set your execution policy to a value that
15:55will allow you to do so.
15:56We'll get more into this when we talk about getting
15:57started with scripts.
15:58But essentially, this is going to get treated as a script.
16:00And we won't be able to do it unless we set our execution
16:03policy.
16:03So I'm going to do that.
16:04And I'm going to hit Yes here.
16:05And now, we should be able-- well,
16:07just to prove the point that car isn't here,
16:09if we run a Get-Command, it's going to say, nope, sorry.
16:11We can't find it anywhere, because we didn't add this path
16:14into our module path, nor did we copy this over,
16:17like we did before.
16:18So now, we're just going to run an Import-Module,
16:20specify that in directory.
16:21And now, it should be manually imported.
16:23And now, we should just be able to run
16:25a help or any of those other two methods to load them up.
16:29And if we run it, check it out.
16:30There's help for Get-Car.
16:31And I should mention you can write your own help
16:34files for your modules.
16:35And I'll give you the link.
16:37It's very simple.
16:38We don't really need to go into it, because it's not
16:40very complex at all.
16:41But I will give you the link so you can check that out
16:43on your own.
16:44All right.
16:44So there's a good look at how modules work here
16:46in PowerShell.
16:47Let's finish this Nugget up with a look at your three challenges
16:50for extending the shell.
16:51Challenge number one-- and a lot of this stuff we've done here.
16:53So it should be pretty straightforward.
16:54Challenge number one, view a list of loaded modules
16:57and then a list of available modules.
16:58Use the autoloading feature to load a module that is currently
17:01unloaded.
17:02Challenge number two, create a simple script
17:04module-- psm1 file-- save it outside of the PSModulePath,
17:07then import and load it into a session.
17:10So you'll be using Import-Module to do that.
17:12And challenge number three, download a module
17:15from the internet.
17:15Add it to a PSModulePath directory.
17:19Get help on a commandlet in the module,
17:21and view the loaded modules.
17:23And here, again, are some of those resources
17:25that we looked at.
17:25So find something on there that you would find useful.
17:28Download it.
17:29Add it to the PSModulePath, and then use it.
17:32And again, you can find the answers here
17:34underneath these regions.
17:35Just expand those, and you'll find
17:36the challenges dot ps1 file in the directory
17:39for this Nugget in the Virtual Nugget Lab files.
17:42And as always, good luck.
17:43In this CBT Nugget, we saw how to extend the shell.
17:46We saw that a module is a deployable unit in PowerShell.
17:49We can download other people's modules.
17:51We can create our own modules.
17:52But they're really just packages that
17:54contain all of the components in PowerShell that we can use.
17:57So commandlets, functions, providers, variable scripts,
17:59all that stuff we can package up into a module.
18:02So it's PowerShell's deployable unit.
18:04And what makes them so awesome is that there's no installation
18:08or registration.
18:08It's just a simple copy-paste somewhere.
18:10And then we can either automatically
18:12load it or, as we saw, use Import-Module to manually load.
18:15We also saw here how to create our own modules.
18:18I hope this has been informative for you.
18:19And I'd like to thank you for viewing.
Extending Objects
0:00Extending Objects.
0:01So we've seen that PowerShell is extensible from the outside,
0:05and that is we can bring in more functionality in the form
0:07of commandlets and such through modules.
0:09We can import and load them into our session
0:11and start working with them.
0:12Well, PowerShell's also extremely
0:13extensible from the inside, meaning
0:15we can add our own members, properties,
0:17and methods to types and objects here within PowerShell.
0:20Now this is a great productivity feature
0:21that's going to allow us to create our own shortcuts
0:24and reduce the amount of typing when writing commands,
0:26especially if you see yourself writing a lot of the same stuff
0:29within your commands.
0:30Just to give an example of that, let's say
0:32that we are always working with files here in PowerShell,
0:35so we're running dir or get ChildItem
0:37to pull back a list of files which are,
0:38by the way, FileInfo objects.
0:41And these FileInfo objects expose a length property.
0:44But guess what, that length property, it's in bytes.
0:47So if we want to work with megabytes or gigabytes
0:49or whatever bytes, we would then need
0:51to pipe these objects to maybe a select or aware
0:55if we're doing filtering, and then write our own customer
0:57expression to convert that to gigabytes, or megabytes,
1:00or whatever have you.
1:01Wouldn't it be great if we could just
1:03wrap all of this inside of our own custom property called
1:06length megabytes or length gigabytes, and going forward,
1:10we only need to work with that property
1:12rather than write all that extra code to convert it.
1:15So extending objects is a great way
1:16to get PowerShell to work for you,
1:17and that's just one of the many benefits.
1:19So let's jump in and we'll dig in
1:20to see how PowerShell makes this possible.
1:22We'll also get familiar with all the different types of members
1:25that we can add, and then we'll get into demonstration
1:27to show you how to do.
1:28Let's begin.
1:29So in a previous Nugget I said that PowerShell is really
1:31just dot Net framework for administrators.
1:33And while that isn't entirely false,
1:34it's also not entirely true, because PowerShell
1:37can work with many, many, many underlying object frameworks.
1:41And this is all due to something known as the Adapted Type
1:43System.
1:44So while dot Net gets all the glory
1:45because that is where most of the awesome is,
1:48other object frameworks such as COM, ADO, WMI, CIM as well as
1:52XML have been mapped into PowerShell as well.
1:55And it's all done through this common layer
1:57known as PS Object.
1:59So developers can write adapters that map these underlying
2:02frameworks into a PS Object, which
2:04is really the base for all objects here in PowerShell.
2:07PowerShell also has an Extended Type System,
2:09and this is what's going to allow us to dynamically add
2:12our own members, properties, and methods to PowerShell types
2:15and objects.
2:15For example, let's say that we ran
2:17the get AD Computer commandlet from the Active Directory
2:20module, and we got back a bunch of computer objects
2:23representing Active Directory computers.
2:25We could extend that object, add maybe an IP address property,
2:29and maybe a ping method.
2:31That way, we wouldn't have to pipe this to other things
2:33to do that they would just be built
2:34in right onto that object.
2:36And I'll show you how to do that here when
2:37we get into our demonstration.
2:38So the big takeaway here, just remember that type adaptation
2:42is what allows developers to map other object
2:44frameworks into PowerShell.
2:46Type extension is what we're going
2:48to use to add our own members onto existing PowerShell
2:51objects.
2:52Let's take that a step further and look at the kinds of ways
2:55that we can extend our objects.
2:57So we have what are known as member types,
2:59and we've seen these when we ran Get Member in previous Nuggets.
3:02Let's go over them now.
3:03Let's start here with Alias Property.
3:05So this is very simply just a new property with another name
3:08on top of an existing property.
3:10In fact, let me bring up PowerShell
3:11and give you a good example of this one.
3:12So if we do a Get Service and pipe it to Get Member,
3:14and we head up to the top here, here's two alias properties,
3:17so name is an alias for service name,
3:20a little less typing there.
3:21And required services is an alias for services depended on,
3:24a little more readable and understandable,
3:27required services than services depended on.
3:29So that's generally what we use alias properties
3:30for make it a little easier to read
3:32it a little easier to type.
3:34No Property is just a property with a static value.
3:36Script Property is a property with PowerShell code behind it,
3:40and a Script Method is the same thing, a method
3:42with PowerShell code behind it.
3:44And then Code Properties are really
3:45just properties and methods that sit
3:47on top of statis.net methods or static.net properties.
3:51Most of the time you'll be using Script Properties and Script
3:54Method, so we'll be writing PowerShell code to extend
3:57our PowerShell objects.
3:58And we'll take a good look at how to create these here
3:59shortly in our demo.
4:01Now there are many ways to extend an object
4:03with these member types and, again, we'll
4:05go over all these different methods here
4:07in a demonstration.
4:07But the first one here we've done in previous Nuggets.
4:10Pass a hash table to select-object.
4:12We give it a name.
4:13We give it an expression and essentially it's
4:14a way to create a calculated property on the fly.
4:18But do note that this is really only good for display purposes,
4:21because it will convert that original object to a PS custom
4:24object, so if you try to pass it further
4:25down the pipe to something that expects a specific object,
4:29you could run into problems there.
4:31Using add member against anything
4:33is a great way to add a property or method to an existing
4:37object.
4:38Take a look at how to do that.
4:39Using new object to extend the PS object.
4:42This is how we create our own PS custom object.
4:44So for example, if you wanted to create your own computer
4:46object, and you didn't want to use the AD Computer object,
4:50then you create your own from scratch,
4:52fill it up with properties and methods and utilize it.
4:54Show you how to do that.
4:55And then not extend types using Update Typedata.
4:58This is great, because while Add Member
5:00is good for a single instance or are single variable containing
5:03a collection of your objects, Update Typedata will actually
5:06update the types or adding it to the actual type itself,
5:10meaning that any objects we spawn off that type
5:12will automatically have those extended properties and methods
5:16in them.
5:16With that, why don't we jump into the Virtual Nugget Lab
5:19and take a look at how to utilize PowerShell's Extended
5:21Type System.
5:22Hey, welcome back to the Virtual Nugget Lab.
5:24So one thing I wanted to do real quick before we
5:26jump into the ISE and I show you how to extend objects is just
5:29show you one little neat thing here with Get Members.
5:31I'm just going to pipe Get Service to Get Member,
5:33and I wanted to show you this view parameter.
5:35This is useful because it allows you to see things
5:37like adapted members, base members,
5:41that that's how the dot.Net framework sees the members.
5:43Adapted is how the Adapted Type System sees the members.
5:45Extended is another good one, because it allows us just
5:48to see the extended members to the ETS, the Extended Type
5:51System here.
5:52This is where all of your Alias Properties, Note Properties,
5:54Script Properties, Code Properties, Script Method,
5:56and Code Methods would show up.
5:58So that's useful for seeing how these numbers look
6:01from different perspectives.
6:02All right, let's jump in to the ISE.
6:04So let's look at the many ways we can extend an object
6:07and work with those member types.
6:08We're going to be utilizing Get WMI Object,
6:10and we haven't gotten into WMI or CIM yet.
6:12We will down the road.
6:13But by passing in Win132 operating system,
6:15it's going to give us a bunch of great information
6:18about our local machines operating system and beyond.
6:20So I'm just going to highlight this code just
6:22to show you what we get here first,
6:24and then we'll put it into a variable
6:25and see some of the things we can do with it.
6:27So look at this, a lot of great information
6:28here such as the operating system, which
6:30is known as caption in here, which would probably
6:33be a great idea for an Alias Property
6:34because caption is kind of silly.
6:36Why not call it operating system?
6:37But there's a lot of other information in here,
6:39but let's say that we're missing something.
6:41Maybe we wanted this to also have the IP
6:43address of the local machine.
6:45Well, we could do something like this.
6:46We could do a select and pass in an expression
6:50here by giving it our hash table with name
6:53of the property and the expression
6:55being a commandlet to extract the IPv4 address
6:58of this machine.
6:59So that's one way to do it.
7:00And by doing that, check it out.
7:01There's a computer name, there's caption,
7:03and there is the IP address is here of this local machine.
7:07So that's one way to do it using select object.
7:09Now next up we're going to work with Add Member
7:11and, again, Add Member's going to be the preferred method
7:12of doing so, because we're going to be
7:14able to work with these methods and properties, these members,
7:17later on down in our script, where Select Object is
7:19good for just adding them on the fly to create
7:21calculated properties.
7:22So the first thing we're going to do
7:23is add a Script Property just as we did above, only we're
7:26going to break it out here.
7:27So if we pipe our variable to Add Member passing the member
7:30type being a Script Property, passing the name just as we
7:32did above in our hash table here,
7:34it's going to be the name of the property.
7:35And then the value of the property
7:36just as we had in our expression up here
7:38is going to be the same.
7:38It's going to be the Get New IP address commandlet,
7:40pass in the parameter of our address family of IPv4.
7:44So if we run that, we have now just added this member
7:47physically to the object, if we run a Get Member,
7:50we should see it down here at the bottom.
7:51Check it out.
7:52There's our Script Property.
7:53There's the definition, and there is the name.
7:55And now we can work with it like it
7:56was a real property on the object
7:58because it is a real property on the object.
8:00So that's a Script Property just PowerShell code
8:03inside of your value.
8:05What about an Alias Property and Note Property?
8:07Again, Alias Property is a great way
8:08to rename something just as we're
8:09going to do here with Caption.
8:11We're going to add an Alias Property using Add Member,
8:13so the member type is going to be Alias Property.
8:15Give it a name operating system, and the value
8:17is going to be caption.
8:18So that's the field that we're referencing.
8:20So it'll make it a little easier to understand.
8:23And then the second one will do for service packs.
8:25So we'll rename service pack major version
8:27to just service pack, which will reduce
8:29the amount of typing we have.
8:30And then the third one we're going to add here
8:32is a Note Property called department, which again,
8:34for static value.
8:35We'll just add the static value there PSOps.
8:38So by adding these three members to it,
8:41now if we pipe this to Get Member,
8:43we should see all of them.
8:44And these are in alphabetical order by member type.
8:46So up top here we'll have our two Alias Properties.
8:48There's operating system, there's service back.
8:50Here's our Note Property here in department.
8:52And then down at the bottom, we should have our Script Property
8:54that we just previously created in our IPv4.
8:56So we've got all of our properties
8:58in here that we made so far.
8:59And now we can just pipe all this
9:02to select to pull out these specific properties, all
9:05of them that we've created thus far, and they're there.
9:08What about a Script Method?
9:10Let's say, again, that we wanted to add some ping functionality
9:14to our object here.
9:15We're going to pipe, again, our variable to Add Member.
9:17This time we're going to specify Script Method.
9:19We're going to give it the name ping,
9:21and then our value's going to be connection.
9:23Our computer name is going to be this, dotPScomputername,
9:27which is referencing the property
9:28on this current object.
9:30Now the only caveat here that you need to be aware of, is
9:32when you're defining Script Methods,
9:34you cannot use the dollar sign underscore placeholder you need
9:37to use this for the placeholder rather than that.
9:41All right, so for anything Script Method
9:43or Script Property-related, keep that one in mind.
9:45So let's go ahead and highlight all this.
9:47And by the way, the ForceOne will override it
9:49if it's always there.
9:49Just want to throw that in there,
9:50because if you're doing this and your testing,
9:52and your testing, and your testing,
9:54and you run this without Force, you'll
9:55get an error that that property already exists.
9:57So use Force to overwrite any existing property or method
10:01member as we call it.
10:02So let's run this one.
10:04Let's hit Execute, and now we should
10:05be able to just doing an OS ping,
10:08and that will ping this machine.
10:10There it is.
10:11And again, if we pipe our variable here to Get Member,
10:14we will now see we should have a pink Script Method right here.
10:19There it is.
10:19Cool.
10:20So that's how we use Add Member.
10:21Now let's take a look at another one here.
10:23This is a cool one.
10:24How about New Objects?
10:25Say you wanted to create your own custom
10:26objects from scratch.
10:27Let's do that.
10:28Let's create our own PC object here.
10:30So we're going to create a variable called PC.
10:32We're going to use the New Object commandlet.
10:33We're going to pass in the type that we want to work with.
10:35We're going to create a brand new PS
10:37object, which is going to give us a PS custom
10:39object from scratch.
10:39Then as the property parameter, we're
10:41going to pass in a hash table defining
10:43all of our initial properties.
10:44So we'll have a user in there, which
10:46is going to pull the username is currently logged in,
10:48and we'll send that to lower.
10:49The machine's going to grab the computer
10:51name that I'm currently on and send that to upper.
10:53We'll get IPv4 in here again, which we're
10:55going to call that commandlet.
10:56We're going to get the operating system you're using
10:57CIM rather than WMI this time.
10:59We'll pull the caption off of that.
11:01And then we'll get the service pack,
11:02which will pull the service pack major version again off
11:04of there as well.
11:06So by doing this, we're going to have our own object,
11:09our own brand new object.
11:10In fact, if we just pipe this all to Get Member,
11:13let's do that.
11:14We can see the kind of object that we're working with.
11:15Check it out.
11:16There it is.
11:16PS custom objects.
11:17We get all those base members, and then we get the ones
11:20that we added in here.
11:21Right now, those are all added in as Note Properties.
11:23Now let's make things a little more interesting here.
11:25Now the first one isn't very interesting.
11:26We've done this.
11:27We're just adding another Note Property here called
11:29department, put a static value in there.
11:31But these next couple of lines are very interesting.
11:33So we're going to create a service variable,
11:35and we're going to store in there to the currently
11:37running services.
11:39So Get Service where the status is equal to running.
11:41And then we'll create another log variable,
11:43and we'll say Get Event Log, all the system event logs,
11:45the newest 10 entries.
11:46And then we're going to add a Script Method.
11:49We'll call it Get Running Services,
11:51and we'll pass in that variable.
11:52And we'll do the same thing here for our log.
11:54And then, we'll also add another one
11:56that I haven't mentioned yet, just
11:57to throw in here, called a Property Set,
12:00and we'll call it Stuff.
12:01And we'll get the value of machine OS and SP,
12:03the ones that we recruited above here initially.
12:05A property set is just a way to create a group of properties,
12:08and then you can call that one property,
12:09and you'll get all of the properties associated
12:11with the back.
12:11Again, a nice great productivity feature there
12:13if you find yourself working with common properties,
12:16wrap it into a property set.
12:17Then you can just call that one property instead
12:19of multiple properties in one shot.
12:22All right so let's add all of these into here.
12:25And now, if we come down here and run a Get Member
12:27once again, look at them all.
12:29So we've got our property set, we've got our Script Method,
12:31we've got all our Note Properties that we
12:33were working with there before.
12:34And now just to show you here, we
12:35could pipe this to select stuff and it's
12:37going to give us those three properties that we set up
12:40in that property set.
12:41And if we call a Get Running Services,
12:43it's going to run that method and get
12:44all of the running services as they
12:46were at that point in time.
12:47We can also do the same thing here and run a Get System Logs,
12:51and it would give us the same result,
12:53all the logs that we stored inside of that log variable
12:55that we associated with that Script Method.
12:57So New Object, another really great way
12:59to create your own objects and start building it up
13:01with your own properties and methods.
13:03Now the last method I want to show you
13:04here is extremely useful, because this
13:07is how we extend types rather than objects.
13:09Again, objects live in memory, so as soon as they go out
13:12of memory, we lose them.
13:13We lose all these members that we dynamically added,
13:16and we need to reconstruct them any time
13:18we run the script, which may or may not be a big deal.
13:20But this could be a huge time saver,
13:22especially if you're doing something
13:23like we're going to do here.
13:25Let's say that you're always working with daytime objects,
13:28and you have a big need to work with quarters,
13:30maybe for reporting purposes or whatnot.
13:32Well, guess what?
13:33Quarter is not a property on Get Date.
13:36In fact, if we run Get Date and pipe it to Get Member,
13:38you can see that there's no quarter on here,
13:40so no daytime objects have quarter on them.
13:43So this would be something that if we dynamically
13:45added in anytime we're in daytime objects,
13:48it would equate to a lot of code, right?
13:49But by running Update Typedata, passing in our type name,
13:53and then adding our own Script Property or Script
13:55Method to it, which is what we're going to do here.
13:57Member type, we're going to give the name quarter,
13:59and then our value is just a big if statement to figure out
14:01where the current month is, and then
14:03outputting whatever quarter that month is as the value.
14:07So by doing this we're updating the raw type information,
14:11meaning any object that gets spawned off of this, no matter
14:13where it comes from, will automatically
14:15have quarter on it.
14:17So let's run this, and now no matter
14:20what we do Get Date or otherwise,
14:22anything that has system.datetime as a return
14:25object will have quarter on it.
14:26In fact, we can see this if we just pipe Get Member here,
14:29we should now see quarter down here as a Script Property.
14:32Cool.
14:32And now we can grab the quarter, and we
14:34can see that we are currently in Q4 of this year,
14:37but this is great.
14:38Now the only other thing I want to mention here
14:39is that this is also session-based,
14:41so it's going to live in memory from the time you run this
14:45to the time you close out your session,
14:47so this is another great candidate
14:49for profile scripts, something else we'll
14:51cover later on in the course.
14:52But by putting this inside of your profile script,
14:54you'll never have to worry about it again.
14:55Any time you fire up PowerShell, quarter will automatically
14:58be added to your daytime types.
15:00So that's how we can take advantage
15:02of PowerShell's extended type system
15:04to add our own members to both types and objects.
15:08Let's finish this Nugget up with a look at your challenges.
15:10Challenge number one, view only the extended members
15:13of a System.IO.File Info object.
15:15So here we're going to do is first we need to get
15:17a bunch of FileInfo objects.
15:18How will you do that?
15:19Right, run Dir or Get ChildItem, pass in the file,
15:22switch parameters, so you just get
15:23a bunch of FileInfo objects.
15:25Then pipe all of those to Get Member
15:26and use that view parameter that we were just looking
15:28at earlier in this Nugget.
15:30Challenge number two, extend the System.IO.FileInfo type
15:34to add a custom Script Property for LengthMB.
15:38So this, pay attention to the wording here, type.
15:40What does that mean?
15:41Well how are you going to extend the type?
15:42You guessed it.
15:42Using the commandlet we were just
15:44looking at, Update Typedata.
15:46So again, this is just a great real-world one,
15:49especially if you find yourself writing the same expressions
15:52over and over to generate the same properties.
15:54Why not just add it to the type so it's always there.
15:56Now this last challenge is probably the trickiest one
15:58I've given you yet.
15:58Let's go over it.
15:59You're going to extend the objects returned
16:01from Get ChildItem using Add Member to include
16:03a last written to Script Property that contains
16:06the difference between the current date and the last write
16:08time in the format of days and hours, colon minutes, colon
16:11seconds.
16:11And you're probably like, huh, what?
16:13Here's the idea.
16:14So we've got a last write time on objects, right?
16:16In fact, let me fire up PowerShell here and just show
16:18you.
16:19If we do a Dir against sequel backslash, myDir,
16:24we've got this last write time here.
16:25And we know what the current date is.
16:26So what I want is a property on the end of here
16:28that says the last time this file was written
16:30to in the form of four days, three hours, 15
16:35minutes, and five seconds ago, that kind of format.
16:38So that that's the whole idea here.
16:39Now this will obviously be very tricky if you've never
16:42worked with format strings, but I'll tell you,
16:44it's really not that bad.
16:45It's a lot easier than it seems.
16:47And if you do feel like doing this one on your own,
16:49just do some Google searching for format strings
16:52with the two-string method.
16:53And then if you want to try it on your own,
16:55pause me or close me right now, because I do
16:56want to walk through the solution now,
16:58because I think this is extremely valuable.
17:00It's a great thing to learn, because it will certainly
17:02be something that you come across in PowerShell someday.
17:05So three, two, one, here we go.
17:08Here's the solution.
17:09So what we're going to do is run a Get ChildItem
17:11against a directory.
17:12That's going to give us a bunch of FileInfo and directory info
17:15objects that are going to get stored inside of our variable.
17:17Then we're going to pipe those objects to Add
17:18Member adding a Script Property with the name last written to.
17:21Here's the value.
17:22Here's all the tricky part right here.
17:23Here's all the magic.
17:24So we're going to take Get Date, and we're
17:25going to subtract it from the last write time,
17:27and that's going to give us a timespan,
17:28right, the amount of time from this moment to the last time
17:31the file was written to.
17:32So all we need to do is format that into something friendly.
17:35How do you want to format it?
17:36Days, hours, minutes, seconds?
17:38We're going to do all of those and inside
17:39of the two-string method, you can pass in a format string.
17:42You can format currency, numerics, decimals, dates,
17:45times, everything using these format strings,
17:48extremely, extremely powerful.
17:50So how we're going to format this time span is by doing
17:52a date, so we'll do first day, dd,
17:56and so that's going to give us the length of two there, so 01,
17:5902, so it's going to zero pad it for us.
18:01Then the backslash means the next character is a literal.
18:05So that's where the period comes into play.
18:07So it's going to be date date dot, then our hour, backslash,
18:11colon, minute, backslash, colon, seconds.
18:14And that's it.
18:15Pretty straightforward.
18:16So let's do this.
18:17Let's highlight all this, hit Execute.
18:19And now, if we run this, and I just created a file in there
18:22not long ago, so if we run all of this and hit Execute,
18:25we should get those three files inside of this directory
18:28that I created here called myDir.
18:30Here are those three files.
18:31If we look, we've got the last write time here,
18:33and then we've got the last written to in the format
18:36that we specified there.
18:37So the first one here, 34 days, three hours, 50 minutes,
18:4040 seconds.
18:41Here's what I just created four minutes and 20 seconds ago,
18:43and here's our other one, test, that was created 25 days ago.
18:46Pretty cool.
18:47But see, it's not as bad is it seems,
18:49just a little tricky there with the formatting.
18:51In this CBT Nugget, we saw how to extend the PowerShell
18:53objects.
18:54We got familiar with the adapted and extended type system.
18:57We got familiar with the many different member types
18:59that we can use to extend objects
19:00with, such as Script Method, Script Properties, Code
19:03Method, Code Properties, Alias and Note Properties.
19:05And we also got familiar with the many different ways
19:07that we can extend objects using Select Object,
19:10using Add Member, using New Object,
19:12as well as using Update Typedata.
19:14I hope this has been informative for you,
19:16and I'd like to thank you for viewing.
Formatting Output
0:00Formatting output-- wouldn't it be great
0:02if you had full control over how the PowerShell displayed
0:04objects once you hit the end of the pipeline?
0:06Well, I'm here to tell you that you do.
0:08And that's what we're going to look at in this Nugget.
0:09We're going to familiar with the major format commandlets.
0:12I'm going to get you familiar with the process
0:13that PowerShell goes through for determining
0:16how to display our objects once you
0:17hit the end of the pipeline.
0:18I'll even show you how to control those defaults.
0:20And we'll look at how formatting in the format commandlets
0:23differ from the select commandlets.
0:25Because they feel very similar and you can
0:27do a lot of similar things between them.
0:29All right, let's begin.
0:30So, PowerShell does a pretty decent job
0:32of displaying our objects in a format that's
0:36easy to comprehend.
0:37But sometimes it doesn't.
0:39And that's why it helps to understand how PowerShell does
0:42these things and, of course, understand the format
0:45commandlets.
0:45Because that will give us total control over our output.
0:49Here's how this works.
0:50Now let's say that we were just going to execute a command
0:52and let PowerShell take over from the formatting
0:55perspective.
0:55In fact, let's just do a get-process here.
0:57And let's get all processes that start with W.
0:59Right, now how did PowerShell know to grab these properties
1:04and format this as a table?
1:05Notice this is a table.
1:06We have column headers here.
1:07We have rows inside of here with all the data.
1:09And also note.
1:10That these column headers are not
1:12the property names that live inside
1:15of those process objects.
1:16In fact, if we just piped us to get member,
1:18look-- there is no VM, meaning virtual memory in megabytes
1:23or page memory in kilobytes or working set in kilobytes.
1:26None of these columns, so to speak,
1:29are inside of the actual object, right?
1:32So how did PowerShell know to do that?
1:35That is the formatting system taking over here.
1:37And that's what I want to get you familiar with first is how
1:39PowerShell decides to format.
1:42So it's going to do this no matter what
1:43at the end of the pipeline, right?
1:44We're going to create a pipeline.
1:46We're going to go get some objects.
1:47Maybe we'll filter out a few objects.
1:49And right when it gets to the end of the pipeline,
1:50PowerShell's going to look at a bunch of these format files
1:53to determine what properties are going to get outputed
1:56by default and what format they're going to get outputted
1:59in-- so format being a list view or a table view as we just saw.
2:03So before all of this data gets to the host,
2:06PowerShell needs to figure out how it's going to display them.
2:08And it's going to go through some processing rules here.
2:11Rule number one is it's going to loop
2:13through these files for a predefined view for that type.
2:17Let me give you an example.
2:18Let's bring PowerShell back up here.
2:19Let's get some space to work with.
2:21And by the way, all these format files live inside of pshome.
2:24So let's just do a cd, which is an alias for a set location,
2:27on pshome.
2:28And now let's just do an ls and find anything
2:30with format in the name.
2:32Look at them up.
2:32There they are-- tons of them.
2:34So what I want to do here is, first, let's head to the top
2:36and let's see what type we're working with here.
2:39We know, because we did a get-number,
2:41that the type is System.Diagnostics.Process.
2:43Let me just grab this.
2:44And then we'll copy it.
2:46And then we'll head down to where I was here.
2:49And let's just start.
2:50I'm going to do DotnetTypes because I
2:52know that's where this specific type's view definitions live.
2:55So I'm going to start this up.
2:57All right, now let's go ahead and do a Control-F
2:59and let's find anything with that type.
3:01And now the first one it's going to find here
3:03is actually Process Modules.
3:05Let's do it again.
3:05There it is.
3:06So what it's doing first is it's looking for this view right
3:09here.
3:10See that?
3:10See that view?
3:11This is a view, which is going to pretty much determine
3:15the kind of format it's going to use to output these objects.
3:19And this is a table control, which actually lines up
3:22with what we saw here because, guess what?
3:24That is a table, right?
3:25Rows and columns.
3:26And if we look further into this,
3:27we can see all of these column definitions-- the label,
3:31the width, the alignment.
3:33If we come down, you're going to see there's our working set.
3:35There's our virtual memory in megabytes.
3:37And so this is what's going to override the property names.
3:40And then we head down here, here are the actual mappings.
3:42So we have a script block in here
3:43that defines exactly what it is.
3:45So here's our working set divided by 1024.
3:47It will give us the kilobytes.
3:48And then virtual memory divided by that
3:50will give us the megabytes.
3:51So that's the first thing it's going to do.
3:53It finds it.
3:54Great, it's done.
3:54It outputs it using those defaults.
3:56And that's exactly what we have here with getProcess.
3:59Let's do another one here.
4:01Let's take the file info object here.
4:03If we do a dir file, let's just pipe this
4:05to get member here and head up.
4:07We know that this is going to be a System.IO.FileInfo type.
4:10We've used this one before.
4:11I'm just going to copy that to the clipboard.
4:13And if we head back to our Dotnet types here,
4:15let's just go to the top and let's search for this.
4:17It's not in there.
4:18How come?
4:19Well, that's because there are many format files
4:21and they all get loaded into memory.
4:23In fact, again, if we do an ls here for format,
4:25we'll be able to see that file info is probably in the file
4:28system doc format file.
4:30So if we do-- let's see.
4:32Let's go ahead and just start this up here.
4:35There we go.
4:36And we can see right up here is the definition for directory
4:38info and file info.
4:39And if we scroll down, here is the view definition.
4:41It's also going to be a table, Mode, LastWriteTime,
4:44Length, so on, and so forth.
4:46And that matches up with what we have
4:47here-- Mode, LastWriteTime, Length, so on, and so forth.
4:50All right, so that's step number one.
4:51It's going to look for those predefined views for that type
4:54in all those formats files.
4:55And yes, you can create your own format files
4:58and have total control over the formatting and the output here.
5:01You can create your own format files,
5:02put them in a directory that'll get loaded into memory.
5:04And it will then look for your specific views as well.
5:07And by the way, just think of a view as really
5:09just another layer on top of your objects for formatting.
5:12So you can define those column headings.
5:14You can define the widths of those columns, the alignment
5:16and things I'll show you here once we
5:18get into all the different format commandlets.
5:20Now, what if there is no view for that type?
5:23This is where it's going to take the second step
5:25and it's going to look at the raw type definition
5:27inside of the types.ps1xml file to determine
5:31which properties to output by default.
5:34And to give you an example here, let's just go ahead
5:36and do a Get-wmiObject.
5:38And let's do this for the win32 operating system.
5:41So this is one that has no predefined view.
5:44In other words, there is nothing for this type
5:47inside of the format files.
5:48And what type am I talking about here?
5:49Let's pipe this to get-member and let's grab this right here.
5:55Copy it to the clipboard.
5:56And I know we can go through all the formatting files
5:58and you won't find it.
5:59So what we can do is let's just open up here types.ps1xml.
6:05Again, this is where all the type definitions live for all
6:08the types here in PowerShell.
6:10So if we open this up, and I'm just going to search for that,
6:13we will find this.
6:14And so the second step it's going to do,
6:16then, is look for anything that has a default display property
6:20set, which everything does.
6:21And it's going to use this, then,
6:23to determine the default properties to display--
6:25so system directory all the way down to version, which lines
6:28up with what we have here in PowerShell
6:30when we ran that command.
6:31There it is-- system directory all the way down to version.
6:33So that's how it determines the default properties.
6:35But how does it determine the default format?
6:38List, or a table?
6:39Well that's step number three here
6:41is since, again, we don't have a view defined,
6:43it's going to look at the number of properties
6:45and it's going to say, all right, if it's five or more,
6:48then it's going to put them inside of a list.
6:50If it's less than five, it's going
6:52to display them in a table.
6:54And those are the internal rules that it uses to do so.
6:57And just to prove that here, let's head back to PowerShell
7:01and let's just run GetwmiObject again here.
7:03Only let's just select, how about,
7:06system directory and version.
7:09See that?
7:10Now we get a table rather than a list
7:12because it's less than five properties being returned.
7:16So that's how PowerShell determines internally
7:18how to display our objects once you
7:20hit the end of the pipeline.
7:21Now let's get familiar with these formatting commands.
7:22These are extremely useful to know because it'll
7:25help you customize your output.
7:26So Format-Table, we were just looking at this,
7:29just gives us rows and columns to work with.
7:31Format-List gives us kind of key value pairs
7:33up and down, a property kind of view
7:35where we have the name of the property,
7:36colon, and then the value of the property-- extremely useful
7:39when you're troubleshooting as well here.
7:40I'll show you some neat tricks with that.
7:41Format-Wide is really just used to work with one property.
7:45So if you're working with one property,
7:46it'll list them all in a row.
7:48And we have control over the columns here as well.
7:50I'll give you that.
7:51And then Format-Custom is one of the advanced format
7:53commandlets that allows you to define
7:54your own customized views.
7:57So you can output things any way you can think of.
7:59All right, let's jump into the virtual Nugget lab
8:01here and take a look at how to work with these format
8:03commandlets.
8:04Now, the first thing I want to do
8:04is get familiar with Format-Wide.
8:06But before we do that, let's just do a get-service and let's
8:08pipe this to select and pull out just a single property.
8:11Now, what did that do?
8:12That give us a table with one property.
8:14And that is going to result in a lot of scrolling.
8:17Wouldn't it be better if we could just
8:19format this as a wide here?
8:21So we'll do a format wide which, by the way,
8:23has a property switch on it.
8:24And that's positional.
8:25So we don't technically need to type that out.
8:27And then let's say name.
8:29What's that going to do?
8:30Results in a lot less scrolling because now we
8:32have two columns with that single property inside of it.
8:34In fact, we can even control this with the column parameter
8:37here.
8:37We can say column, give me five columns.
8:39And look at that-- they all are in one nice view
8:41with a lot less scrolling.
8:43So use Format-Wide when you're dealing with a single property
8:46because it makes it a little easier to work
8:48with there on screen.
8:49Now, the next one I want to get you familiar with you
8:51here for Format-List.
8:53So let's do a get-service and let's do a Format-List here.
8:57Put in the property parameter just so you can see it.
9:00Let's do name, display name, and how about status?
9:04All right, there you go.
9:05Look at that.
9:06So there's Format-List, right?
9:07And we didn't actually need to do that because we were
9:10under four properties there.
9:12So we could have just did this in a select object
9:15and we would got them back here as a list anyway.
9:17But one thing I want to show you here
9:19is kind of a neat little parameter
9:21to get used to because this is extremely useful.
9:23And that is group by.
9:25Let's say we wanted to group by status.
9:26And the nice little gotcha here is that didn't work so well.
9:29And that's because it grouped them
9:31as those objects were coming at the end of the pipeline.
9:34They were just getting pushed out one at a time.
9:36So this is why whenever you use group by,
9:38just make sure that you do some sorting here.
9:40So let me head back here-- right here.
9:43And let's throw a sort in here.
9:46Sort by status first and then format it.
9:50And now it's grouped accordingly.
9:52So now I'll get some column headers here.
9:54And there's running.
9:55See that?
9:56And here's all the stopped ones.
9:57So we get some column headers and then all the stopped
9:59services underneath that, all of the running
10:01services underneath that.
10:03So that's group by.
10:04Now, what Format-List is really good
10:05for is when you want to do some troubleshooting
10:08and you want to see all the properties.
10:10Because we could do something like this.
10:11I'm just going to do a get-service here, format list.
10:14And instead of typing out property-- it's positional,
10:16we'll use it-- we can do an asterisk there,
10:18which means it's going to pull out every single property.
10:21And in fact, here-- that was a lot going on there.
10:24In fact, we could probably do something like this here.
10:27We could do a select.
10:29Let's just do, how about first five?
10:33There we go.
10:34And then we'll pipe that there to format list.
10:36And there we go.
10:36Now we get the first five.
10:37But what's great about this is that it's just an awesome way
10:40to do some troubleshooting against your objects
10:42because it shows you absolutely every property
10:44on the object that's getting sent here to Format-List.
10:48So that's Format-List.
10:49The next one we'll look at here, probably
10:51one of the more useful ones and more powerful ones--
10:53we can do quite a bit with this-- is Format-Table.
10:56So let's do a get-service here.
10:58And let's pass that over to Format-Table.
11:00Again, the alias there is ft.
11:03And let's just say property here.
11:05And let's pull out name, display name, and status.
11:09Now, here's the thing.
11:10Look at that.
11:11See what it tries to do by default
11:12is it tries to fill up the entire screen.
11:15Here's where the auto size parameter is extremely useful.
11:19Because what it'll do is it'll just
11:20make sure that every column is as wide
11:24as it needs to be for, of course,
11:26the widest value within that column.
11:28Let's do another one here.
11:29Let's do GSV, pipe that to Format-Table.
11:34We'll do an asterisk so we get everything.
11:35And let's see what this returns.
11:37Woah, look at that.
11:38That's a lot going on there in that table.
11:40Now, any time you see dot, dot, dot, that just simply
11:42means that there is more to be had.
11:45It couldn't fit it all inside of that column.
11:48So this is where wrap comes in handy here.
11:50There we go.
11:50We could add the wrap switch for Format-Table,
11:53which will actually wrap it then inside that column
11:56so it's all typed out downwards.
11:58And then we could also combine then
12:00with an auto size-- oop, auto size--
12:03to clean that up a little bit.
12:05And there it is, even though it's still
12:06a little more difficult to use.
12:08But at least it auto sized it and wrapped it.
12:11So it's a little easier to read than before.
12:12So those are going to be the most popular switches here
12:15with all these formats commandlets-- group by,
12:18auto size, and wrap.
12:19Get familiar with those.
12:20Play around them because they can go a long ways
12:22and help you control the output of your object.
12:24Now, another neat thing I want to show you here
12:26with format table that's also going to highlight one
12:28of the differences between this and select object
12:30is customizing your output, right?
12:35Creating your own columns, aligning them,
12:37formatting them-- that kind of thing.
12:40So let's jump in the ISE here because there's
12:42a lot of typing involved here.
12:44I don't want to make you watch me type all this out.
12:45And I opened up our commands file for this Nugget.
12:47Now, this is all the stuff we just
12:49did up to this point right here-- get-eventlog.
12:51So here, what we're going to do is
12:52we're going to get the system event log, get us the first 10
12:56entries or the most recent 10 entries,
12:57and then we're going to format the table.
12:59Now, let me show you what this looks
13:01like without our custom column.
13:02Because we're going to add our own custom
13:04formatted column here on the end of all this.
13:06Here's what it looks like.
13:07So you can see we've got some issues here
13:09with the formatting.
13:11But we're getting the most recent 10 entries here.
13:13We're pulling back these columns.
13:15So we're going to add our own column onto the end of this
13:17called when.
13:18And what we're going to do is format
13:20this in the form of days, hours, minutes, seconds
13:23so we know exactly how long ago this happened relative to now.
13:26So we're going to take the date.
13:27We're going to subtract time generated,
13:29the time this interview was generated from it,
13:31and we're going to align this column to the right
13:34and then format it here using this format string.
13:36This should look familiar.
13:37We did this in a previous Nugget, all right?
13:39So it's very easy to do.
13:40We pass a hash table in.
13:42We specify the name.
13:43You can also use label.
13:44You could spell out a name or you can just
13:46use n, which will result to name.
13:48So that will give us our column header.
13:50Then our expression here is going to be the actual value.
13:53And here, we're just doing get date minus the time generated,
13:56which will give us, again, the relative time that this
13:59happened in the form of days, hours, minutes, and seconds.
14:02But here's the special part of this expression inside a format
14:05table.
14:06We can control the alignment-- right, left, center--
14:09and we can control the format of that string.
14:13Pretty cool-- now let's take a look at this by running it.
14:16And there it is.
14:17Now, we still have some formatting issues,
14:19but we've got our column here and it looks great.
14:21All those formatting issues can be
14:23fixed with our magical switch here, auto size.
14:26So let's just add auto size into that.
14:27And look at that.
14:28It looks great.
14:29So there's one of the big differences
14:31between format and select.
14:32Think of select as you're in the pipeline,
14:34doing things with your objects in the pipeline.
14:36But we can still pull out specific properties
14:38if you have no need for formatting.
14:40Formatting is really good for you're
14:42at the end of the pipeline.
14:44Your objects are about to get displayed.
14:45Do you want to do anything else to them?
14:47Make them pretty, line them up, do that kind of things.
14:49And I should also mention second big difference here
14:53is that Format-Table or any of the format commandlets,
14:56once they hit, your objects are done.
14:58They're toast.
14:59They actually get fully replaced.
15:01Because if we do something like this
15:03here, if we do a get member after a select,
15:06they're still objects, right?
15:07Look at that.
15:08We get our objects.
15:09And here, we're going to get a listing for every type of entry
15:10in there.
15:11But they're still objects.
15:12Where if we were to do a get-member here
15:14after our format, they're going to be format objects.
15:19Look at that.
15:19See that?
15:20So those objects are gone.
15:22They've been formatted.
15:23They're out of the pipeline.
15:23So that's why it's very important
15:25that whenever you do formatting, make sure that it
15:27is the last thing you do.
15:29Now, the last thing we want to show you
15:30how you can control the default output for properties
15:35on objects.
15:36Now, of course, you could go into your format files
15:38and edit those or your type files and edit goes.
15:40But that's definitely not the recommend way to do it.
15:42Leave those files alone.
15:43If you're going to create your own formats,
15:44create your own format files.
15:46And if you want to control default property output,
15:49use our trusty commandlet that we've
15:50looked at in a previous nugget called Update-Typedata.
15:53We can also use this to determine
15:55or I should say define the default display outputs.
15:58So here, we're going to take the System.DateTime type.
16:01And we're going to say, you know what?
16:02We don't want the defaults.
16:03In fact, just to show you the defaults
16:04here, if we do a get-date and send it to format-list,
16:06here's what it looks like.
16:08There are all of those properties that
16:09are outputted there by default. So if we
16:12wanted to control that-- to say maybe
16:14we only wanted a couple-- then we
16:15could use Update-TypeData, specify your type name,
16:18and specify default display property set
16:21and pass in your properties.
16:22PropertySet is used for Format-List.
16:24Property without the set here, just default display property,
16:28is how you control outputting for Format-Wide.
16:30So here, we're going to say date, time, day of year,
16:33and quarter.
16:33Let's go ahead and run this.
16:35And remember, this will only work inside of this session.
16:37So if you're going to do this stuff you want a permanent,
16:39this will be another thing that you add to your profile.
16:42So we do that.
16:43And now if we run this, we should just
16:45get those properties.
16:46But guess what?
16:46We don't have quarter defined in here
16:48because this is a different session from when
16:50we were working with our extending objects
16:52where we actually ran this block of code
16:54to add our own member type, our own script property here,
16:57to the date time type.
16:59So let's run this block of code, same block of code
17:01we ran in a previous Nugget.
17:02So we're going to add our own script property called quarter
17:04with a value here that'll figure out the quarter based
17:07on the current month.
17:08So I'm going to execute that.
17:09And now if we run Get-Date with Format-List,
17:12we should have quarter filled out.
17:13There it is-- awesome.
17:14So there are all of your formatting commandlets,
17:16how to use them, and also how to control the default output.
17:19Let's take a look at your challenges for this Nugget.
17:22Challenge number one-- pretty straightforward.
17:24We did this in our demo here just a little bit ago.
17:26Return a list of all processes.
17:27Use Format-Wide to output the name property
17:30using six columns.
17:32Challenge number two-- return a table of the 25 most
17:34recent system event log entries sorted by entry type.
17:37Than output source time generated
17:40and message using Format-Table.
17:42Then group by entry type and wrap the results-- again,
17:45something else that we've done here in our demo.
17:48And challenge number three-- return a table of processes.
17:50Use Format-Table to return the ID name VM,
17:53and define a custom property named VM megabytes.
17:56Remember, VM by default returns bytes.
17:59So you're going to add your own custom column here,
18:02which is going to be VM, Virtual Memory, in megabytes.
18:04So you're going to use an expression that converts that
18:06to megabytes, use right alignment
18:08with the numeric stream format for two decimals,
18:10and auto size the results-- a little more involved,
18:13but again, really not that difficult to do.
18:15Just remember, you're going to use a hash table
18:17to define that custom property using the property
18:20switch on your Format-Table to add your own column
18:24into the results.
18:25Remember, you can find the solutions
18:27underneath these regions.
18:28Just expand them and you can find
18:29all of these files inside of the Nugget lab files,
18:32which are downloadable on the right hand side of the course
18:35page.
18:35Good luck!
18:36In this CBT Nugget, we covered formatting output
18:38in PowerShell.
18:39We saw how PowerShell determines what format to use
18:42and what properties to pull out of our objects
18:44once they hit the end of the pipeline.
18:45And we got familiar with those big formatting
18:47commandlets-- Format-List, Format-Wide, and Format-Table.
18:50I hope this has been informative for you
18:52and I'd like to thank you for viewing.
The Pipeline Returns
0:00The pipeline returns.
0:02So PowerShell rocks because we can do so much with so little.
0:05What used to take complex VBScripts
0:07can now be done with a one-liner in PowerShell.
0:10But how does it do it?
0:11How do objects traverse the pipe line and commandlets transfer
0:14data to the next commandlet?
0:15That's what we're going to cover in this Nugget.
0:17Understanding the internals of the pipeline,
0:20and how objects are transferred between commandlets
0:22can go a long way in giving you the power
0:25to control that pipeline.
0:27Let's begin.
0:27So how does the pipeline really work?
0:30Up to this point, we've been stringing commands together,
0:32and we just kind of assume that it's all going to work.
0:34So we were to do something like a get-service,
0:37and we were to pipe to this over to say, a stop-service,
0:40we just know it's going to work.
0:41Now up to this point, we've talked about objects.
0:43So we know that get-service is going to return objects,
0:45and it's going to send those objects over to stop-service.
0:48But we just take this pipe for granted.
0:50It's a magic symbol that does all the work for us.
0:52We don't have to know how it works.
0:54But again, understanding how it works
0:56will help us really have a lot more control over the pipeline,
1:00as you'll see here.
1:01So here's how it works, right here.
1:03Commandlets accept input on a parameter.
1:07So this is also why it helps to dig into the Help files
1:10to look at the details of each parameter,
1:12because we've got a really nice property
1:14underneath each one of these parameters called
1:16Accept Pipeline Input.
1:19And that's what we're going to dig into.
1:21Now, how PowerShell determines what parameter to hook up to
1:25is a process known as Pipeline Parameter Binding.
1:29And it's going to do this in one of two ways.
1:31It's either going to do it ByValue or ByPropertyName,
1:34which is one thing that you're going to see on the Accept
1:36Pipeline Input.
1:37If that's true, it's going to either say ByValue, ByProperty,
1:41or it's going to be both ByValue or ByProperty.
1:44Let's look at ByValue.
1:45This is the first thing PowerShell
1:46is going to try to do.
1:47It's going to try to take those objects
1:49and see if there's any parameter that matches that object type
1:54and can accept pipeline input ByValue.
1:57So PowerShell is going to first evaluate the objects coming in.
2:01If there any parameters that can accept this object type
2:04as pipeline input, then it's going to say awesome, great,
2:08I'm going to pass all those objects through that parameter
2:11to the next commandlet.
2:12If it can't do that, then it's going to move on to step two.
2:15But let's just pause for moment and just kind of digest
2:18what just happened there with step one.
2:20Let's take get-service, for example.
2:21So if we were to run get-service,
2:23get a bunch of objects back, and then we
2:25pass this [INAUDIBLE] stop-service,
2:26again, the PowerShell is going to look
2:29at the types of those objects.
2:30It's going to say, OK, these are service controller objects.
2:33And then it's going to look at this commandlet
2:36that we're passing it to, and it's going to say, all right,
2:39does this commandlet have any parameters
2:42that accept a service controller object as pipeline input
2:46ByValue?
2:47And it does, and in which case it
2:49would use that, pass those objects into that parameter,
2:52and stop-service would then be able to do its thing.
2:54So what if by value fails.
2:56In other words, we're passing data
2:58through a commandlet that doesn't accept objects
3:01of this type for any parameters that accepts pipeline input.
3:04If it doesn't, it's going to move over to step number two
3:06and try to match them up ByPropertyName.
3:10Now, what this means is it's going
3:11to take a look at the objects coming in,
3:13and it's going to look at the actual property
3:16names of those objects, and try to match them up
3:18to the perimeter names of the commandlet that's accepting
3:22these objects that also accept pipeline input ByPropertyName
3:26name, and literally just match them up.
3:28It's going to take the data from that object property,
3:31and pass them over to the parameter with the same name.
3:33And it will hook them up.
3:35Now there are, of course, a couple
3:35of pitfalls with this, because it's not
3:37guaranteed that that's the right data going back and forth.
3:40And I'll give you a good example of that.
3:42And that's what it really helps to understand
3:44this internal process, because you'll be aware of that fact.
3:48And if things go wrong or you get unexpected results,
3:52you'll know why.
3:52So that's all it is.
3:53It's just literally going to match up the name.
3:55It's going to evaluate the objects,
3:57match the name of the property of the object
4:00with the name of the parameter that accepts pipeline input
4:03ByPropertyName.
4:04And it will match multiple property names.
4:07So if you have an object that has a name property, and maybe
4:10a title property, and then you have a commandlet that
4:13has both of those parameters that accept by pipeline input
4:17ByPropertyName, it's going to send both of them
4:19over the commandlet at the same time.
4:21Now let's step into the Virtual Nugget Lab
4:23so I can show you how this process works in both ByValue
4:26and ByPropertyName.
4:27And then I also want to show you how you can control this
4:30by using custom properties.
4:31So we can manipulate the objects in the pipeline
4:35so we can ensure that they're getting transferred over
4:38to commandlets accurately.
4:39And I also want to show you something
4:40about parenthetical commands, which is a great way
4:43to get around certain limitations
4:44within specific commandlets.
4:46All right.
4:47We're in the Virtual Nugget Lab.
4:48Now, the best way to show how this works is
4:49to get a couple of Windows side by side
4:51here, so we get some Help files, as well as XEU
4:54commands here in the same screen.
4:56So the first thing we want to do is just show you
4:58how this works ByValue.
4:59So if we were to do a get-service,
5:00and we were to pipe this to stop-service,
5:02and I'm going to throw a what if on here,
5:04so we don't actually do it and crash our machine,
5:06that would've worked.
5:07It would've stopped all the services on the system.
5:10But how?
5:11How did that work?
5:12Now let's get help here on stop-service.
5:15And let's go full mode here.
5:16We need full.
5:17That way, we get all the perimeter descriptions
5:19and such.
5:20And I'm just going to scroll up here.
5:21And what we're going to do is look at these parameters.
5:23So the one that you're looking for
5:25is right here-- accept pipeline input.
5:29So Display Name, nope, Exclude, nope, Force, nope, Include,
5:32nope.
5:33Oh, but look at this one, Input Object.
5:35It accepts ServiceController, and more importantly,
5:37or it accepts pipeline input ByValue,
5:40meaning if we were to pass ServiceController objects over
5:44to this top service commandlet, this
5:46is how it's going to accept them, and it'll work.
5:48And that's exactly what we did over here,
5:50because we know that get-service-- in fact,
5:52if we do a get-service here and just pipe it over get-member,
5:55we know that these are ServiceController objects.
5:58So that's why that succeeds.
6:00And that's always going to work when you have nouns here
6:03that are the same.
6:04So get-service piped over to stop-service,
6:06and start-service.
6:08Those are pretty much going to work all the time.
6:10All right.
6:10Let's take another example here.
6:12Let's just clear our screens.
6:14And let's do a get-service.
6:16And let's pipe this over to sort-object.
6:19And let's sort say, by a display name.
6:22All right.
6:23Cool.
6:23Hey, how did that work?
6:24Well, let's get a help here on sort-object.
6:26And let's get full.
6:27This one's very interesting, because you
6:29can pretty much pass any object over to sort-object,
6:32and it'll work.
6:33But how?
6:33How will it do it?
6:34Well, let's look at the properties here,
6:36and let's see here.
6:38Look at this.
6:38Oh, we've got a PSObject.
6:40Oh, look at that.
6:42It accepts it True ByValue.
6:44We also have a more generic object here on Property,
6:47but guess what?
6:48It doesn't accept pipeline input,
6:49so we know that it won't work.
6:51But this one will work.
6:53So PSObject is what?
6:54Yeah, the base of all objects in PowerShell.
6:56So what that tells us is we could pretty much pass anything
6:59into sort-object here, and it'll work.
7:02So keep an eye out for that.
7:04So that's just another good example there of ByValue.
7:08And it's a much more generic example,
7:10because sort-object accepts virtually any kind of object
7:12here in PowerShell.
7:15Let's do another one, and let's do ByPropertyName now.
7:17So what I'm going to do here is I'm
7:18going to just do a get-help on, let's say,
7:20stop-process instead of services here.
7:23Mix it up a little bit.
7:24And let's just get the full help here.
7:26Let's take a look at these parameters.
7:28So how can we pass data here to stop-process.
7:31Well, if we scroll down here-- oh, there's one.
7:33ID.
7:34And it's ByPropertyName.
7:37So if we have an object with ID in it,
7:39we can pass it over here and stop it.
7:41What about here?
7:42Oh, InputObject, of course, process.
7:43So we can use get-process to get process objects.
7:46And of course, if we do that, then that's what it will use.
7:48But if we don't do that, then we have a couple of options here
7:51ByPropertyName that's going to be
7:52ID as well as name as a string.
7:55So let's see.
7:56Let's do something here.
7:57Let's fire up some Notepad instances here.
8:00How about just one?
8:01Let's do a get-process for Notepad.
8:03All right.
8:04So we've got one process in there.
8:06And now how about this?
8:07The name of it is Notepad, even though it went off the screen
8:11there.
8:11Let's format that as a list.
8:13There we go.
8:14Notepad.
8:14See, formatting commandlets are great,
8:16because we can do things like that.
8:17So here it is.
8:19Notepad is the name.
8:20And what was I looking for there?
8:22Yeah, that's pretty much what I was looking for.
8:24So can we do this?
8:25Can we do Notepad and pass it over to stop-process.
8:28Will this work?
8:29Should this work?
8:30Because look at that.
8:31It can accept a string, ByPropertyName if we hit Enter.
8:35You can say, no, sorry.
8:37Anybody know why that didn't work?
8:38Right.
8:39Because this isn't an object.
8:40We just passed a string.
8:41I'm sorry, it's not an object that contains a property
8:45with name in it.
8:46So this won't work, because we're just
8:48passing a string over.
8:49In fact, if we do this, Notepad, and we pipe that to get-member,
8:53we're just passing over a System.String.
8:56So it works from the data type perspective,
8:58but parameter binding isn't working ByPropertyName
9:02because this isn't an object with the property of name.
9:08That's what we really need here.
9:09So watch this.
9:10Let's do this.
9:11Now, let me get a little more screen space for this one here.
9:15Properties.
9:15Layout.
9:16Let's just change this back to 120 here.
9:18120.
9:18All right.
9:19Good deal.
9:19So let me paste some code in here.
9:21Now, here's what's happening.
9:21We're going to create a brand new object here.
9:23Just a base PSObject.
9:25So our own custom object.
9:26And then we're going to add the member name.
9:28Just a note property here with a value of Notepad.
9:31And we'll just add one more in here just
9:33to get another property in here called Time.
9:35It's just going to be a time stamp.
9:36Now if we execute, or pass I should say,
9:39this object over to stop-process,
9:41is it going to work?
9:42Watch this Notepad down here when I hit Enter.
9:44Oh, it's gone.
9:45It worked.
9:45And why did that work?
9:46Because if we look at this object here,
9:48we just send our variable over to get-member,
9:51we can see that this is an actual object that
9:54has a property of Name.
9:56And if we head back over to our Help here for stop-process,
9:59we can see that there it is, Name.
10:01ByPropertyName.
10:02And it failed on ByValue because we're
10:04passing over a PSCustomObject, and the ByValue here
10:08accepts ProcessObjects.
10:09So step one failed.
10:11Step two succeeded, because we have a property name accepted
10:15on Name.
10:15And we've got another property name up here for ID,
10:18but we don't have ID.
10:19If we did have ID, it would also pass that data over as well.
10:23But this is how it succeeded right down,
10:25and how Notepad was killed.
10:26Because we created an object with the Name property,
10:28and it matched up to the Name parameter,
10:30because it accepts pipeline input on that parameter.
10:33Make sense?
10:33All right.
10:34Cool.
10:34Now, let's head into the ISE here.
10:37Now this is why we need to be aware of how this stuff works.
10:41Because there is a potential, when you're not
10:45passing objects ByValue that objects property names
10:49and parameters names from commandlets could line up,
10:51but it could be different data.
10:52Here's an example.
10:54Get-service.
10:55What if we piped this to stop-process?
10:56Look at that.
10:57Two totally different commandlets.
10:59We're dealing with services.
11:00We're dealing with processes.
11:01But services, of course, underneath the hood
11:03still expose generally a long running process.
11:08But here's the thing.
11:09Service names, because get-service returns objects--
11:13in fact, just to show here-- returns objects
11:15with a Name parameter.
11:16There's that Name parameter.
11:17And yeah.
11:18Stop-process, as we just saw, accepts parameter or pipeline
11:22input on the name parameters.
11:24So this would actually work.
11:26But it may not line up.
11:27In fact, I'm just going to do a what if on this, just in case.
11:31But if we hit F8 there, it worked.
11:33The commandlet actually accepted parameters.
11:36The reason we're getting these errors
11:37here is because it can't find processes
11:39with the same name and service names.
11:41But there are a couple of things.
11:42I could scroll up here a ways.
11:44But there are a couple that will work,
11:46because some services' name are the same as their executable.
11:50So that would work.
11:51So this is why you just need to be careful
11:53when working with ByPropertyName,
11:56because object properties likely could
12:00have a name or two that match a parameter that you're
12:02passing it to.
12:03But thankfully, we can control this.
12:06We have full control over everything in the pipeline.
12:10So let's take an example of that.
12:11Let's say that we've got a couple of departments coming
12:13on board, and we need to create a bunch of Active Directory
12:15Users.
12:16So we get a CSV, or spreadsheet, or whatever data,
12:19and whatever format here from HR,
12:21and they give us the CSV file that
12:22contains the name, the user name, the title,
12:26and the company, and maybe lots of other fields inside of here.
12:29And this CSV file, we can import and turn
12:32into a bunch of objects.
12:33And the Import-Csv commandlet is just
12:35an awesome commandlet for this.
12:37So I actually created this file called Users.Csv
12:39with this exact data inside of it.
12:41And if we were to just run this by itself,
12:43you'll see that it brings it in, and it transforms those column
12:48headers into object properties.
12:50And then we have an object for each one.
12:51So we've got three objects inside of here.
12:53And actually just to prove that here,
12:55if we have pipe this to get-member, watch this.
12:57This is pretty neat.
12:58So we get a PSCustomObject.
12:59And we get Company Name, Title, and Username
13:02as properties of those objects.
13:03So that would give us three objects
13:06representing those individuals.
13:08Now, here is where things get interesting.
13:10So let's say that we wanted to pipe this
13:12to the commandlet New-ADUser which creates an Active
13:15Directory user.
13:16Now, we know we're passing over PSCustomObject.
13:19So if we looked at the Help for a New-ADUser-- in fact,
13:21let's do that.
13:22Let's look at the Help here for get-help new-aduser.
13:27I'm going to do full Help here.
13:29If we check this out, and we scroll up here,
13:32look at all these ByPropertyNames.
13:33Look at them all.
13:34There's lots of them.
13:36So we know that in order to create Active Directory Users
13:40ByValue, we would need to actually get ADUser Objects
13:44But this coming from a CSV.
13:46We've got a PSCustomObject.
13:47So our only option here is going to be ByPropertyName.
13:50But pretty much everything in here accepts ByPropertyName.
13:53So that means we could map all of this stuff
13:55from the spreadsheet from those property names,
13:57but we need to make sure that the property
14:00names of those objects line up with the parameter names
14:03inside of New-ADUser.
14:05And how can we do that?
14:06Because name will line up, but username will not line up.
14:09It's actually same account name.
14:11Title and company will also line up.
14:12So we need to do something about this username.
14:14And maybe we have another one on here.
14:16Maybe we have D-E-P-T instead of something spelled out
14:18department.
14:19How can we do that?
14:19This is where custom properties are
14:21awesome, because we can throw a select object
14:24in between our import and our New-ADUser command
14:28to transform that pipeline, to add our own new properties
14:32on top of these existing properties with names that
14:35won't work with New-ADUswer.
14:39And what New-ADUswer will do then
14:41is to just ignore anything that doesn't map.
14:43So username, we don't have to do anything special with it.
14:45We can just ignore it, because that commandlet will ignore it,
14:48and we'll create our own called samaccountname on top of it.
14:50And if we did have department, we could spell out department,
14:53and then create a custom property that maps
14:54to the D-E-P-T. We don't have that in here.
14:56I just wanted to show you that for completeness there.
14:59But let me get that out of there.
15:00There we go.
15:01And now if we execute this, it's going to actually create
15:04these three users, because we now have Sam account
15:06name, which is required.
15:08So let's do that.
15:08And there it is.
15:09It should have created that.
15:10How do we know?
15:11We can run a Ge-ADUser, and we should get all three
15:15of those individuals in here.
15:16There it is.
15:16There I am.
15:17There's starlord, and there's Jeffrey Snover.
15:20Cool.
15:21And just to show you in the GUI here,
15:23if we do Active Directory Users and Computers,
15:26and we head down to Users, hey, there I am.
15:28And if we head over to Organization,
15:29hey, look at that.
15:30There's my title.
15:31It got mapped over.
15:32Company got mapped over.
15:33And even our account here, if we look there,
15:36got pushed over here to the username,
15:38was mapped to the samaccountname.
15:41Pretty cool, isn't it?
15:42So that is how we can control the pipeline.
15:45So if you're to working with ByPropertyName,
15:48just make sure that what you're passing over lines up
15:52with the parameter that you're expecting.
15:54And if you do need to transform properties,
15:57just create your own custom properties
15:59here using select object.
16:01Really powerful stuff.
16:02Now, the last thing I want to show you here
16:03is parenthetical commands.
16:04This is another really powerful trick
16:05that you can use to get commandlets to work for you,
16:08especially if they do not accept pipeline input
16:10on a specific parameter.
16:12So I've got two files, servers.txt.
16:15This is just a file with literally just
16:18our servers in it.
16:19There's no heading.
16:20It's not a CSV, So it's just literally
16:21strings inside of there.
16:23And I've got another file called servers.csv,
16:25which is the same data, only we've got some columns
16:28inside of here.
16:29So this will be an object with the computer name
16:31property on it.
16:32Now get-service, we know just from the Help
16:35here, if we do a get-help on get-service--
16:39we've got to do full.
16:40There we go.
16:41And if we look at the Computer Name parameter here,
16:44somewhere in here, here we go, that this does accept
16:47pipeline input ByPropertyName.
16:49So we know the first one won't work,
16:50because it's just a bunch of strings
16:52getting passed over, right?
16:53Not going to work.
16:53But this one will work because it's
16:55an object with the Computer Name property
16:57and Computer Name except ByPropertyName.
16:59So that would work in that case.
17:01Now, let's take a look at a commandlet that
17:03has the Computer Name parameter, but it
17:06doesn't accept pipeline input.
17:07So get-wmiobject has a computer name perimeter.
17:11But look at this.
17:12It does not accept pipeline input.
17:13It accepts a string of computer names.
17:17So how do we get around that?
17:19Because if we were to do something like this,
17:21import our CSV, get our object with Computer Name,
17:23and try to pass it, nope, not going to work,
17:25because the input object cannot be bound to any parameters
17:28for the command.
17:29All right.
17:30So this is how we can use parenthetical commands
17:32to get around this.
17:33We can wrap in parentheses another commandlet,
17:37get-content.
17:38This'll get all those server names,
17:39and we will pass them over to the Computer Name property.
17:43And this will work.
17:43If we do get-wmiobject to get all the OS info
17:46across all the computer names in our networks, this will work.
17:49So there it is.
17:50Look at that.
17:51There's all of the OS properties for all of our machines there.
17:54Pretty cool.
17:55So that's a great way to get around some limitations
17:58of parameter binding.
18:00And here's another way to do this.
18:01We could run Get-ADComputer.
18:04And then, I wanted to show you this Expand property,
18:06because this is a great one.
18:07But what this will do is this will get all the Active
18:09Directory computers inside of Active Directory
18:12as ADS computer objects.
18:14So if we didn't do this right here, this won't work, right?
18:18Because we're getting computers, and we're
18:20trying to pass this through the computer name parameter,
18:22which accepts an array of strings.
18:24So what we can do there is we can
18:25pull out a specific property, and use the Expand Property
18:30switch here parameter on select-object, which will
18:32actually go and get the data.
18:33In fact, if we just do this right here-- actually,
18:36let's do this.
18:36The full thing.
18:37There we go.
18:37You can see it's going to pull out those names as we saw them,
18:41just like we saw them inside of our servers on a txt file,
18:44only it's pulling it from Active Directory.
18:45So it's pulling everything.
18:46But this one will, in fact, work as well, because we're just
18:50extracting the raw string out of that computer object
18:54that's returned from Get-ADComputer.
18:55And this will give us the exact same result,
18:57except across all of our servers and clients
18:59that are in Active Directory.
19:01So those are some very powerful techniques
19:03that you will absolutely be using when you get deeper
19:06into PowerShell.
19:07Because having the ability to add our own custom properties
19:09to ensure that they map correctly to commandlets
19:11as we're passing them down the pipeline
19:13and having this little trick here
19:15with parenthetical commands will ensure
19:17that there is nothing that is stopping us
19:19from controlling that pipeline.
19:21All right.
19:22Let's go look at our challenges here for this Nugget.
19:24Challenge number one, review the full help topic
19:26for Get-EventLog.
19:27Does this commandlet accept pipeline input?
19:29And number two here for challenge number one,
19:31review the full help topic for Get-Hotfix.
19:33So which parameters accept pipeline input?
19:36So here, just getting you accustomed to looking
19:39into the full help topics, analyzing those parameters
19:42seeing what accepts pipeline input,
19:44and how it accepts pipeline input.
19:46And that way, again, there won't be any surprises when you're
19:49connecting commands together.
19:50Challenge number two, retrieve the most recent system event
19:54log entry from multiple machines using parenthetical binding.
19:57Would you have accomplished using parameter binding,
19:59and why not?
20:00So here, what you're going to do is use
20:02the Get-EventLog commandlet.
20:04Take a look at the parameters for that commandlet,
20:06and see how you could pass multiple computers into it, why
20:10you'll need parenthetical binding to do so.
20:12And then challenge number three, use parameter
20:14binding to pass a list of computers
20:16from Get-ADComputer to the Get-HotFix commandlet
20:19to view installed hotfixes across servers in the network.
20:22And I'll give you a hint with this one here.
20:24Get-ADComptuter, the property name
20:26that's returned for the Computer Name is actually called Name.
20:29Get-Hot for Computer Name, it tries
20:32to map it ByPropertyName on computer name.
20:35So you'll need to use a custom property to transform the Name
20:39property from Get-ADComputer to the Computer Name
20:41property on Get-Hotfix.
20:43That way, you can line them up, and it'll work.
20:46Good luck.
20:47Just remember, you can see the solution in the Nugget lab
20:49files, downloadable from the right-hand side of the course
20:52page.
20:52Look underneath these region files to see the solution.
20:55In this CBT Nugget, we dug deeper into the pipeline
20:58to get an understanding of how commandlets connect by passing
21:01objects back and forth.
21:02We took a big look here at ByValue and ByPropertyName.
21:07We saw that the first thing PowerShell will do
21:09will try to connect commandlets and their object data
21:12ByValue, meaning it will actually
21:14try to connect the objects to a parameter that
21:15accepts that object type and can accept pipeline input.
21:19And we saw that if that fails, it
21:20will use ByPropertyName, which will literally just line up
21:24the name of properties in the object
21:26with the name of parameters in the commandlet.
21:29So understanding how this process works
21:31will give you the ultimate control over your pipelines.
21:34I hope this has been informative for you,
21:36and I'd like to thank you for viewing.
Providers
0:00Providers.
0:01Wouldn't it be great if we can see any information store
0:04through PowerShell as if it were the file
0:06system, this nice familiar hierarchical structure?
0:09Well, that's what providers bring to the table.
0:11We have a single set of common commandlets
0:14that we can use to access things like the file
0:17system, the registry, SQL Server, ISS, access
0:20any of those as if it were this very familiar
0:23hierarchical structure.
0:24So that's what we're going to look at in this Nugget.
0:26Let's get to it.
0:27So again, what is a provider?
0:28It's really just a model for treating data storage
0:30hierarchically.
0:31PowerShell has these things called PS providers.
0:34And they're really just adapters that transform that underlying
0:38datastore into what we're all familiar with, the file system.
0:42So no matter what that underlying data structure looks
0:45like-- be it the file system with drives and directories,
0:47subdirectories, files, or the registry with hives,
0:50and root keys and keys and values--
0:52or really anything-- like SQL Server,
0:54right, you've got instances, databases,
0:56and a whole smattering of objects underneath databases--
0:59no matter what it looks like at the source,
1:00PowerShell transforms it into this common hierarchy
1:04that we can access through a common set of commandlets.
1:06And believe it or not, it's actually pretty simple
1:08to write to your own provider.
1:09So if you have a custom data store out there
1:10that you want to access through PowerShell using
1:12these generic commandlets, then, now,
1:14if you have some [INAUDIBLE] skills
1:16or know a developer that you can talk into writing one for you,
1:19you just simply need to map their data store
1:21to these generic commandlets here
1:22that we're going to be looking at through the rest
1:24of this Nugget.
1:25And it's really, it's pretty straightforward.
1:27So how this works-- just to give you an idea here.
1:30Let me break out a screenshot.
1:31Here we go.
1:32So how it works here is we've got providers
1:34at the very top level.
1:35And when you define a provider, you have your capabilities,
1:38what this provider could do.
1:39We'll talk about these capabilities
1:40here shortly when we get into our demonstration.
1:42And then we have drives.
1:43Everybody's familiar with drives,
1:44right, that nice entry point into what we all know and love,
1:48the file system.
1:49And now, this is where people can get tripped up
1:50because they're like, wait a minute, drive,
1:51you're dealing with the file system.
1:53Well, think of a drive really as just an entry point.
1:55So yes, if you're dealing with the file system,
1:57it's literally going to be the drives that are the drive
1:59letters on that file system.
2:00But if you're dealing with the registry,
2:02a drive is going to be your entry
2:03point-- such as HKLM, local machine, that would be a drive.
2:06HKCU, current user, that would be a drive.
2:09So think of it as the entry point for whatever
2:12data store you're hooking into.
2:14Underneath drives, we have items.
2:15And in items, we're dealing with the file system.
2:17Could be a directory.
2:19Could be a file.
2:20If it's a directory, it's container,
2:21so it can contain other items.
2:23If we're dealing with something like SQL Server,
2:25it could be a database.
2:26That's an item.
2:26But a database is also a container
2:28that can contain other items like tables
2:29and stored procedures and indexes.
2:31If we're dealing with something like a registry,
2:33we've got keys.
2:34If we're dealing with say, ISS, we
2:36could have virtual directories and items underneath that.
2:39So a item is just a generic placeholder for whatever
2:41we're working with.
2:42And you want to know something funny
2:43about this-- we've actually been using these generic item
2:46commandlets quite a bit up to this point.
2:48Here's one for you-- DIR.
2:50Frankly, we've been doing DIR all over.
2:52If we switch to a drive that's on top of the registry or SQL
2:55Server, we can use DIR to get a listing of everything
2:58underneath that because what's DIR mapped to?
2:59You guessed it.
3:00Get child item, GCI.
3:03And there's also one called GI for get item.
3:05There's so ton of item commandlets
3:07for working with specific items underneath the drive.
3:10And items, of course, have item properties.
3:12So if we're dealing with a directory or a file,
3:14we can set attributes like read only, write only,
3:17that kind of stuff, so attributes
3:18in metadata about that item.
3:20There's also location commandlets
3:22that allow us to navigate the hierarchy.
3:25And we've used one quite a bit up to this point
3:27as well, CD, which is an alias for set location, which
3:30allows us to move to a specific item in the hierarchy.
3:34So that's the whole idea behind providers,
3:36just giving us a nice, consistent way
3:37to access any information store through a common set of item
3:41commandlets.
3:42Let's jump into the Virtual Nugget Lab.
3:43We'll get familiar with how to work with providers, drives,
3:46and many of the item commandlets.
3:47Welcome back to the Virtual Nugget Lab.
3:49Let's get to it.
3:50So let's start by running a get PSProvider.
3:53So this is going to get us all the current loaded providers.
3:55Here are the defaults.
3:56And another provider I didn't mention-- Active Directory.
3:59So if we do something like get AD computer-- and let's
4:02just add a filter on here for everything.
4:04Watch this.
4:04It's going to load that module.
4:06Now, if we run get PSProvider, check it out.
4:08We have Active Directory down here as well.
4:09And here is the drive that we can then CD or set location
4:13into and start running DIRs or Get-Item, Get-ChildItems,
4:16all over.
4:17Now, this capabilities thing is interesting.
4:20So should process is telling us that this
4:23accepts the what if parameters.
4:25So we could use the what if parameters as well as
4:27the confirm parameter.
4:28I don't know if I mentioned the confirm parameter before,
4:30but essentially, that just means any time you run something
4:32with the confirm switch parameter on it,
4:34it will ask you, are you sure you
4:36want to do this, yes or no or cancel, that kind of thing.
4:38So other capabilities here are credentials.
4:40So we can supply credentials to this provider
4:44and run it under that security context.
4:46Transactions-- the registry supports transactions,
4:48so we can do all or nothing propositions.
4:51Let's see.
4:51We got filter.
4:52We just saw that one with Get-ADComputer.
4:54It allows us to run queries against that data store.
4:57We also have include and exclude,
4:58so we can include specific ones, ensure they're in the results,
5:01or exclude, so on and so forth.
5:02So these are just the capabilities,
5:05specific parameters and switches that those providers support.
5:08Now, we can also run a get PS drive, which
5:11will give us a listing of all the current drives
5:13on the system.
5:14So before, we had providers and we had a drive property
5:17for the provider object that showed us
5:19all of them inside of an array.
5:20This shows us all the drives actually listed out.
5:24So now we can set location or change directory
5:27to any one of these.
5:28For instance, here's a really cool one.
5:30Let's do a change directory to, how about environment
5:34variables?
5:35See this one?
5:35Any time you do it, you need to add a colon to the end of it.
5:38So here's environment.
5:40Look at this.
5:41Now we are in the environment variables drive.
5:43And now if we do a DIR, or get child item,
5:46we'll get all the items underneath that.
5:48And look at that.
5:48Here's all the environment variables on the system.
5:50We can also go into PowerShell variables here,
5:53which is CD into variable.
5:54And this is extremely useful, by the way.
5:56We'll do an ls, same as DIR, same as get child item.
5:59And look at that.
5:59All of these variables here in PowerShell, as well as
6:02their values.
6:03What about the registry?
6:04CD HK.
6:05Let's go current user here, colon, and do a DIR.
6:09Look at that.
6:09There's at that.
6:10There's the top level items of the out Pretty neat, huh.
6:12How about the file system?
6:14Let's go back to the file system here.
6:15We'll switch to the C drive, which will get us
6:16right into our profile.
6:17Now, just to take a step back for a moment.
6:19You can also create your own drive.
6:21It's just like mapping a drive in Windows.
6:22The only differences is, you're mapping it
6:24to anywhere, any provider drive, and it's
6:27only accessible through PowerShell.
6:29But just to give you an idea here, let's do a PS drive,
6:31new PS drive.
6:32And let's give it a name here.
6:33Let's say we wanted to map this to our Nugget Lab files
6:36over on our file share somewhere.
6:37So we'll call it Nugget Lab here.
6:38We'll give it the PS provider property.
6:41It's going to be a file system.
6:43And then we'll set the root up here
6:45to be about, what is that, FS Nugget.
6:47That's the name of our file server, PSv4.
6:50And now, we have ourselves in drive.
6:52And we can see that, obviously, right there it gives us
6:54the result. But we could also then do a get PS drive,
6:57and boom, there it is.
6:59Another lab.
6:59And so now we could do a CD Nugget Lab.
7:02And look at that.
7:03We're there.
7:03And now we can do a DIR and we're
7:05right into all of the files there on our file server.
7:08Let's create a file over there.
7:10Let's do a new item.
7:12We'll call this myfile.txt It's going
7:14to go into the root of our Nugget Lab directory
7:16there, by the way.
7:17And then let's call this the item type,
7:19it's going to be a file.
7:21There it is.
7:22We just created a new file.
7:24Now, we can also set content.
7:25Here's another-- all the content commandlets as well you
7:28can use to work with any item inside of a provider data
7:32store.
7:32So get item here or set content will do a path.
7:36And let's just path write to myfile.txt there.
7:39And let's set the value equal to hello.
7:43Perfect.
7:43And now we could do a item property.
7:45Let's set this as read only now.
7:46So what we'll do is set item property.
7:48And let's just go ahead and specify the path here,
7:51myfile.txt.
7:53And the name here of the property is read only.
7:57There's a property right there.
7:58And then the value, let's set this
8:00to true, meaning we're setting the read only property to true
8:03there.
8:03And there it is.
8:04Now, if you would get item property,
8:05we could also do a get content on the file there,
8:08passing the path, myfile.txt.
8:10And there it is, hello.
8:12We could also just run get trial item, otherwise known
8:14again, as DIR here.
8:15And there it is.
8:15Look at the mode property.
8:16A stands for archived.
8:17R stands for read only.
8:19Let's do the same thing in the registry.
8:21Let's switch over here to HK local machine.
8:24And let's just go right into the software hive here.
8:27And once we're inside of here, now we
8:29can do a new item, new item.
8:31We'll call this Nuggets.
8:32And the item type here is going to be directory.
8:36All right.
8:36There it is.
8:37Now we have a new node underneath the software
8:40in HK local machine.
8:41Now, we can do new item property and let's just set
8:44the path here to be Nuggets.
8:47We'll give this the name.
8:48How about the key of win.
8:52And the property type is going to be a string.
8:55And let's give the value here.
8:56How about just my reg data?
9:00Perfect.
9:01There it is.
9:02And now let's go take a peek at that in the registry.
9:04We can also just do a DIR.
9:05Just to show you from a graphical perspective here,
9:07let's go to reg edit 32.
9:09And let's head down here into local machine, software.
9:15We should now have-- look at that.
9:17There it is, Nuggets.
9:18And there's our key of win with my reg data.
9:20Pretty cool, huh?
9:21And we can do all of this stuff through a common set
9:23of commandlets through PowerShell.
9:24And we also then run set item or set item property
9:28to change the value of this key, if we wanted to.
9:31But all the commandlets-- there's a lot of them.
9:33Let me just give you an idea of how to find some of them here.
9:35So let's bust out our favorite-- one of our favorite commandlets
9:37here-- get command, GCM, for short.
9:38We're going to use the non-parameter.
9:40This is actually a parameter that accepts a string array,
9:43so we can pass a comma delimited list of strings here.
9:46Let's do item, item property, child item, location, and path.
9:51There it is.
9:52There are your provider commandlets.
9:55So we can use these commandlets.
9:56We will be using these commandlets, no matter what
9:58provider you hook into.
10:00And then the only two that then show up in here
10:01are PS drive and PS provider, which we looked at.
10:04But all of these live inside of the PowerShell.management
10:07module.
10:08So no matter if you're working with the file
10:10system, the registry, the certificate store, IIS,
10:12SQL Server, Active Directory, these
10:14are the commandlets you'll be using
10:16to work with all of the items inside of those data stores.
10:19All right.
10:19Let's bring up the Integrated Scripting environment here.
10:21Here's a list of all the commands
10:22that we were just working with.
10:23There's one more thing I want to show you in here and then
10:25and I'll give you your challenges
10:27here for this Nugget.
10:28And that is, whenever you're working with providers,
10:30you're going to be a lot of navigating and finding things.
10:33And so path versus literal path is
10:36important to understand the difference.
10:38And to just to give you an idea here,
10:39let's head back here just for a second here and let's
10:42just do a help on GCM, or GCI, sorry, get child item.
10:46So here it is.
10:46And if we look up here, we've got two different ways
10:49to use this.
10:49One is path.
10:51One is a literal path.
10:53Where is it?
10:54There it is.
10:54Right here.
10:55And this is a required parameter down here.
10:56So if you use literal path, you're
10:57not going to be able to use path.
10:58They're mutually exclusive here.
10:59Now, the big difference is that some data stores
11:02work differently than others.
11:03And a good example of that is the file system.
11:05You can't use colons and question marks
11:08and things that act as special characters.
11:11You can't use those when you name a file or directory.
11:14But certain data stores, you can.
11:15Like the registry, you can use a question mark
11:17to name a node inside of the registry.
11:20So path is the default and will use those special characters
11:24as things like wild card characters.
11:26And a good example of this over in the ISE here
11:29is if we were to create a bunch of files here-- let's
11:31create File.txt-- File 1 with brackets, File 2 with brackets.
11:35Now, these brackets, we can create in Windows.
11:38We can use these brackets to name the file.
11:40And there you go.
11:40We just created those three files.
11:42In fact, if we do a DIR here just to show you,
11:44there they are.
11:45They're in here right here.
11:46Here's those three files.
11:47So if we try to just do a get child item using
11:49path, which is the default, guess
11:51what, it's not going to work.
11:53It didn't come back.
11:53And that's because these are special characters with path
11:57that it is actually using the range wild card.
12:00So we'd use this to define a range of characters amd values
12:03within the file name.
12:04But literal path, it will work because it's
12:07treating those as literals.
12:09So that's the big difference.
12:10That's just something that you certainly
12:11need to be aware of because path, which is the default,
12:15uses special characters as wild cards.
12:17Literal path will use them as actual characters
12:21inside of the path.
12:22So keep that in mind.
12:23That will be extremely important.
12:24And it's definitely something that we
12:26need to know when working in PowerShell because you will
12:28come across it when you're navigating providers,
12:31file systems, all that kind of stuff.
12:33I'm going to remove those items using a wild card character
12:36because that's what path does.
12:37And there we go.
12:38Now they're all done.
12:39If we do a DIR, they're all gone out of there.
12:41All right.
12:42Let's at your challenges for this Nugget.
12:44Pretty simple here.
12:45Challenge number one.
12:46Display a list of PowerShell providers.
12:48Switch to the environment drive.
12:49Create a new environment variable
12:51and then list all environment variables.
12:53Couple of hints here.
12:54How do you get a list of PowerShell providers?
12:56We saw that one.
12:57It was one of the first things we did, get PSProvider.
12:59Switch the environment drive.
13:00Just remember, once you look at your providers,
13:03you will see the drives listed in there.
13:04You can also do a get PS drive to view all the drives
13:06and just add that colon at the end of the drive name.
13:11So you'll do a CD or a set location
13:13to env colon to switch.
13:15Then create a new environment variable, which we ultimately
13:17use for that, yeah, new item, right, new items which
13:20we'll use.
13:20And then obviously, you'll know how to list all environment
13:22variables.
13:22We've been doin that quite a bit with get child item and DIR.
13:25Challenge number two-- use PowerShell
13:27to navigate to the H key local, or excuse me, current user,
13:30software Microsoft Windows current version hype
13:32and perform a wildcard search for anything
13:34within that contains the word internet.
13:37That's an interesting one.
13:38And number three, use PowerShell to create a new file
13:41on a network share, or really anywhere, add some test data,
13:45set it to read only, and read the data back into the shell.
13:47Certainly something that we did here.
13:48I'll give you a demo of that.
13:49But just to give you some hints here.
13:51You're going to be working with navigation commandlets.
13:53You're going to be with some item commandlet
13:55here, item property commandlets, and then content commandlets
13:57for getting set content.
13:59So those are your challenges.
14:00Good luck.
14:01And again, you can find the solutions
14:03underneath these region properties inside of the Nugget
14:05Lab files downloadable on the right hand side of the course
14:07page.
14:08In this CBT Nugget, we took a big look at providers.
14:10We saw that providers in PowerShell
14:12are really just a layer of abstraction that
14:14allows us to work with any underlying data store using
14:18a common set of commandlets.
14:19So we learn these commandlets once
14:21and we can use them no matter what
14:23provider we're working with.
14:24I hope this has been informative for you
14:26and I'd like to thank you for viewing.
WMI & CIM
0:00WMI & CIM, or as I like to call it the "Wimmy and Cim Show."
0:06We're talking about Windows Management Instrumentation,
0:08and the Common Information Model.
0:10This is really one thing, this is an underlying standard
0:13used to access the hardware and software layers of a system.
0:16So in this Nugget we're going to talk
0:18about the differences between these two,
0:19why we have two things for really
0:21one underlying technology.
0:23And how we can utilize them from PowerShell
0:24to get access to virtually any management
0:27information on a system.
0:29Let's begin.
0:30So way back in the early days of computing the DMFT,
0:33the Distributed Management Task Force,
0:34which Microsoft is a member of, said
0:36we need to create a set of standards
0:38for exposing and accessing management
0:39information at the hardware and software layer.
0:41So they came up with something known as CIM, the Common
0:44Information Model.
0:45Now those were the early days so these standards weren't
0:48fully developed, but Microsoft still wanted to get on board.
0:51So they said, we're going to create our own layer on top
0:53of that, and that's where Windows Management
0:56Instrumentation, WMI, came from.
0:57WMI is really just Microsoft's implementation
1:00of CIMS, known as a CIM server.
1:02So when PowerShell came out we had a whole set of WMI
1:06commandlets to tap into that wealth, vast, vast wealth
1:10of information there at the hardware and software layers.
1:13So these WMI commandlets were great.
1:15But again because these standards were loose,
1:17there was no standard for communicating with WMI,
1:20and DCOM was very popular back then,
1:22Microsoft decided to use DCOM and RPC to communicate
1:26with the WMI repository.
1:28Fast forward to modern day times,
1:29and we know that Microsoft has all but abandoned
1:32DCOM and RPC because it's not very firewall friendly, uses
1:35dynamic port allocation, and some other things that just
1:37make it difficult as a communication layer to CIM,
1:41the underlying repository that contains all this information.
1:44So that's why we now have a whole new layer,
1:46a whole new set of commandlets from PowerShell 3.0 and beyond,
1:49which are CIM commandlets.
1:51So we get WMI commandlets which are old school,
1:54and we've got CIM commandlets which are new school.
1:56And they communicate using the WS-MAN Protocol, which
2:00we'll talk more about when we get into remoting,
2:02which is delivered over HTTP.
2:04So the bottom line here is that these WMI commandlets are still
2:08around, they're going to be around
2:09for a while for backwards compatibility purposes.
2:11But for new development they're legacy.
2:13So only use them if you have to, meaning
2:15if you're on PS version 1 or 2 Use
2:17the new CIM commandlets going forward for PowerShell 3.0
2:21and beyond.
2:21So here's how this works.
2:22Every machine has a repository on it, right?
2:24That contains all that juicy management information exposed
2:28via these CIM interfaces.
2:30So every single machine has its own repository.
2:32And no matter if we use the WMI commandlets or the CIM
2:36commandlets that information is going to be the same.
2:38It's just one repository.
2:40It's just the communication layer
2:42to access that information is really
2:43what's changed between these two different sets of commandlets.
2:47So if we were to dig inside the repository
2:49here, at the top level we have something known as a NameSpace.
2:52And NameSpaces are really just a way to group
2:54and organize all of that information.
2:56Think it as a directory inside of the repository.
2:59But underneath NameSpaces we have Classes.
3:01And we talked about Classes pretty extensively
3:03on our Objects Nugget.
3:04We know the a Class is just a way to represent a live Object,
3:07or to represent something.
3:08So we've got Properties, which describe
3:10the data points of the state.
3:11And we've got Methods, which describe the actions we
3:14can perform against that.
3:15Then we have Instances.
3:17And an Instance is a live version of that Class.
3:19So for instance, we have a Class known as Win32_logicaldisk.
3:23And then we have an Instance for each one of the actual disks
3:27inside of the operating system.
3:28So we have one for the C drive, the D drive, the E drive,
3:31so and so forth.
3:32So the big to take away from this,
3:33is again, when you're inside the repository it doesn't matter
3:36if you're using WMI or CIM.
3:38Because that repository contains the same information
3:40no matter what.
3:41What really matters is from the outside.
3:44Because WMI uses is DCOM and RPC, CIM uses WS-MAN and HTTP
3:51or HTTPS.
3:53Now because this communication layer
3:54is so different across these sets of commandlets,
3:57it means that we need to work with them a little bit
3:59differently.
4:00For example WMI we always have a live connection
4:03to the repository, meaning when we request
4:05these Instances we are going get live Objects back
4:08to work within PowerShell.
4:09That means we can call Methods here
4:11on these Objects inside of the pipeline
4:13and from the client side.
4:15So it's a really tightly coupled set of commandlets.
4:18CIM on the other hand, it's more modern day,
4:20it's more like working with a web server, it's stateless.
4:23We request these Objects from the repository,
4:26they get serialized into XML and sent across as data,
4:30and deserialized back into Objects at the client side.
4:33Meaning all the Methods are getting stripped off
4:35the Objects, we're not going to be
4:36able to work with these Objects because they're not
4:38live Objects.
4:39But this also means it's much more lightweight,
4:43and it's much better on performance.
4:45Because we don't have this tightly coupled connection
4:49to the repository, it's very loosely
4:50coupled as most things are in today's stateless world.
4:53So again the bottom line here is going forward
4:55use the CIM commandlets.
4:56It's what Microsoft is pushing us toward,
4:58they're really providing the WMI commandlets here
5:00for backwards compatibility.
5:02All right let's jump into the Virtual Nugget Lab
5:04and get some experience here working with WMI and CIM.
5:06All right, welcome back to the Virtual Nugget Lab.
5:08Now the first thing I want to do is give you this tool
5:10for exploring the repository.
5:12It's an excellent tool, I'll give you the URL
5:13where you can download it.
5:14I'll also include it here in the Nugget lab files,
5:16it'll be in the directory for this Nugget 13WMI-CIM.
5:20So it's called WMI explorer.
5:22And this is just a fantastic tool
5:24because it allows you to literally explore
5:26the repository from top to bottom.
5:29Everything that's in it, all the Classes, Instances, Properties,
5:32Methods, it's a really, really great tool.
5:34So what I'm going to do here is just
5:35connect to the local machine, we can also
5:37connect to any server in our environment here.
5:39And what that'll do is first give us
5:41a list of NameSpaces underneath this machine, so here they are.
5:44And by the way, this is going to be the most popular NameSpace,
5:47it is also the default NameSpace here.
5:49Which I'll talk about here when get into some
5:50these commandlets.
5:51But here it is, Root, whack, CIMV2.
5:55So inside of here when you double click on a NameSpace
5:59it'll actually give us all of the Classes in that NameSpace.
6:02Again this will be by far the most popular one.
6:05And look at this, we have all of these Win32 Classes in here,
6:08which are going to be the majority of the Classes
6:10that we're working with it.
6:11And by the way why is this even important?
6:13I should have mentioned that early, but why
6:15do we need to access to this repository, when
6:17we have lots of commandlets that get this information anyway?
6:21Well, the answer to that is there is so, so much more
6:24information.
6:24Like I said it's extremely vast.
6:27And while we are getting commandlets
6:29on top of all of this-- in fact, let's find one here,
6:31Win32_service, something that we've
6:33been working with quite a while here
6:35in PowerShell our Services.
6:37It's in here somewhere, this is why we have a filter up here.
6:39Right here, Service, there we go, WIN32_service.
6:42That's all the GetService commandlets do, by the way.
6:45What most commandlets that get information,
6:46they're just hitting up this repository,
6:48that's all they're doing.
6:49So yes we do have commandlets, thankfully.
6:53So we don't have to rely on purely
6:56hitting the WMI repository here.
6:58But there are lots of things out in here,
7:01I should say, not out here-- in here
7:03that we can't get through commandlets.
7:04So as time goes on we're going to get
7:06more and more commandlets that access,
7:07and make it easier to hit this information.
7:09But this why it's crucial to know this stuff,
7:11because there will be things in your PowerShell career
7:14that you can't do through commandlets, that you will only
7:16be able to do here using this repository.
7:18All right, so once we find something in here,
7:20we find a Class, we can double click on it.
7:22And that's going to go and get all the Instances
7:25of that Class.
7:26So when we're dealing with Services
7:27we're going to have an Instance for every Service.
7:29We can click on it here and it's going
7:31to give us a list of all the Property and Property
7:34values for that Instance.
7:35And by the way these tabs are great up here as well
7:37because if you hit Properties you
7:39can get nice descriptions on all of the Properties
7:43for this Instance in this case.
7:45Pretty cool.
7:45And any time you click on them it
7:47will take you right to that Property
7:48and give you a nice description of it.
7:49And we also have all of our Methods here.
7:51We can click on it to see what our parameters are,
7:53the input parameters, and output parameters
7:55are for these Methods, as well as descriptions of them.
7:58So this is a great, great, great tool.
8:00Because it allows us to explore and discover, as well as get
8:04some great information on what data
8:05these Classes expose, and descriptions.
8:08It's just a fantastic, fantastic tool all around.
8:11And the search by the way, is also fantastic.
8:13Because you can search Classes, Methods, or even Properties.
8:16Say for instance, that we wanted to find everything
8:18with memory in it.
8:19We can type that in and it's going
8:21to search that name space.
8:23So this is why we have a little recursive take over here,
8:26because it'll search all the other NameSpaces
8:28underneath that NameSpace that you're in.
8:29But we won't do that because that'll take a very long time.
8:31So I'm just going to hit search, which
8:33is going to search all of the Class and Properties
8:36inside of the Root CIMV2 NameSpace here.
8:38And look at that, there's quite a bit
8:39and it gives us the Property name, as well as
8:41the Class they live in.
8:42And then we get the other NameSpaces
8:44with their descriptions here.
8:45So all kinds of stuff here for memory.
8:47We could go to Methods, we could say
8:48what are all the things we could create here
8:50for everything inside of-- here, give us the create Methods.
8:53Look at that we create processes,
8:55we can create Services, we can create shares, and all kinds
8:59of other things in here.
9:00And of course you can also search for Classes.
9:02So, say, I want to do something that's going to involve BIOS,
9:05I can search for BIOS and look at that, there we go.
9:07We've got some Classes here that work with BIOS.
9:10So get familiar with this tool and always have it handy
9:12because it will be your go-to tool, again
9:15when it comes to working with anything inside the repository.
9:18Now let's jump into PowerShell and get familiar
9:20with some of these commandlets.
9:22And really I want to focus on the CIM commandlets,
9:23but I will give you just a taste of the WMI commandlets as well.
9:26The first thing I want to do is show you
9:27where you can find all these CIM commandlets.
9:28So we can do a get-command here.
9:30And let's just go ahead and say Module, CIM, commandlets.
9:34This is the module that they all live in, and here are
9:37all of the CIM commandlets.
9:39The important ones here are the ones
9:39we're going to be working with, CIM Class,
9:41CIM Instance, CIM Associated Instance.
9:43I'll even give you a little taste working with sessions.
9:46More of that when we get into remoting,
9:47but it's still pretty cool to be able to create a session,
9:50and some of the neat things we can
9:51do with working with remote repositories.
9:54And also invoking CIM Methods, so we'll
9:56look at some of the more popular ones.
9:59The first thing I want to show you is how to find Classes,
10:01even though it's hard to compete with this tool
10:04when it comes to finding what you're looking for.
10:07So generally, I would say any time
10:08you're looking for things just use this tool.
10:11But you can certainly still use PowerShell,
10:13in fact you can use Get-CimClass to find anything.
10:18And they have a NameSpace parameter,
10:20so you can look for a specific NameSpace.
10:21Again the default is that Root CIMV2 NameSpace, which
10:24is where a majority of things you're going to be looking for
10:26live.
10:27So you can generally just omit the NameSpace parameter.
10:30But if we just do a Get-CimClass it's
10:32going to give us all of the Classes inside of the Root
10:35NameSpace that we were looking at.
10:36That's equivalent to just double clicking our route CIMV2,
10:40same exact list right here.
10:42We can also do something like this, Get-CimClass
10:45where, let's say the ClassName has disk in it.
10:49Here we go, there's all the Classes that have disk in it.
10:51We can do the same thing with Methods.
10:52Let's say we want to see anything
10:53that has a Method, as we did there in the UI, of create.
10:56Here we go, this will give us all the Classes
10:58that have a create Method.
11:00So while it is great that we can use
11:01PowerShell to find this information,
11:03just use the WMI explorer.
11:04It's so much easier to find things.
11:07How about the important stuff, getting data
11:08from the repository?
11:09Let's start with the same commandlets.
11:11If we do a Get-Command and let's just do for the module
11:15a cim-commandlets, that's where they all live.
11:17There it is.
11:17Cim-- oops forgot the commandlets part--
11:19commandlets there we go.
11:20Cim-commandlets, here they all are.
11:21So we just look at you Get-CimClass Get-CimInstance
11:24is the one that we'll be using to retrieve data
11:26from the repository.
11:27Also I'll show you a little bit about the session
11:29stuff at the study, and also how to invoke Methods using
11:32the Invoke-CimMethod So Get-CimInstance we're
11:36going to provide it with a Class, so here we go,
11:38Get-CimInstance What's our ClassName going to be?
11:41Well, again we can jump over to the handy-dandy WMI explorer,
11:45let's go to Classes.
11:46Let's say we wanted to find all the disks on the system.
11:49Let's just do a search for disk in here.
11:51And look at that here we go, Win32_logicaldisk.
11:54There's our Class, here's our Instances,
11:55we need to double click on this and that'll
11:57give us our Instances.
11:58So here we go, we got three Logical Disk here
12:01on the system.
12:02So if we head back into PowerShell
12:04and provide that as a Class name Win32_logical-- and now here's
12:07another really nice thing about the CIM commandlets
12:10is they support Tab completion.
12:12Looks at that, I'm Tabing through all
12:14of the Classes that is completing
12:16for me typing in Win32_logical.
12:1832
12:20This will not work with any of WMI commandlets.
12:24So no Tab completion, no IntelliSense support,
12:26anything like that, only with the CIM commandlets.
12:28So a great reason to use the CIM commandlets.
12:31So let's go back to Logical Disk,
12:33somewhere-- where did I go-- there we go, Logical Disk.
12:35So let's just start with this.
12:37I'm going to hit Enter.
12:38Here we go, we just queried the repository
12:39and there are those three Logical Disks.
12:42Now we can also do the same thing with WMI,
12:44just to prove that it's the same exact repository.
12:46And by the way for WMI it's Get-WmiObject
12:49And we can pass in the same thing here for the Class.
12:51So instead of a ClassName it's actually just Class.
12:53And both of those, by the way, are positional parameters
12:55so you'll actually need to provide them.
12:57But let's just do the same thing, Win32_logical.
13:00And now I'm hitting Tab, notice that, it's not working.
13:03So no Tab completion we need to type if all out.
13:05Logical Disk, and there it is.
13:06The same exact information, it's just
13:08giving it to us in a List format rather than a Table format,
13:12but the same exact results because it's
13:13coming from the same spot.
13:15What about Filtering?
13:16Let's do this, let's do that same command here
13:19Get-CimInstance, ClassName Win32_LogicalDisk only as
13:21a Filter parameter.
13:22See this?
13:23So this Filter parameter we can use by passing in let's say,
13:28let's look up here, DriveType is your Property.
13:30DriveType = 3.
13:33What is that?
13:33Well, once again we can jump over here into WMI explorer,
13:37we can go over to Properties, and let's look
13:39for Device Type, or Drive Type.
13:41There it is.
13:42Drive Type contains a numerical value corresponding
13:44to the Type of this Drive this Logical Disk represents.
13:47And here are those values, 0, 1, 2-- or no,
13:51actually, possible enumeration values is not a value.
13:53So this one's 0, 1, 2, 3.
13:55So these are Local Disks.
13:57So for the Network Drive 5 will be Compact Disks.
14:00So we know that so that these are all Local Disks that we're
14:02going to be querying for.
14:04And so if we hit Enter we should get just one of them.
14:07We only have one disk on this machine,
14:08and that is the C Drive here.
14:10Now the downside of using this filter parameter
14:12is it's not what we're used to with PowerShell.
14:14Look at this, we have an equal sign.
14:16With PowerShell we're used to doing -EQ.
14:19In fact, we could still do something like this here.
14:22Let me just go recall our last command here.
14:25We do something like this, we could
14:26say we don't need to filter, we want to use PowerShell
14:29from this point, that we keep this side more using
14:32the underlying technology, being the repository WMI/CIM.
14:37And then we can use PowerShell for everything else right.
14:39We could do a Where here, and then we could do a $_.
14:44and then say DriveType, here it is, DriveType- = 3.
14:50We could do this, we'll get the same results.
14:52But the big difference there, this is server-side filtering.
14:57This is client-site filtering.
14:59So once we start getting into doing this,
15:01and we start adding the ComputerName parameter to it,
15:03and decide we want to do is for DCNUGGET and maybe FSNUGGET.
15:08Doing this is actually doing all of that processing
15:12on those individual servers.
15:14So this is server side, that's a good-- that's
15:17the positive side of using this filter parameter.
15:20And this is actually WQL, the WMI query language.
15:24So it's nonstandard but you're doing it on the server side,
15:26as opposed to using PowerShell, the syntax we're familiar with
15:29and bringing all those Objects on to the client
15:31and then filtering them down.
15:32So if you want to reduce network traffic,
15:34especially if you're bringing back large volumes
15:36with data, which can certainly happen when
15:37querying the repository.
15:39Then you may want to think about how you structure your filters.
15:43So keep that one in the back of your mind, Filter, server side,
15:46PowerShell, WhereObject, client side.
15:48Another word for you here.
15:49Let's recall our previous command,
15:51let's do this one right here.
15:53And let's just add this into some variables,
15:56let's grab some variables.
15:57I want to show you associations, it's what the point is.
15:59So Disk1 and Disk2, even though there's only one disk,
16:02so actually, we could probably just get away with just one.
16:05But if we had multiple disks, we could pop them
16:06into their own variable.
16:07So we'll do this one equals, Get-CimInstance, thing is going
16:11to pipe it into that variable.
16:13So now we've got it inside of the variable.
16:15Now can call Get-Associate, or Get-CimAssociatedInstance here
16:18it is.
16:19Get-CimAssociatedInstance, we can pass in that variable,
16:22and now what it's going to do is it's
16:24going to go get all of the Classes that are associated
16:27with this Instance.
16:29We've got quite a few of them back here.
16:30So I know this one is the System_Directory,
16:33Win32_Directory.
16:35We've got one for partitions, we've got one for the computer.
16:38We've got some other ones.
16:39How do we find this, out jeez.
16:41Well, what we can do is pipe it, let's
16:45just pipe Disk1 here to GetMember.
16:48And let's see everything that came back.
16:50So, well, in this case we've got our logical disk back here.
16:53Oh, that's all that came-- There we go, Get-AssociatedInstance.
16:58Obviously, this one just contains a logical one
17:00because that's what we put inside of it.
17:01But if we do a Get-CimAssociatedInstance
17:03and pipe to GetMember, now we're going
17:05to get all of those Associations.
17:07So Win32 Group was one of them.
17:10We've got Quota Setting was one of them.
17:12We've got-- this one should be Computer System,
17:14there it is Win32_ComputerSystem.
17:16And then we got a disk partition in there,
17:19oh, we got another one up here as well.
17:20Yeah, Win32_Directory.
17:21So these are all of the associated
17:25Classes for that Instance.
17:27So all the associated data around what we originally
17:30passed in here which was the logical disk.
17:32Now you could also get something specific.
17:34So we could do something like this Get-AssociatedInstance
17:38for Disk1, and we can pass in the ResultClassName here.
17:42And let's say we only really cared about the disk partition,
17:45we can do Win32_DiskPartition, use a little Tab
17:47completion there since we're dealing with the CIM
17:49commandlets.
17:50And there we go, we just get back that specific Instance.
17:53Let's do one more example of Associations here.
17:55Just a little bit different of an example but same idea.
17:58Let's say that we wanted to get all of the dependent Services
18:00from a Service.
18:01Let's create a Service Variable.
18:02And let's put inside of the Service Variable
18:04the Result of Get-CimInstance.
18:06And how about for the Win32_Service
18:09is going to be our Class there.
18:10And let's just add a Filter on here.
18:12Let's say our Filter is going to be again Name.
18:14So Name, Like, and then double quotes here,
18:18and we'll end it with a single quote,
18:19the Name's going to be Like how about WinRM, the WinRM Service.
18:22Now notice a couple of things.
18:24Number one, whenever we're dealing
18:25with a query inside of a query, our query inside of here we
18:28start with our single quotes, then we have double quotes
18:30around the string.
18:31Also use percentages for wild cards
18:33because again we're dealing with the WMI query language here.
18:36So we're going to put that inside of a Service,
18:38let's just make sure that we have that,
18:39we just look at Service here, boom, there is.
18:41So there's our Service for WinRM.
18:43And now let's say that we wanted to get the Associated
18:45Instances with this.
18:46Let's do a Get-CimAssociatedInstance.
18:49And we're going to pass in as an InputObject Service.
18:53And our Association is going to be Win32_DependentService.
19:01We Enter and there it is.
19:02So the WinRM Service depends on the HTTP service.
19:07Cool.
19:07Now what about Methods?
19:08How do we call Methods on these CIM Instances?
19:12Well, first let's get a list of Methods.
19:14I'm just going to create a Variable called P.
19:16And inside of here we'll do a Get-CimClass.
19:19And let's get the Class here for the Wind32 Process.
19:22All right, that looks good.
19:23And all we need to do is a P dot-- and look here,
19:27we can get Methods, Properties, and all kinds
19:29of other information.
19:30Let's say we wanted to see a list of all the Methods.
19:32Here they are.
19:33Here's all the things we can do with a Process,
19:35Create, Terminate, Get-Owner.
19:36Let's say we wanted to get the owner of a specific Process.
19:39Take our PowerShell Instance here that we're working with.
19:42So let's create another Variable.
19:45We'll call this one A, we'll say Get-CimInstance.
19:49The Instance we're going to get here is a Win32 Process.
19:52Let's add the Filter on here, and let's just
19:54do a Name like, how about PoweShell,
19:57or we'll just do Power.
19:58So, Power.
20:00Here we go, that should do it.
20:01So do we have anything in there?
20:03We do, there it is, the PowerShell
20:04IC what we have right here.
20:06So now all we need to do is pipe this to a little Method known
20:10as Invoke-CimMethod.
20:12There it is, Invoke-CimMethod.
20:14What Method we would like to invoke?
20:15Here's our MethodName, let's say GetOwner, and there it is.
20:19So remember, we have this Invoke-CimMethod
20:22because we're dealing with a stateless environment.
20:24So we need to take the Objects that have been de-serialized
20:26at our local machine and pass them to this CimMethod
20:28in order to get them over to the machine to invoke
20:31the Method on these Objects.
20:33Let's finish this up with a couple of random things.
20:35The first random thing is Credentials.
20:38Now Get-WmiObject, in the WMI commandlet
20:40support the Credential parameter.
20:42Which is nice because you can prompt users for credentials,
20:45or you can supply your own credentials
20:47whenever you need to.
20:48Especially if it's something remote that requires
20:50maybe specific credentials.
20:52But the Get-Instances, in the CIM commandlets
20:56do not have that parameter.
20:58So imagine this is still because the CIM commandlets are
21:01relatively new, I'm sure eventually we'll get them.
21:03But that doesn't mean we can't use credentials.
21:06In fact this is where Sessions come into play.
21:08Now, before we even get into Sessions let's
21:10do something interesting here.
21:11Let's do a Get-CimInstance, and let's say
21:13we wanted to get all the Win32_Environment variables
21:17across multiple machines.
21:18So let's just pass in here, how about our DCNUGGET, our domain
21:21controller, and our file server.
21:22Cool, you know what that did?
21:24That just used remoting over HTTP to go to these machines--
21:28because, by the way remoting is enabled by default on Windows
21:31Server 2012 and that's what both of these machines are,
21:34so we didn't have to do anything special there.
21:36And remoting automatically adds this last column to anything.
21:39Which is awesome because now we can
21:41tell where these environment variables came from.
21:43These came from FSNUGGET, these came from DCNUGGET.
21:45And we're getting heavily into remoting and sessions, and all
21:48that stuff, in a future Nugget.
21:50In fact, it's actually the Nugget immediately following
21:52this one called Remoting.
21:53But that's great, but what if we wanted to supply a credential?
21:57This is where Sessions come into play.
21:58So if we can do a New-CimSession--
22:03we could pass in a computer name, let's do the same thing.
22:05Let's do ComputerName, let's do DCNUGGET,
22:07maybe we'll do APPNUGGET this time.
22:09And then let's also give the session name,
22:11we'll call it Servers.
22:12And here is where we can pass any credential parameters.
22:15So if you need to, passing credential there, and then
22:19give it a username here, let's do NUGGETLAB,
22:21backslash Administrator.
22:22And now if we hit Enter, it's going to prompt us.
22:24Cool.
22:25So that's really nice-- in fact let me just Escape there,
22:28and I didn't even have to supply the password because I'm
22:31already logged in under this.
22:32But what that did is it created two sessions, one
22:36for each one of the servers.
22:38Now this is where this really gets
22:40powerful is if you wanted to maybe hit a down level server,
22:44and you wanted control over the protocol.
22:47Because by default here we're using WS-MAN and HTTP.
22:50But what if we've got, again, a bunch of old servers out there
22:53that we want to manage?
22:54Well, we could create a SessionOption here,
22:56you can do this right here.
22:57A SessionOption, so can do a New-CimSessionOption,
23:02there we go.
23:03And now we could pass in the protocol,
23:05and we could say DCOM, look at that.
23:08So now, let's just hit Enter there,
23:09we create another Session.
23:11Let's create this, let's call this New-CimSession,
23:13pass in the computer name here, we
23:15can just call this old server.
23:17And let's hit up our APPNUGGET here,
23:19we're going to hit our APPNUGGET using DCOM.
23:21And then we can pass in the session parameter
23:23here, SessionOption parameter, and pass in our SessionOptions.
23:28There it is.
23:29I totally messed up my screen here, so I fixed it
23:31and I got us back to where we were.
23:33So let's say that we wanted to use these Sessions.
23:35We've got our two Sessions here with the name servers.
23:38So if we want to use those we could do a Get-CimSession,
23:41Get-CimSession.
23:42And we could get them by ID, by name, by computer name,
23:46let's say we wanted to get them by name here.
23:48We can do Name, pass in servers, and we can pipe these sessions
23:51over to Get-CimInstance.
23:54And let's say the same thing Win32_Environment, cool,
23:58and there it is, same results.
23:59Now if we want to use our-- we'll
24:01called this our DcomSession, we could do the same thing, only
24:04let's pipe in the Name, I believe
24:06it was CimSession three, CimSession three.
24:10And here it is, same result. And it was CimSession three,
24:12we can actually verify that right here, CimSession three.
24:15So that actually used DCOM there to hit up our APPNUGGET server
24:19with that previous command.
24:20So CIM Sessions are very cool, and they stay out
24:23there so we can continue to reuse and again.
24:25We'll get more into that when we talk about remoting.
24:27That's about it for this Nugget my friends.
24:29One thing I want to point out before I give you
24:31the challenges, is that, again, the commands .Ps1 file inside
24:35of the directory for each respective Nugget here
24:37in the NUGGETLAB files, contains all the commands that
24:39we've worked with throughout that video.
24:41And I just want to point out for this one I also added Help
24:44for each major commandlet.
24:45So here's GetHelp for CimClass, GetHelp for Get-CimInstance,
24:49for AssociatedInstance, as well as New-CimSession.
24:52So definitely dig into the help files
24:54get familiar with the syntax and some of the parameters
24:56in there.
24:56Because it would be impossible for us to cover them all,
24:59there's just so many.
25:00All right, your challenges for this Nugget.
25:02Challenge number one, less of a challenge more of a task.
25:04Use WMI Explorer to explore Classes, Instances,
25:08and Properties.
25:09So just get familiar with that fantastic tool,
25:11it'll go a long way in your future with PowerShell.
25:14Challenge number two, use WMI Explorer to find the Class
25:17for working with BIOS.
25:18Then use the CIM commandlets in PowerShell
25:20to retrieve all of the Instances properties.
25:23And challenge number three, this is a good one.
25:25Use the PowerShell CIM commandlets
25:26to query for a physical drive and change the label
25:30the volume.
25:31Now the reason this is cool, and a little bit tricky,
25:34is because we didn't cover Set-CimInstance to change
25:37the value of a property.
25:39So do a little discovery and exploration, get help on this
25:42to see how to do it.
25:43But essentially what you're going to do
25:44is create a drive variable, store
25:47the results of Get-CimInstance for the Class that
25:49contains a physical drive.
25:51Then pope that variable-- yeah I'm
25:53sure the Pope would love variables.
25:54Pipe that variable to Set-CimInstance
25:57and set the VolumeName property.
25:59And also, optionally here, you can use the pass through switch
26:01so you can see the results of the operation.
26:03Or you can just go into Windows, look at the file system
26:06and see if that drive label was changed.
26:09So this also just shows some of the power
26:10of working-- having access to the WMI repository
26:14is a big deal.
26:15Because if you can't do it using the regular commandlets
26:17you can certainly do it using the repository.
26:20And not only is it a place to see all this information,
26:22but you can see we've got Methods
26:24on many of these Classes.
26:25So we can actually do things.
26:26We can create new ones, we can modify existing ones,
26:29or even remove things, Really, really powerful stuff.
26:32All right, good luck.
26:33In this CBT Nugget we covered WMI & CIM, otherwise known
26:36as Windows Management Instrumentation and the Common
26:39Information Model.
26:40We saw that WMI is really just Microsoft's own layer
26:43on top of CIM standards.
26:46And that's all we had in PowerShell 1 and 2
26:47so that's what we used.
26:49But now with PowerShell 3, 4, 5, and going forward we've
26:52got CIM commandlets.
26:54Which are based on HTTP, as well as WS-MAN,
26:58firewall friendly protocols.
27:00Where WMI was based on DCOM and RPC,
27:03not very firewall friendly, definitely legacy.
27:06And they're really only there for backwards compatibility.
27:09So we saw how CIM works.
27:10We took a good look at all the major CIM commandlets,
27:12and we saw that awesome tool, WMI Explorer.
27:15I hope this has been informative for you
27:16and I'd like to thank you for viewing.
Remoting
0:00Remoting.
0:01Now we're starting to get into the cool stuff.
0:03And remoting is the coolest of the cool.
0:04This is the reason that people are
0:06going to be moving to PowerShell right here.
0:08Because remoting is what enables us to write a command
0:10and send it to many, many machines.
0:12So the productivity gains alone from this are astronomical,
0:15and you certainly don't need to be a PowerShell ninja
0:18to take advantage of this stuff right now.
0:20So let me ask you a question.
0:21How do you manage a bunch of machines?
0:24Let's say, for instance, that we've
0:25got a cluster of IIS servers out there, or maybe
0:27database servers, or SharePoint servers, or whatever.
0:30And something happened, you need to make a configuration change,
0:32or maybe you need to patch all these machines.
0:34How would you do that right now without PowerShell?
0:36Let me guess, you probably have an RDP connection manager
0:39out there with all of your RDP sessions,
0:41and you would log into each one of those machines
0:43individually to do that, right?
0:45Definitely, probably, what most people
0:47do without PowerShell skills.
0:48Or maybe they fire up an MMC snap-in
0:51and connect to all those machines individually.
0:54Definitely not the way we want to do that going forward.
0:56The way going forward is using PowerShell.
0:59One command, hit all of those machines
1:01without ever having to physically log in
1:04and do anything to them.
1:06Very, very cool stuff.
1:07Let's see how it all works.
1:08So what is remoting?
1:09We know that it's the super tech that
1:11allows us to execute PowerShell commands remotely.
1:13But really, what it is, it's just simply
1:15the WinRM service the Windows Remote Management Service.
1:18This is based on the WS-Man protocol, the Web Services
1:21Management Protocol, which is another open standard defined
1:24by the DMFT for communication across the wire.
1:28It's based on SOAP, which is what web services are based on,
1:30the Simple Object Access Protocol,
1:32which just basically means that our objects are serialized
1:35into XML.
1:36XML is the only thing that's transmitted across the wire,
1:38and then that XML is deserialized back
1:40into an object at the source.
1:42And the real key thing here is that it
1:43uses HTTP or HTTPS for communication,
1:47which is great, because as we know,
1:48HTTP is firewall friendly.
1:51As opposed to that computer name parameter
1:53we've seen on some command lines in the past,
1:55which use DCOM and RPC.
1:56So here's how this works inside of WinRM.
1:58When we enable remoting, which I'll show you how to do,
2:00even though it's enabled automatically on Windows
2:02Server 2012 and above machines.
2:03But when you do enable it, the first thing it's going to do
2:06is set this service, services start mode to automatic.
2:10Then it's going to create four end points.
2:12And end points are also known here
2:13in remoting as session configurations.
2:16And it really just defines the application,
2:18and there's some other options in there.
2:19And we can actually set some options too.
2:21We can control who or who cannot connect to it,
2:23what commands and scripts they can run, the security context.
2:26It must run under that kind of thing.
2:28So it's going to create these end points.
2:29Then it's going to create a couple of listeners.
2:31It's going to create one for HTTP, one for HTTPS,
2:33and it's going to bind them to the IP addresses
2:35on your machine.
2:36So when the requests come in, say
2:37a request goes over the HTTP line,
2:40that listener is going to accept that request
2:42and forward it to whatever end point or session configuration
2:46is set up for that application.
2:48Then it's going to run the command on the machine,
2:51take those objects, serialize them into XML,
2:53and send them back to the client machine
2:55where it will deserialize them into objects,
2:57and we'll have our results.
2:59So that's really the basics behind remoting.
3:01It's just simply the WinRM service,
3:02which handles all of the communication
3:04and transporting of our commands and objects
3:07across these machines.
3:09So what can we do with it?
3:10Well, we can do a number of things.
3:12We've got one-to-one remoting, which is just basically,
3:15for all you Linux folks out there, it's SSH in Windows.
3:18That's all it is.
3:19So in PowerShell, we can enter a PS session,
3:22which will literally put us right on that machine
3:25in our PowerShell console.
3:26And all the commands we execute are actually
3:28getting executed on that machine.
3:29There's also one-to-many remote management.
3:32And this is the really powerful stuff,
3:34because this is what's going to allow us to write one command,
3:36send them to all those machines, and then those machines
3:40will do all the work and send the results back to the client.
3:43Let's get familiar with many of the commands
3:45that you'll be working with here when
3:47working with remote commands.
3:48And then we'll get into Virtual Nugget Lab
3:50and play with many of these.
3:51So Enable and Disable remoting is how
3:53we turn remoting on and off.
3:55And you're essentially enabling or disabling the WinRM service.
3:58Then, we've also that enter EnterPSSession
4:00and ExitPSSession.
4:00This is for one-to-one remoting, otherwise known
4:02as interactive sessions.
4:04So we Enter PSSession, pass in a computer name,
4:06and we are literally on that machine just like we were
4:09SSH'ed into it.
4:10We exit it, boom, it's gone.
4:11That session is destroyed.
4:13We also have InvokeCommand.
4:14This is your one-to-many here.
4:16And this is how we're going to send a command
4:19to many, many machines.
4:21And we can do so by just sending a script block.
4:23So we just pass in a command.
4:25Or we can even pass in a files, so we can send whole scripts
4:27over to remote machines.
4:29We also have the ability to create our own sessions, which
4:31is extremely useful when you want
4:33to maintain state across calls.
4:35Because if we were just run an InvokeCommand
4:37and pass a command over, it'll spin a PowerShell
4:39in the remote machine, execute that command,
4:41then spin down PowerShell and send us the results.
4:44Meaning, if we were to declare a variable,
4:46and then come back that machine again,
4:47that variable would be gone.
4:47Or if we were to import modules, those modules
4:49would be gone, because everything
4:51is session based, right?
4:52So this allows us to save our session,
4:54and then we can just disconnect from it,
4:56and then reconnect to it later, maybe from another machine,
4:58and our state will be there.
4:59Our PowerShell session will be intact with everything
5:01that we did inside of it.
5:02Kind of like RDP.
5:03If you were to RDP into a machine, you log in,
5:07you open some tools, and then you
5:09disconnect, rather than log off, that allows
5:11you to come back later.
5:12And your machine will be in that exact same state.
5:14You'll be logged in, all your tools will be there.
5:16So you won't have to go through that process all over again.
5:18That's what sessions bring to the table here in PowerShell.
5:21All right, I'm sure you're ready to see this stuff in action.
5:23Let's do it.
5:24Let's jump over to the Virtual Nugget Lab
5:25and look at all the cool things we can do with remoting.
5:28And we're back.
5:29So the first thing we need to do is enable remoting.
5:30And remember remoting is enabled on Windows Server 2012
5:33and above automatically.
5:34So here's our App Nugget server already enabled,
5:36DC Nugget already enabled, FS Nugget already enabled.
5:39But our client machine here, it's not enabled.
5:41And you can actually easily figure that out
5:43by just running a get PSSessionConfiguration.
5:46And if you hit Enter there and it's not,
5:49it's going to say hey, WinRM service is not started,
5:51and running this command will start the service.
5:53So we're actually going to say no there.
5:55You can also just look at the service.
5:56It gets service.
5:57Let's look at WinRM here.
5:59There it is.
5:59We can see that it is stopped.
6:01If we go to our other machines, let's go to our server machine
6:03here, and do the same thing-- let's
6:04just do a get PSSessionConfiguration.
6:07It's going to send back end points if it's enabled,
6:10and it is, cool.
6:10Or we could do the same thing here, get service winrm.
6:13And look at that.
6:14There it is.
6:14It is running.
6:15So it's enabled there, not enabled on our client machine.
6:18Not that we would need to enable it on our client machine,
6:19but just to show you how the process works and what it does,
6:21let's do it anyway.
6:22So we're going to enable PSRemoting.
6:26There it is.
6:27Hit Enter.
6:28It's going to walk us through a couple things here.
6:30So the first thing it's going to do
6:31is run this set WSManQuickConfig command list.
6:33Don't run this one by yourself.
6:34Always enable this through the enable PSRemoting command,
6:38because there's some other things that it does.
6:40But this is going to start or restart
6:41the WinRM set the startup type to automatic,
6:43create some listeners on all of our network cards
6:46for all the IP addresses, and then enable
6:48a Windows Firewall rule exception for WS-Man HTTP
6:52traffic.
6:52So we're going to say yes to that.
6:54And now, it's going to create those four end points.
6:56So it's going to run set PSSessionConfiguration
6:59to create the PowerShell end point.
7:01This is for the 64-bit version, the one we're in.
7:04So we're definitely going to need this.
7:05And then it's going to as us to do one for workflow,
7:07ask us to do one for PowerShell 32-bit,
7:09and then ask us to do one for Server Manager workflows.
7:11So we're going to say yes to all those.
7:12That will create all those end points.
7:14And now if we run get PSSessionConfiguration,
7:17it should come back with all those end points.
7:19Perfect.
7:20Not too bad, right?
7:20Pretty painless.
7:21Now the only caveat I want to point out there,
7:23if you're on an older operating system
7:24and you have a network card that's location
7:27is set to public, then it'll fail.
7:29But there is a way around that.
7:30And it is called SkipNetworkProfileCheck.
7:33So that's a workaround.
7:34Obviously, a better way to do that
7:35would be to change the network location out of public,
7:38but this will certainly get you there.
7:40All right, let's get into a one-to-one remoting here first.
7:43So this is really easy to do.
7:44Ready, enter PSSession, and give it the name.
7:47Let's create a session over to our file server.
7:50That's it.
7:51Now, look at that.
7:52We are on our file server as you can
7:53see, because our prompt now is prepended with this FS Nugget.
7:57Pretty cool.
7:58So now we can change directories.
7:59Let's just change right over to the files.
8:02And you know what this is, right?
8:03Yeah, we have our share set up on top of this
8:07that we've been hitting here for our Nugget Lab files.
8:09So we can just do a DIR there, right in that psv4.
8:13Check it out.
8:13There's all our files.
8:14We are on our file server right now,
8:16even though we are technically on our client machine
8:19here, CL8 Nugget.
8:20But that's as easy as it gets.
8:22Enter PSSession, give it the computer name,
8:25and this is called an interactive session,
8:26one-to-one.
8:27It's just like SSH'ing into the machine.
8:29If we want to leave, we do an exit PSSession, and we're gone.
8:32We're back to where we were.
8:34Now, what about one-to-many remoting.
8:36If you're not already familiar with this command line,
8:37you will be getting very familiar with it.
8:38In fact, this will be your favorite command line,
8:40I guarantee it, going forward.
8:41So invoke Command.
8:43We're going to pass in a script block.
8:45We could also pass in a file path.
8:46I'll show you that one in a second,
8:48but let's do a script block here.
8:49And in the script block, what remote command
8:51do we want to send over here?
8:52Let's do something a little different?
8:53How about get windowsFeature.
8:55This is a good one.
8:56And let's say we want to see if the web server role is
8:59installed on multiple machines.
9:01Now we're going to use that computer name switch parameter
9:04and pass in some computer names.
9:06Let's see, let's look at DC Nugget, App Nugget.
9:08Let's do all of our servers here.
9:09And what's our last one, oh yeah, FS Nugget,
9:12our file server.
9:13So what we're seeing here is we want to send
9:15this command to these machines.
9:16And this is a remoting command line.
9:18So this is not using RPC and DCOM.
9:20This is all using HTTP.
9:22All right, we hit Enter.
9:23And now it's going to go all of those commands
9:26ran on those servers.
9:28How cool is that?
9:28They all did their own processing
9:30and sent us back the results.
9:32Pretty crazy.
9:33But here's the results.
9:34None of those have IIS installed on them.
9:37We'll change that later on in this Nugget.
9:38How about another one?
9:40Let's do an invoke Command here.
9:41And this time, let's just pass in a file path.
9:43So this will be great when you want to pass in scripts.
9:45And I actually have one here.
9:46It's not a full blown script, but we'll
9:47start to create scripts very soon,
9:49once we get into scripting.
9:50But just to show you, let me open this with Notepad here.
9:52It's just simply a one-liner that'll create a directory
9:55called /logs on the C drive.
9:57So let me copy this location here.
10:00And I'll just paste that into here, and let's do this,
10:03it's called create-logdirs.ps1.
10:06Oh, there it is.
10:07I can just auto complete there.
10:08Perfect.
10:09Now we just need to specify the computers
10:10we're going to run them on.
10:11Let's run them on everything, DC Nugget, App Nugget,
10:14and FS Nugget.
10:15Hit Enter, and there it is.
10:17Look at that.
10:17How ridiculously powerful is that?
10:20I feel like we should be in Windows version
10:232050 or something, because it was
10:25way too easy to create a directory across all
10:28these machines in one go.
10:30Absolutely incredible.
10:31In fact, we can just verify that.
10:32Let's go over to App Nugget here.
10:34Let's go into the C drive.
10:35Look at that, logs directory.
10:37Here's our domain controller, C drive.
10:40Oh, it's a little slow, there we go.
10:42Logs directory.
10:44And then, obviously FS Nugget would have the same result.
10:46But really, really neat stuff, and very simple to do.
10:50And a really great thing about this Invoke-Command commandlet
10:52is it automatically adds the property
10:54to the end of whatever objects are coming back,
10:56PSComputerName, so you know exactly what computer
10:59that data is referencing.
11:00Now, here's the thing though with the way
11:02we've been using it, is it literally just spins up
11:05a PowerShell session on the remote machines,
11:07executes a command, and tears it down.
11:09So if we wanted to do something across commands,
11:13we would lose our state.
11:14And this is where sessions come into play.
11:16But just to prove that, well let's run an invoke Command.
11:19And let's just do a script block here.
11:21And inside of here let's store instead
11:23of a variable here called w.
11:25We'll set this equal to get service.
11:26Let's get all the Win services here.
11:29Perfect.
11:30And let's just execute this across a couple of machines.
11:32How about App Nugget and FS Nugget.
11:35Perfect.
11:35So that executed.
11:36Now, let's do another one, only let's just
11:38get the result here of w, see if anything is in it.
11:41What do you think?
11:42What's going to happen?
11:43Nothing.
11:43There's nothing in it.
11:43How come?
11:44Because that's how invoke Command works.
11:47It literally spins up PowerShell, executes it,
11:49spins it down, send us the result.
11:50So that's why we have no persistence across these.
11:54And this is where sessions come into play.
11:56So let's create a session here, a new session,
11:58and store this inside of a variable called DC.
12:00We'll do this for our domain controller.
12:02So new PSSession, and we're going
12:03to connect right up to DC Nugget.
12:05All right, there we go.
12:06So now if we do a DC here, we can see that's a session.
12:08In fact, if we do a get session, we've
12:10got a session out there ready to go.
12:12So now let's enter the session.
12:13Enter PSSession, only this time we're
12:15going to pass in that variable.
12:17Oop not DV, DC.
12:20There we go.
12:20And look at that, we are now connected to that session.
12:23So now let's create a variable, just like we did before,
12:25logs in, let's just do get EventLogs here.
12:27And let's do this for the system.
12:30Let's get the newest 10.
12:33Perfect.
12:34So now it's in there.
12:34We can verify that if we look at the logs.
12:36Variable, there they are.
12:37Perfect.
12:38So now, let's exit this session, exit PSSession.
12:41We're out of it, and now let's disconnect from it,
12:43disconnect PSSession.
12:45And we're going to pass in our DC variable there.
12:48And now, it's in a disconnected state.
12:51So now, we could-- maybe we had to go somewhere,
12:53but we still want to maintain our state there for later.
12:55Or maybe we're even switching machines
12:56and we're going to a different part of the building.
12:58But we still want to connect to that.
12:59Well, what we could do is lets mimic that by firing up a brand
13:02new PowerShell session.
13:04If we do a get PSSession here, it's not going to see it.
13:07See that?
13:07We actually need to specify the computer name that it's on.
13:10So let's see all the sessions on our DC Nugget machine.
13:13Hey, there it is.
13:13All right, let's do the same thing,
13:15only let's put that into a variable called newdc,
13:17and boom, now we've got a session.
13:19We've got that session stored inside of a variable.
13:21Now we can do something like this.
13:22Let's do an invoke Command, and we'll just
13:24do a script block here.
13:26And let's see if we get that logs variable in here.
13:28We called that logs, right, log or logs.
13:30Hopefully it's logs.
13:31But we're going to set that over there,
13:33and we're going to use the session parameter here
13:36to pass in our new DC session.
13:39Oh, and it didn't like that because, anybody, anybody?
13:42Know why it didn't like that?
13:44Read the error message.
13:44The session state is disconnected.
13:46We need to, first, connect it.
13:49So let's just recall a couple of commands here.
13:51And let's just pass this all into connect PSSession.
13:57That'll get it back up and running
13:59and store that in there.
14:00Now this'll work.
14:01Invoke Command script block.
14:03Let's see if we can get that logs variable here.
14:04We're going to pass in the session of newdc,
14:06and hey it worked.
14:08So cool.
14:09That's what sessions are all about.
14:10They allow us to maintain state across calls.
14:13They allow us to move around, fire up new sessions,
14:15go to another machine, go to another part of the world,
14:18and still connect and again, maintain all that state.
14:21Now, one really cool thing that I want to show you,
14:23this is really powerful stuff here, is implicit remoting.
14:26This is the future of remote management right here.
14:30The whole idea of implicit remoting
14:32is that I don't ever need to install tools on a client
14:35machine I don't need.
14:36To give you an example of that, take Active Directory.
14:39I don't need to install RSAT on this CL8 Nugget machine.
14:42Wouldn't it be great if I could import modules from my servers,
14:47like import the Active Directory module from my domain
14:49controller onto to this machine here, and then use those
14:53as if I had those modules loaded an installed on this machine.
14:56That's what implicit remoting is all about.
14:58It's going to allow us to just have
15:00these dumb clients with nothing installed on them,
15:02and any time we need to utilize tools from another machine,
15:05we just pull them over.
15:07And it's going to create, essentially, proxies
15:10to those commandlets in that module.
15:12And we can use them on those machines
15:14as if they were installed on this machine.
15:16And I'm going to give you this example using IIS and the IIS
15:19commandlets.
15:19So the first thing we're going to do
15:21is install IIS on our App Nugget machine.
15:23So let's do an invoke Command.
15:24We're going do this all using remoting, of course.
15:26And let's do a script block here.
15:28And our script block is going to be Install-WindowsFeature.
15:32We're going to install the role web server.
15:34All right and let's pass that over
15:35to the computer name, App Nugget.
15:38There we go.
15:39So what that's going to do is it's
15:40going to install IIS our App Nugget machine, which will also
15:45install all the IIS commandlets.
15:47And then I'm going to show you how
15:48we can use implicit remoting to get all of those IIS
15:50commandlets onto our client machine
15:52here without actually installing them.
15:54They're really only going to be installed on App Nuggets,
15:56but we're going to use them is if they
15:58were installed on this machine.
16:00Perfect.
16:00There it is.
16:01All done.
16:01Success.
16:02We've got to IIS all up and running over there
16:05on App Nugget.
16:05And now, just to prove a few things,
16:07let's head over to App Nugget here.
16:08And let's fire up PowerShell.
16:11And let's see if we have those modules installed.
16:13So let's just do a-- how about a help here on get website.
16:16I know that's an IIS commandlet.
16:17And there it is.
16:18We got help on it.
16:19So we know that it's there.
16:20And now, if we just Control C out of this,
16:21let's do just a get module here.
16:23Let's see, we got web administration.
16:24There it is.
16:25These are all the IIS commandlets.
16:27So that module is loaded up here.
16:28And all those commandlets are here.
16:30We didn't actually need to do that.
16:31We didn't need to physically load
16:33up the module on this machine.
16:35It's already installed and it's there.
16:36So now if we go back to our client machine,
16:38let's do the same thing help, oop,
16:39here we go, help get website.
16:44It's searching help for get website.
16:46And look at that, can't find it, can't find it
16:49because we have no module.
16:50We don't have that module.
16:51In fact, we could even do this, get module,
16:53or we could just search for-- we could just do a search here.
16:55Let's do a get- command- module- web administration.
17:00Nothing.
17:00Nothing at all.
17:01All right, so here is implicit remoting.
17:02Here's how it works.
17:03First, let's get a session going here.
17:05Let's create a session.
17:06We'll call this newps session, and we'll
17:08create this to App Nugget.
17:09All right, so now we've got a session ready to go.
17:12So here's the trick.
17:13We can do an import module.
17:15Web administration was the name of that,
17:17yeah, web administration.
17:18And then, we're going to use the PSSession parameter
17:21and pass in that session.
17:24So what this is doing now is it's actually
17:26creating shortcuts on our local machine
17:28here to the module, all the commandlets, everything
17:31inside of that web administration module
17:33that is installed over on our App Nugget machine.
17:36So now if we do a help get website, it should work.
17:40Look at that, there it is.
17:41And now if we call get website, it should work.
17:44It's actually getting the website over there
17:46on our App Nugget machine.
17:47How cool is that?
17:48So that's all done through the magic of remoting.
17:50Its all done under the hood, hence implicit.
17:52It's actually exporting and importing.
17:54There's actually two commandlets importPSSession,
17:56exportPSSession.
17:57It's just totally, basically automating that process for us.
18:01And it's importing those commandlets from that machine
18:04and giving us a way to access it remotely.
18:06But this is so cool that now we no longer
18:09have to manage software on all of our machines.
18:11We don't have to install these modules,
18:13and install any specific management software,
18:16on our client machines.
18:17They can stay clean and empty, meaning
18:19it'll just make it so easy for us
18:21if we, oh look, there's a machine over there.
18:24Man, I wish I could use that to hit my servers,
18:27but I don't have all my tools installed.
18:28Well guess what?
18:29With this, you don't.
18:30Fire up PowerShell.
18:31As long as remoting is enabled, you
18:33can easily do things like this.
18:34Just import the module from that machine, and boom,
18:37you've got everything you need without having to install
18:40everything to work with it.
18:41Very, very, very powerful stuff.
18:43So that remoting in a nutshell.
18:44Here's all the commands we used in this Nugget.
18:46Go through some of these.
18:47Especially go through the help topics
18:48for things like invoke Command.
18:49That is a very deep commandlet with a lot of options,
18:52and there's a lot of things you may come across,
18:54especially things like the throttle limit.
18:56By default, we can hit up to 32 machines.
18:58You can up that by using the throttle limit
19:01to as many connections, or threads I
19:03should say because it's a thread per connection,
19:05that your client machine can handle.
19:06Check out things like use SSL.
19:08That's another big one, especially
19:09if you want to hit machines are outside of your domain.
19:12You'll need to set up SSL to do so.
19:15Or if you want just a secure connection over HTTPS,
19:17then you can do it that way.
19:18And there's a lot of other ones, so certainly scan
19:20the help topic.
19:20Get familiar with some of those parameters
19:22because they can be very useful.
19:24Let's look at the challenges for this Nugget.
19:25Challenge number 1, connect to another machine using
19:27an interactive one-to-one session,
19:28get services, and exit the session.
19:30Pretty straightforward here, just
19:32getting you familiar with enter PSSession and exit PSSession
19:35to create that one-to-one interactive session.
19:37Challenge number 2, run a command
19:39to view the most recent 10 system event
19:41logs across multiple servers using invoke Command.
19:43Another straightforward one that we
19:44did, just getting you familiar and comfortable there
19:46with working with invoke Command.
19:48Challenge number 3, create a new session to another machine,
19:51store a list of processes in a variable,
19:52disconnect from the session, then reconnect
19:54to the session from another PowerShell instance
19:56and view the variable.
19:58Then exit and remove all sessions.
20:00All things we've done in this Nugget just
20:01to, again, all three of these challenges just
20:03getting you comfortable with all the different perspectives
20:06of using remoting.
20:06Again, you can find the answers underneath these regions,
20:09and you can find these challenges inside of the Nugget
20:11Lab files for this course, down-loadable on the right hand
20:14side of the page.
20:15Good luck.
20:16In this CBT Nugget, we covered remoting
20:17and got a glimpse into the future of remote management
20:20at scale.
20:21Remoting allows us to send PowerShell commands
20:23to many machines without having to really do any work.
20:26It's just like writing commands like we have been.
20:29It's just that we can target many machines, which
20:31is just incredible.
20:32So we saw that remoting is really
20:34just the WinRM service, which is basically WS-Man protocol,
20:37uses HTTP and HTTPS, exposes end points,
20:40and creates listeners for communication.
20:42And then we saw all the different ways
20:43that we can use remoting, from one-to-one, to one-to-many,
20:46and even got a taste of implicit remoting.
20:48I hope this has been informative for you.
20:50And I'd like to thank you for viewing.
Jobs
0:00Jobs.
0:01And we're not talking about your nine to five here--
0:03even though PowerShell's obviously
0:05going to help us out quite a bit with our nine to five--
0:07but we're talking about PowerShell jobs.
0:08And we've got a bunch of different PowerShell jobs
0:11out here, ones that allow us to run
0:13our commands in the background-- great for those long
0:15running tasks, so we're not locking up our Shell-- as well
0:18as scheduling jobs, so we can automate a lot of the things
0:22that we're doing in PowerShell.
0:24So let's jump right in.
0:25Let's get familiar with the different kinds of jobs
0:27that are out in PowerShell, the purposes that they serve,
0:30and then we'll get into a demonstration
0:31here to show you how to use each type.
0:33So you can see we have a lot of different kinds of jobs
0:35here in PowerShell, background, remote, workflow,
0:37schedule, there's even one I didn't add in here called WMI
0:39jobs.
0:39But here's the thing, they're really
0:41just all the same thing underneath the hood, right?
0:43They are asynchronous background processes.
0:46The big difference is scheduled jobs
0:47are persistent asynchronous, meaning
0:51we can make them repeatable and run them more then once, right?
0:53Run them on a schedule, run them on a specific interval,
0:55whatever.
0:56But asynchronous means that we are
0:58taking anything, a command, a script, whatever,
1:02and pushing it to the background.
1:04That way, we're not locking up the UI, right?
1:08We're not locking up our session waiting for a long running task
1:12to complete, we can just throw it in the background,
1:14let it do its thing, check its status every now and then,
1:16when it's done, we can retrieve the results.
1:19That's what jobs are all about.
1:20And that's pretty much your basic workflow there with jobs
1:22as well.
1:23I'm going to bring up PowerShell just give you an idea.
1:24So let's say we were going to do something crazy here.
1:26Let's recurse, d, colon, backslash, d, colon, backslash,
1:28ah.
1:29So this would take all day long, right,
1:31to go through every directory and file
1:33and I'll put it here to the shell.
1:35So I'm going to cancel out of that.
1:36This is what jobs are about.
1:37So say that we had something like that,
1:38maybe not that specifically, but maybe we
1:40had a script that was going to take a long time to run
1:42but we still wanted to do things in the shell.
1:43Well, we could just start a job, we could pass in the file path
1:46to the script, or we could just pass in a script block
1:48here which is what we're going to, do the same thing.
1:51We'll recurse it and boom.
1:53Now it's just going to take a second to create the job,
1:55but it's running in the background
1:57so I'm free to do other things inside of the Shell here.
1:59So I could sit here and just continue to get the status,
2:02there it is, all right, running, running, running,
2:03or I could stop it here.
2:04Let's do a Get-Job and let's pass that to Stop-Job.
2:07Boom, and now if we get the job, it stops.
2:10And now if we wanted to see how far that job got,
2:14we could do a receive-- oh, i before e except after c,
2:17I'm always forgetting that with a Receive-Job-- ID 2,
2:20there's how far it got before we cancelled it.
2:22Cool.
2:23So what we just witnessed there was a background job.
2:25Background jobs are tasks running asynchronously
2:28in the background on the local machine.
2:31We also have remote jobs, and this is just
2:33our remoting commandlet, Invoke-Command,
2:35with the AsJob switch parameter turned on.
2:37If we do that, whatever machines we target
2:40in that Invoke-Command commandlet,
2:41using the computer name parameter,
2:43will get their command sent to the background
2:45and store it inside of a job that we can reference,
2:49manage, and view the results from our local machine,
2:51the machine that we kicked off the Invoke-Command commandlet
2:53from.
2:54We can also set up our workflows to run
2:56as jobs, which is very cool.
2:57If you're unfamiliar with what workflows are,
2:59we've got a Nugget in this course dedicated to workflows,
3:01so check that out.
3:02But essentially it allows us to take
3:05a bunch of scripts, or a bunch of commands,
3:08and coordinate them.
3:08Run them in parallel, run them in sequence,
3:11run them across machines.
3:12We can do check pointing, so if we have a really big process,
3:16we can checkpoint after the long part
3:17so if something bad were to happen later in the script,
3:19we can restart it from that point.
3:21Really, really cool stuff, so definitely
3:22give workflows a look.
3:24Last, and certainly not least, and probably most useful here,
3:27are scheduled jobs.
3:28This is what's going to allow us to automate
3:30those repeatable tasks.
3:31So a scheduled job is one that persists,
3:33meaning we're going to set it up on a schedule
3:36and it's going to run on that schedule.
3:38And that's what's also by the way known as a job trigger.
3:40So we're going to set up a trigger, which
3:42is going to be run this daily at this time,
3:44or weekly on these days at this time,
3:46or whatever interval we can think of.
3:48And then we can set up job options as well,
3:50and it will fire up and run against whatever we have
3:55defined inside of the test.
3:56And it'll run on those times with that option.
3:59And you know what's funny is these
4:00are actually viewable and manageable inside
4:03of the Windows Task Scheduler.
4:04So that's all it's doing, it's just
4:05sitting on top of the Windows Task Scheduler,
4:07creating these jobs, and we can manage them from there,
4:09or we can manage them in PowerShell as well.
4:11So here's a look at many of the common commandlets
4:14that you'll be utilizing when creating and working with jobs.
4:16Just to go over a couple of them here, Start,
4:18Get, Stop and Receive-Job, these are all
4:21working with background jobs.
4:22And remember, everything is really a background job.
4:24So for instance, a scheduled job,
4:26it's really just a container that contains
4:28the options in the trigger.
4:29But when that job starts, it's really
4:31going to be a background job.
4:32And you can still manage these scheduled jobs that
4:34are running, the instance jobs as we call that,
4:36with these commandlets.
4:38Invoke-Command with the AsJob switch parameter
4:41is known as a remote job.
4:42But again, it's really just a background job
4:43in the remote machine that you fire up
4:45from your client machine, and manage from your client
4:46machine.
4:47And then, we've got lots of commandlets
4:49here to work with that scheduled job container.
4:52So Register and Unregister to Create, and Delete,
4:54Get for managing the containers, New-JobTrigger
4:57for creating schedules, and New-ScheduledJobOption
4:59for managing all the different options.
5:01Let's jump into the Virtual Nugget Lab
5:03and put some of these commandlets to use.
5:04All right, welcome back to the Virtual Nugget Lab.
5:06Let's jump right into the ISE here and start
5:08writing some commands.
5:08So let's start a few jobs.
5:16So this is very similar to the first one we did,
5:18the difference is we give it a name this time.
5:20And we just Get-ChildItem rather than dir,
5:22and we're just hitting the system drive environment
5:24variable rather than statically typing it in.
5:25But I'm going to hit Enter, and that's
5:27going to set us up with a job.
5:28So while that's running, let's create another one here.
5:31We'll do a Start-Job.
5:32Let's also give this one a name, we'll call this, ThisIsBad,
5:35and we'll add a script block in here.
5:36And let's just do a test connection here.
5:39There we go, test connection-- this will be like a ping
5:41essentially.
5:43And let's pass in the computer name for the ping here,
5:46how about we'll do Bad,NUGGET.
5:49So two machines, but we know those are both bad.
5:52So I'm going to hit Enter, and then that one's
5:54going to start as well.
5:55Now if we do a Get-Job, we should see both
5:56of these jobs and their states.
5:58Both of their states are running, so at this point,
6:01we could sit here and wait, or we could do some other things.
6:03But eventually, that state will change to complete,
6:06at which state we could go and retrieve the results
6:08to see what happened.
6:09If it succeeded, or failed, or whatnot.
6:11But we can actually stop a job too, here.
6:13Let's do a stop-job, and let's just do this by ID.
6:15We could do it by ID, we could do it by name.
6:17And we know that our big recursion one there
6:19is ID number 6, as we can see over here.
6:20So if we stop that, now it's going to get stopped.
6:23So now if we run a Get-Job, we can see that has stopped,
6:27and it has some data in there, which
6:29is going to contain the result of the operation.
6:32So this is where receive-job comes into play.
6:34So if we do a receive-job-- and again, there's a number of ways
6:37we could retrieve it.
6:38We could receive it by ID, by name.
6:40Let's just do name here, and let's do recur system drive
6:43as the first one.
6:44And then now, if we just run this right now,
6:46it's going to get those results and dump them from memory.
6:48So they'll be gone, and the HasMoreData flag
6:49will be switched a false, and you
6:51won't be able to retrieve the results any more.
6:53So this is why we've got a keep here.
6:54If you use the keep switch, it'll keep that data around.
6:57So here's the results from-- as far
6:59as it made it until we stopped it anyway--
7:01on recursing the system drive.
7:03Let me just cancel out of that.
7:04And if we do a Get-Job again, we should
7:06see it still has more data.
7:07So if we didn't run our keep-- run this with our keep switch,
7:11it would go away.
7:12So if we do this, cancel out of it, and then do a Get-Job,
7:15it no longer has more data.
7:16So we can no longer see the results of that job.
7:18So those are background jobs and that's pretty much
7:20your workflow there as well.
7:22Start-job will fire up that job container,
7:24put it in the background, and put your commander script
7:26inside of it.
7:27When it's done running, it will contain your results, which we
7:31can then get using Receive-Job.
7:32And then, of course, use Get-Job here
7:34to view the current state of all of your jobs.
7:36Oh, by the way, we didn't look at ThisIsBad.
7:38We know that this failed, so let me just
7:40show you the results of that.
7:41Again, we can do a Receive-Job here,
7:42and we could just pass in the name here,
7:44ThisIsBad, there we go.
7:45And we won't even keep it, we'll just look.
7:47So there it is, so there's the results.
7:49This time it was a failure, because Bad is not a host name
7:52and neither is Nugget.
7:54Cool.
7:54Next up, let's take a look at remote jobs.
7:57And this is going to be all about using the AsJob switch
8:00parameter on Invoke-Command.
8:02So let's do an Invoke-Command here, set up some remoting,
8:05pass in a script block, just going
8:07to throw in a quick script block here, Get-Eventlog.
8:09How about we get the system event
8:11log, how about the newest 10, for entry type error.
8:14Sounds good, great.
8:16And it will pass in the computer name parameter here.
8:18Let's do this across all our servers,
8:19DCNUGGET, APPNUGGET, FSNUGGET.
8:23And here's the trick, ready, AsJob.
8:26That's it, that's the trick.
8:28So just add that parameter to anything remoting
8:31that you do, and it'll spin this up
8:33in the background on all of those machines.
8:36We won't be sitting here waiting for that to finish
8:39in on any of those machines.
8:40So I've hit Enter.
8:41There we go, now it's running on all three of those machines.
8:44Now, here's another thing, if we do a Get-Job here,
8:46this is just going to show us the parent, the top level ones.
8:49Notice how it's skipping ID numbers here?
8:51The last one we did was 8, then 10.
8:53And now if we do another one, it would actually probably jump up
8:55to 14.
8:57Because what it does is it creates a ParentJob,
8:59and then the ChildJob is actually the task
9:02that's performing the work.
9:03And you can actually see this if we
9:04do a Get-Job -IncludeChildJob.
9:07Look at this, so here's our ParentJob, recurse file system.
9:10Here's the actual task that does the work,
9:11here's our ParentJob, ThisIsBad, here's
9:13the task that actually does the work.
9:15And then right here is our remote job,
9:18and because we sent this to three machines,
9:20there's going to be a task for each machine.
9:23So that's why it has a command for each machine going over
9:26there.
9:26All right, and also notice our PS job type here, remote job as
9:29opposed to background job.
9:30Oh, no, that failed.
9:32Look at that, our remote job failed.
9:33What did I do?
9:34Oh, this is a telltale sign right here.
9:36When you see a failed status and it doesn't have any more data,
9:38that's a good sign that is probably
9:40something syntax related.
9:42Because usually it will stay completed,
9:44and then it'll have more data which
9:46contains the error message.
9:46But if we head up here, those of you with sharp eyes
9:49probably noticed that I typed in newest one dash rather then
9:52newest 10.
9:52So let's come back down here, recall my last command here.
9:56There it is.
9:57And let's just fix that right there, turn that into a zero.
10:02All right, cool.
10:03Now it's running, now if we do a Get-Job,
10:06we should see that it completed.
10:09All right, its job number 14.
10:11So let's do a receive-job here, pass in the ID of 14,
10:15and let's do a keep on this because I want to show
10:17you something else as well.
10:18There it is, and look at that.
10:19So there's the results, there's the top 10 error system
10:22logs for each of those machines.
10:25But we could do this as well.
10:26Let's do a Get-Job, let's -IncludeChildJob.
10:29Say that we only wanted to retrieve
10:30the results for one of these tasks,
10:33we could do the same thing.
10:34Receive-Job, let's do it for, how about 17 there, we'll
10:38get rid of keep, and there we go.
10:39Just for FSNUGGET in that case.
10:41And if we do another one now, we don't have any more data
10:44here for this, so we couldn't go and get those results again
10:46because we didn't keep them.
10:48So that is remote jobs.
10:49Essentially they're just background jobs
10:51running on remote machines that we
10:52can kick off from our local machine using
10:54the power of remoting.
10:56Let's take a look at scheduled jobs.
10:59These are amazing.
11:00You will definitely be using these quite a bit here,
11:02especially if you want to automate any tasks.
11:04But just to show you the commands
11:05we are going to be working with here, let's do a Get command.
11:08The module therein is psscheduledjob,
11:10and there they are.
11:11So Register-ScheduledJob is how we're
11:13going to create a brand new scheduled job.
11:15We'll tie a trigger to it, we'll tie some options to it,
11:17and that will create it in Windows Task Scheduler,
11:19and then we can remove it using unregister.
11:22So we've got lots for working with job triggers here,
11:24for job options, and then also for the actual scheduled job
11:28itself.
11:30So our goal for the scheduled task,
11:31as I head over to our file share,
11:33is to keep our Help updated.
11:36So let's head over to FS Nugget PSP4,
11:38we've got this Help directory here, right?
11:40And this Help hasn't been updated
11:41been a while, since we did our Help Nugget.
11:44So our goal is to keep this updated.
11:46So every morning at 3:00 AM, we want
11:49a job to kick off that goes and does a Save Help
11:53and specifies this as the destination path.
11:55So our Help will be updated every morning, every day.
11:58And then in our client machines, we
11:59could have them spin up a job, put into their profile script,
12:02that in the background, the first time they launch
12:04PowerShell for the day, it goes and downloads
12:06help from this file server.
12:07Cool?
12:08All right, let's do it.
12:09So let's start by setting up our job trigger,
12:11and it'll just pass this variable right
12:12into Register-ScheduledJob.
12:13And we'll do the same thing with our job options.
12:16This will make it easier on the eyes
12:17when we're typing this all out.
12:18So we're going to a New-JobTrigger here,
12:20and there's all kinds of things we
12:21can do with this job trigger.
12:23We can do it daily, weekly, we can specify intervals,
12:26so we can do it every third day, every second week, there's
12:28so much we can do.
12:29Specify days of the week, specify users,
12:31we can do it at start up, at log-on, just once.
12:33We're going to do this one daily,
12:35so let's do it daily at-- here, there's
12:38the parameter at-- how about 3:00 AM.
12:41Perfect, so there's our job trigger.
12:42That was easy, that was our schedule.
12:44Now next, we want to set up a job options-- I'm
12:46going to do another variable here, we'll call this option--
12:48and we'll do -New job-- ScheduledJobOption,
12:51there it is.
12:52And here, just a bunch of options if you
12:53want to turn them on or off.
12:54Right, so here, let's say we want to wake to run,
12:57because if we're on a client machine like this,
12:59and we have those power options set and it's sleeping,
13:01it certainly won't wake to run.
13:03So this will make sure that it wakes to run.
13:04Let's do another one here, how about StartIfOnBattery.
13:08There's another one, perfect.
13:09So now we've got some options.
13:10Now we're ready to create the actual scheduled job itself,
13:13so let's do a Register-ScheduledJob.
13:16And let's give this one a name here,
13:17how about we'll call this GetNewestHelp.
13:20That sounds good, GetNewestHelp.
13:22This is going to be a script block,
13:24and that script bob-- script block is just
13:27going to be Save Help, right?
13:29Save Help, we'll give it a destination path
13:30here of our file server, fsnugget, psv4, backslash,
13:36help.
13:36There it is.
13:37That's it.
13:38So we just want to put this on a schedule.
13:40And then our trigger is going to be our t variable that we just
13:44created and our options here after scheduled job option is
13:48going to be our o variable.
13:50That's it.
13:51Done.
13:52Now, guess where you can see this?
13:54Sure, we can see it in our session
13:56here by running a Get-ScheduledJob,
13:58as I just did here.
13:58Not Get-Job, but Get-ScheduledJob.
14:01Remember, Get-Job will show us if it's
14:03running it will show up in Get-Job job,
14:05because these are the instances of it running,
14:08not the actual container.
14:09That's-- you'll need to use ScheduledJob to see that
14:12container.
14:12But you can also see it in the task scheduler.
14:15So if we do a search here for Task Scheduler,
14:17this is pretty cool.
14:18Expand task scheduler library, Microsoft Windows,
14:21head down here to PowerShell, there
14:23it is, and scheduled jobs.
14:25That there it is GetNewestHelp.
14:27So we've got some general information here,
14:29some more options you can work with.
14:31Here's your trigger, and you can modify this
14:32by going into properties if you want
14:33to change the schedule or anything else associate
14:35with your trigger.
14:36You have your actions, which in this case
14:38is just going to be you start a program,
14:39it's going to start PowerShell, pass in all the stuff
14:41that we defined when we set up the job.
14:43You've got your conditions, which
14:44are going to contain more of your power options,
14:45and idling options, and network options down there, settings,
14:48and history.
14:49So really cool that it does show up here,
14:52and it's just another layer on top of Task Scheduler
14:54that we can control all through PowerShell.
14:57Now, if we wanted to test that out and start that job
14:59rather than wait around till 3:00 AM, we can do a Start-Job,
15:02and we can pass in the definition name here.
15:05Definition name is going to be the name of the scheduled job,
15:08GetNewestHelp.
15:10There it is, and that is going to fire it up.
15:12So now we can use the standard job commandlets
15:15to work with this job.
15:16But right now, it's running and downloading all the latest help
15:19into our Help directory over there on our file server.
15:23So that will ensure that our Help is always the latest
15:26and greatest on that share.
15:28And then on the client side, which
15:29I'll show you how to do once you get into profile scripts,
15:31we could easily set up a background job
15:33to run when we fire up PowerShell to do an Update
15:37Help from that file share.
15:39And that way, we'll keep all of our clients nice and fresh
15:42with the latest and greatest help.
15:43Let's finish up by looking at the challenges for this Nugget.
15:46Again, you can find all the commands
15:47we worked with here inside of the commands.ps1 file
15:49for this Nugget.
15:50Here are your challenges.
15:51Challenge number one, start a background job
15:53on your local machine to retrieve the system event log,
15:55check the job status, and when finished,
15:57retrieve the results by ID.
15:59Pretty straight forward, they're just using a background job.
16:01So you'd be using Start-Job, and then
16:03remember to use Receive-Job, only pass in the ID
16:06parameter specifying the ID that was returned
16:09when you created the job.
16:11The second one here, start a remote job
16:13across multiple machines to retrieve the system event log.
16:16Check the job status, including ChildJobs, and when finished,
16:19retrieve the results.
16:20Use a variable to store and work with the job, then cleanup
16:23by removing all jobs.
16:24So same kind of deal as the first one, except you're
16:26going to be working with multiple machines, so there's
16:28going to be a lot of ChildJobs or child
16:30tasks underneath the ParentJob.
16:31And the big difference here is use a variable.
16:33So when you create the job using Invoke-Command,
16:35stuff it inside of a variable.
16:38That way you have a reference to the ParentJob,
16:40and you can use that to check the results
16:42as well as then retrieve the results.
16:45The other big one here, challenge
16:46number three, schedule a job to retrieve security event
16:48logs with an eventtype of error, daily at midnight.
16:51Run the scheduled job manually, view the results,
16:54and then unregister the scheduled job.
16:55So same thing we did in the first two,
16:56except rather than a local-- or remote job,
16:58this is going to be a scheduled job.
17:00So schedule a job to run at midnight
17:03that gets all the security event logs,
17:05run it manually, view the results,
17:06and then unregister it.
17:07And here all the steps here to help you out along the way.
17:10And as always, good luck.
17:12And don't forget, you can download all of the support
17:14files, all of our Nugget Lab files here,
17:16on the right hand side of the course page.
17:18In this CBT Nugget, we covered jobs in PowerShell.
17:20How to take commands and scripts and run them in the background.
17:25So we covered background jobs, remote jobs,
17:28and we even looked at scheduled jobs.
17:29I hope this has been informative for you,
17:31and I'd like to thank you for viewing.
Workflows
0:00Workflows.
0:01One of the greatest features that came out
0:02of PowerShell version three was integration with the Windows
0:05Workflow Foundation Engine.
0:07This gave us the ability to essentially turn commands
0:09and scripts into steps.
0:10And we can coordinate those steps
0:12across machine boundaries in parallel or in sequence,
0:15and we could even recover from failures.
0:18So it gave us a lot more flexibility and control
0:20over those long-running processes.
0:22So our goal for this Nugget is to get you up
0:24to speed on what workflows are all about, how
0:25they differ from scripts, and how we can write them.
0:28Let's do it.
0:29So workflows are special functions in PowerShell.
0:31And I know we haven't gotten into functions yet,
0:33but we'll cover them in great detail
0:34when we get into scripting.
0:35But they're very simply just a named block of reusable code.
0:38So in PowerShell we have a function.
0:39We start out by stating function as the key word.
0:42We give it a name, like get, dash,
0:44whatever using PowerShell naming conventions.
0:47And then we can accept parameters.
0:48We can define our parameters here,
0:50and then we list up some PowerShell code, right?
0:52And then what we call this, we call it just like a cmdlet.
0:54We call it by name.
0:55We pass it the parameters.
0:56And it gives us a way to reuse a block of code.
0:59Workflows are very similar to functions.
1:01In fact, they work the same way, except that we define them
1:03using the workflow keyword.
1:05We give it a name, we can define parameters,
1:07and then inside of here we set up
1:09steps which are commands or scripts that we can execute.
1:12But there's fundamental differences
1:14in how these two work.
1:15Functions are a PowerShell thing.
1:17Workflows are actually outside of PowerShell,
1:20inside of the .NET Windows Workflow Foundation Engine.
1:23So anything we do inside of here is actually
1:25going to get translated to that engine.
1:27That's going to mean things are going
1:28to work a little bit differently, as you'll see when
1:30we get into our demonstration.
1:31About the only thing that's similar between these two
1:33things is, it's a way for us to group commands together
1:35and call them by a name.
1:37There's a lot of differences.
1:38Functions are a PowerShell thing, right?
1:40They're executed by PowerShell.
1:41They are single-action processing.
1:43They start, they run, and they finish.
1:45And if something were to happen in between,
1:46like the power goes out or the network goes down, that's it.
1:49We've got to restart everything from the beginning.
1:52Workflows, however, because they're
1:54executed by the Workflow Engine, support parallelism.
1:56So we can execute commands in parallel.
1:58They can pause and restart.
2:01They can persist beyond computer restarts,
2:03whether it's by design, or whether the power goes out,
2:06or the network goes down, we can resume them,
2:09because we can create checkpoints within them.
2:11So think of workflows as that last thing
2:13you'll do to glue together a bunch of tasks, right?
2:17You have this huge process that contains many scripts
2:19and commands.
2:20And you want to coordinate everything, have it
2:22executed in a specific order.
2:23That's what workflows allow us to do.
2:25So here's an example.
2:26And these commands in here could also be scripts.
2:28So let's say that we've got four scripts that we need
2:30to run that make up a process.
2:32And they need to be run, at least two of them,
2:34in a specific order.
2:35They can all run at the same time, but we need at least two
2:37of them to run in a specific order.
2:39So here we go.
2:40We define a workflow, we give it a name here,
2:42get something cool.
2:43And then we define in a parallel block,
2:45saying commands one, two, we'll call this command two here,
2:48and command three, they can all run in parallel,
2:50as long as command 2-A executes before command 2-B.
2:54So if we visualize this, here we go.
2:56We start our workflow.
2:57So here's our workflow, up here.
2:59This, then, will be our parallel declaration.
3:01And inside of here would be our sequential declaration.
3:04So here's command one, here's command two with A over here
3:06and B over here.
3:08A needs to go off before B. And here is three.
3:10So all these would run at the same time,
3:12but command A would run before command B.
3:16So that's the general idea of a workflow.
3:18Now, let's turn this into something more real-world.
3:20So let's say that we had a fresh Windows server 2012
3:23machine, nothing on it, and we wanted
3:24to turn it into a Hyper-V machine,
3:26install a bunch of virtual machines,
3:27and then configure them, right?
3:29Maybe turn one into a domain controller,
3:31one into a database server, one into an IS server,
3:33a file server, all that stuff.
3:34So the first thing we would need to do,
3:36and this could just be a command,
3:38is install Hyper-V on that box, right?
3:41We could just use Install dash Windows
3:43feature, that cmdlet pass into Hyper-V, and do all that.
3:46Which would also, by the way, require a restart.
3:48Which right away, we couldn't do this from a function
3:50because that would ruin the whole function,
3:52ruin the whole process.
3:53But with a workflow we could certainly do it.
3:55Now the next step, then, we would maybe have a script.
3:57This would be a script called create-vms.
4:00And this would actually, physically
4:03create those virtual machines in Hyper-V. And then we
4:05would have another script here called configure-vms, which
4:07would install the specific roles on specific vms,
4:10and maybe this one would even require
4:12a little manual intervention.
4:13So we could do this, just like down here, except it would have
4:16sequence in parallel flipped because we would need
4:18to start here with Hyper-V. That would be the first one,
4:21that one could just be a command.
4:22Then inside of parallel, we could create our 5, or 10,
4:24or however many virtual machines.
4:26All those could get created in parallel at the same time.
4:29Otherwise it would take forever to install one, wait,
4:31install another one, wait, install another one, wait.
4:33And even inside a parallel here, we
4:35could checkpoint after each one was done.
4:37That way, if something were to go wrong even
4:39in the parallel world, the ones that finished
4:41would be fine, because we checkpointed
4:44after every one completed.
4:45And then the final step here is to configure them.
4:48And if this required manual intervention,
4:50we could even suspend the scripts
4:52for manual intervention, maybe send an e-mail
4:54to an administrator.
4:55Say, hey, this script needs you to go do this manually.
4:58When you're done, execute this command to resume the job.
5:01So we get a lot of options here, with workflows.
5:04They allow us to checkpoint.
5:05They allow us to survive past restarts.
5:07We can resume as soon as that computer comes back up,
5:09after the Hyper-V is installed.
5:11And it's just, there are so many great use cases for workflows.
5:14It really takes it to the next level,
5:16allowing us to coordinate our scripts and our commands,
5:19and just gives us a lot more control over the whole process.
5:22Let's jump over to the Virtual Nugget Lab.
5:23We'll see a lot of how this stuff works,
5:25how we can build workflows, and some of the really cool things
5:27we can do with them.
5:28Here we are, in the Virtual Nugget Lab.
5:29Let's bring up the ISE here and get a feel
5:31for the basic structure of a workflow.
5:32So it's very much like defining a function, only instead
5:34of the function keyword we use the workflow keyword.
5:36Then we give it a name.
5:37This is how we're going to call it,
5:38just like we would call a cmdlet, call it by its name.
5:40We can optionally accept some parameters here.
5:42So we're going to define a parameter of the string data
5:44type.
5:45And here it is.
5:46It's going to be a variable that we reference inside
5:48of our workflow.
5:49And then we're just going to send back as the output here,
5:52hello.
5:52And then whatever they passed in.
5:53So, let's go head and create this workflow.
5:55We'll highlight that all, we'll execute that code.
5:57And now we have a workflow.
5:58So now we'll be able to do things
6:00like run a Get-Command for all things workflow.
6:02Let's do it.
6:02Watch this.
6:03And look at that, it comes up as the command type of workflow,
6:06and there it is.
6:06We could even get help on it.
6:08Let's get help, to see what we get here.
6:10Now, here it is, the name of it.
6:12Here's the syntax.
6:12It accepts our You parameter that we defined.
6:15And it bolts onto it, WorkflowCommonParameters.
6:19And there's a lot of WorkflowCommonParameters
6:21in here, such as PSComputerName.
6:24We'll talk about PSPersists which
6:25is how we're going to do checkpointing as well as all
6:28the common parameters that every kind of function,
6:30or anything in PowerShell gets.
6:32So more on those in a little bit here.
6:33But to call this now, we can just call it like a cmdlet.
6:36Get-MyFirstWorkflow, if we do a dash here,
6:39let me get rid of this here, look at that.
6:41There's our parameter, You.
6:42And I'm just going to pass in Me as the parameter.
6:44If we execute this, it's going to execute it.
6:46And look at that.
6:46Hello, Me.
6:47Cool.
6:48Now, let's get to the cool stuff.
6:49How about a parallel workflow?
6:51We can define a parallel block here as one way.
6:53I'll show you another way here shortly.
6:54And anything inside of this block
6:56will get executed in parallel.
6:57So if we do this on the local machine, first let's go ahead
7:00and create this.
7:00We can just execute this, we're not accepting any parameters
7:03here so we can just call it Get-SystemStuff.
7:05If we execute it, it's going to execute all these in parallel.
7:07So there's no guarantee in what order they'll come back.
7:09Because they'll come back as they finish.
7:11And we could add on here, if we do a PS,
7:14these are all of the workflow common parameters.
7:17So this is built on top of remoting,
7:19which means of course you need remoting
7:20enabled on your destination.
7:21So we can do a PSComputerName here.
7:23Let's pass in, how about our domain controller here,
7:25DCNUGGET.
7:26We'll do APPNUGGET, and we'll also
7:28do our file server, FSNUGGET, here.
7:30Highlight all that, I'm going to hit F8 on the keyboard.
7:32And now it's running all of those in parallel,
7:35across all of those machines.
7:37And you can see, because our results are all over the place.
7:40We get some event logs coming back here,
7:42and then we get a process.
7:43We get some more event logs.
7:44And it shows us what machines they're coming back in.
7:46But the cool part there is all of those
7:48are getting executed in parallel,
7:49across all of those machines.
7:51A couple of things to note here.
7:52Even though we're in PowerShell and we're
7:55putting PowerShell cmdlets in here,
7:58remember this is all workflow stuff here,
7:59so most of the cmdlets have been mapped into the Windows
8:03Workflow Foundation Engine.
8:05So that's why we're able to execute
8:07these commands, no problem.
8:08But each one of these gets executed in its own run space.
8:10That's another big difference from functions.
8:12In functions, we're all in one big run space.
8:15So we can declare variables, we can get objects back
8:17and work with those objects.
8:18We can still declare variables in here, no problem.
8:21So we could declare a variable here, a equals,
8:23say-- we'll just do a Get-Service here, for instance.
8:26So we can do this.
8:27But here's one thing we can't do with this variable.
8:30Try to execute any methods.
8:32Look at that.
8:33It's not going to let us do it.
8:34Because each one is in its own run space here.
8:37And these are de-serialized objects going over remoting.
8:40So we wouldn't be able to do things like that.
8:42But that is where the inline script comes into play, here.
8:46Inline script, and then we can pass in a block of code here.
8:50Now we can do PowerShell stuff.
8:52So once you're in an inline script,
8:54you have full access to PowerShell.
8:55So now we could do the same thing.
8:56We could declare a variable here.
8:57We get that equal to get service.
8:59And then we could do things to that service,
9:02like start or stop the service, no problem.
9:04Because we're in PowerShell at this point.
9:06And that's why we can still use any cmdlets that we can't use,
9:11that haven't been mapped into the engine.
9:13Because they will implicitly get wrapped inside
9:15of an inline script, and they will still work.
9:17But again, most of the major cmdlets have been mapped over,
9:19so we can easily use them outside of inline scripts
9:23within our workflow blocks.
9:24Oh, I should also mention you can still pass data to them.
9:27So let me get these back, here.
9:29So we could do something like this.
9:30If, for whatever reason, we needed
9:32to work with this variable from inside of our PowerShell inline
9:35script, then we can use this right here.
9:38Using.
9:38So we need to use the Using scope modifier,
9:41and that will allow us to access that variable, just like so.
9:45So that will still certainly work.
9:47And that's how you'll pass data between blocks,
9:50in between scripts, and all that here
9:52from inside of your workflow.
9:53Let's look at another one, another way
9:54to do parallel workflows.
9:55This one will be a little more useful.
9:57So now we're going to create one called Copy Files Here.
10:00So we're going to accept a couple of parameters.
10:01We're going to accept a source and the destination.
10:03Then we're going to get all the files at the source,
10:05and we're going to do a Foreach-parallel loop.
10:08So this is another way to do parallel execution.
10:10That means each item in this collection
10:12is going to get executed in parallel.
10:14This is pretty cool.
10:15So what we're going to do here, and this is pretty useful,
10:18is we're going to create a Copy-Files workflow,
10:20meaning every single file in here
10:23is going to get copied in parallel.
10:25Very cool.
10:26So let's go ahead and execute this,
10:27to create that workflow, all right?
10:29And now we can call it, in fact here,
10:30let's create-- what we're going to do
10:31is, we're going to take all the files
10:33from our install directory up there on our file server,
10:35let me get this open here to show you.
10:37Whack-whack, FSNUGGET, PS4, and if we head down here
10:40to Installs, here they are.
10:41So we're going to copy all of these over in parallel,
10:44meaning each one is going to be on it's own thread getting
10:45copied over.
10:46So we're going to copy this down onto our local machine.
10:48So we'll run a new item here to create that installs directory
10:51locally.
10:52Perfect, now we have it.
10:53And now we're going to run our workflow here
10:55by pulling down, passing in the Installs directory
10:58there up on our file server, as the source
11:00and as the destination, our local directory that we just
11:03created.
11:03And it's going to copy these all down in parallel.
11:06And when each one is done, it's going to report back.
11:08So look at that.
11:08Copy, copy, copy, it's on the last one right now.
11:10I put one huge file in there, so I can show you down the road.
11:13We'll expand this, and I'll show you
11:15how we can do checkpointing.
11:16We'll actually turn off our file server
11:17in the middle of this process, and we'll
11:19see how we can recover from it.
11:20So there it is.
11:21Copy files, complete.
11:22So it wrote it output here, that that file was
11:24copied when that file was done.
11:26And then when everything was done,
11:27it said copy files complete.
11:28So those are parallel workflows.
11:30You can use the parallel block.
11:31Everything in that block, then, will get executed in parallel.
11:33Or you can do, for each parallel, or each item
11:36in that loop, each item in that collection
11:38will get executed in parallel.
11:39Let's take a peek at sequential flows.
11:41So what we're going to do hear is,
11:43first we're going to put everything in a parallel block,
11:45right?
11:46So this command's going to get executed,
11:47these commands are going to get executed,
11:49and this last command here, all these
11:51are going to get executed in parallel.
11:52But inside of this sequential block here,
11:54Get-Process A, B, and C are going
11:56to get executed sequentially.
11:58So this one first, second, and third, while all three
12:01are going off at the same time.
12:02So let's go ahead and create this one.
12:05And now, what we should see here is both our service
12:09calls to services that start with A and B,
12:11those went off right away, as well as this one.
12:13So all of these were executed in parallel,
12:15but these three, well actually there's only one.
12:18We only have see processes here.
12:19Let's do something a little bit different here.
12:21Let's go, we know C is there.
12:23I know W will be there.
12:25And then P, for PowerShell.
12:26All right, there we go, CPW.
12:28And by the way, if we just re-execute this,
12:29it'll just overwrite that workflow that's
12:31currently in our session.
12:32All right, so now let's try this again, here.
12:34Let's execute that.
12:35And now we should get the same thing.
12:36So first we get all of our services.
12:38There's our A services, here's our B services.
12:40And while that was going on, there's our C processes.
12:43There's our P process, and there's the W processes.
12:45So those went off sequentially, but together all three of them
12:49went off in parallel.
12:50So that's all.
12:51You need to define sequential flows.
12:53Just wrap them inside of a sequence block.
12:55Now, this last piece I want to show you here
12:56is one of the neatest features in the Workflow Engine.
12:59And that is having the ability to checkpoint
13:03at any point within the workflow.
13:05This is how we can make our workflows resilient.
13:07And especially when you're implementing long,
13:09complex processes-- you have a lot of scripts,
13:11a lot of commands, maybe you're archiving data
13:13and you have a process that takes six hours to run.
13:16Wouldn't that stink if, when it's almost completed,
13:18something bad happens?
13:20The power goes out, the network fails,
13:21something happens that would cause
13:23us to have to restart the whole script from scratch?
13:26Yeah, that's where workflows can help.
13:27Because we can implement the Checkpoint Workflow
13:30command here.
13:30And any time it sees this command,
13:32it's going to save the state of our workflow to disk.
13:34So we can spin up jobs, let them go,
13:37and implement our own check flows.
13:38And if that job, for whatever reason,
13:40hits a suspended state, when everything comes back online
13:43we can just resume the job, and it'll
13:45pick up right where it left off.
13:48Really neat.
13:48And there's a number of ways to implement these.
13:49This is definitely the way that will give you the most control.
13:52Anytime it hits this Checkpoint Workflow,
13:53it's just going to save the state right there.
13:55But you can also do this on cmdlets
13:56that have been converted over to the Workflow Engine.
13:58Get-ChildItem is one of them, and most of them have been.
14:01But PSPersist, there you go.
14:02That would automatically put a checkpoint after this command.
14:05Another way to do it is just have it automatically
14:07checkpoint after every single command.
14:09So down here on our call, we could do a PSPersist.
14:12So putting this parameter right here at the end of our call
14:14to the workflow will do a checkpoint after every one.
14:17That could affect performance a little bit.
14:19That's why I like to just do this on my own.
14:22So after a really long running script or command,
14:25just checkpoint it right afterwards.
14:26And then it'll get saved, and that will give us
14:28the ability to resume from that point,
14:29should something bad happen.
14:31All right, let's do this demo.
14:32So this is the same exact workflow as above.
14:34The difference is we took out the parallel.
14:36We're going to do this sequentially
14:37so we can see it happen.
14:38And we added checkpoint workflow after each copy item.
14:42And we also put a little sleep in here,
14:44so we have time to shut down the machine.
14:45Because what we're going to do is,
14:47we're going to run this as a job,
14:49and then we are going to shut down our file server,
14:52just completely force the shutdown in the middle of it.
14:55And what we'll be able to see is,
14:56that job should go from a running state
14:58to a suspended state.
14:59And it'll sit in that suspended state until we intervene,
15:01and we do something about it.
15:03But again, you can automate this whole process
15:05for events like this.
15:08If you have a process that requires
15:11rebooting the computer, you can certainly reboot the computer.
15:14And then again, put inside of a scheduled task
15:17on start up to find that job and resume it.
15:21So you could totally automate all of this without a problem.
15:23But we're going to do it here with
15:25a little manual intervention.
15:26Oh, and as I mentioned you could manual intervene, too.
15:28So if you have a bunch of processes
15:30and then you need some manual intervention,
15:32this is where suspend workflow comes into play.
15:34So you can certainly do that as well.
15:36But let's run this.
15:37Let's first create our workflow here.
15:39All right, it's good to go.
15:41Now, before we run this let me just show you
15:43I have no tricks up my sleeve here.
15:45On our local machine, our installs directory
15:47is completely empty.
15:48Over on our file server, we have all of our files ready to go.
15:51All right, so here's what we're going to do.
15:53We're going to fire this job up.
15:54Let's do it.
15:55Let's go ahead and execute that.
15:56All right, so it's running.
15:57If we do a good job here, you can see currently it
16:00is running right now.
16:01So let's just give that a second to run a few.
16:03All right, good.
16:04Now let's crush our file server.
16:06Boom, we forced the-- not even a restart,
16:09we just totally shut it down.
16:10And as soon as that command finished,
16:12I just saw over in my Hyper-V server
16:13here, that the state of that machine went off.
16:16So it's completely down.
16:18And now what I want to do is, we could do this right here,
16:21but this is going to give us inconsistent results here.
16:24The problem is our file's right here,
16:25and we're totally connected to our file
16:28server with these scripts.
16:29So what I'm going to do is, I'm just
16:30going to fire up a new PowerShell session.
16:31And let's do a get-job.
16:32It should no longer be in a running state,
16:34but it's in a suspended state.
16:36See that?
16:36So how do we know how far it got?
16:39Well, we could do it a number of ways.
16:41Probably the best way to do this, because it'll
16:43work no matter what kind of process you have, is just
16:46look at the results of our job so far.
16:47But since we're copying these locally, we can come in here
16:50and check.
16:50Oh, we can see, look.
16:51Our big file, that zip, made it over.
16:53So if we do a receive job here, let's do a get-job.
16:56We only have one job here, so we can just do a get-job and pipe
16:58this to receive-job.
17:01And, oh, it's not recognized because I typed it in wrong.
17:04Receive-job.
17:06Boy, I really butchered that one, huh?
17:07There we go.
17:08Look at that.
17:09Big dash file dot zip copy.
17:11So that's how far it got.
17:13So we know that there's more files to be had there, right?
17:16So now what we need to do is, well, I
17:19need to restart my Hyper-V server here.
17:21So let me get back over there and restart our file server.
17:23All right, starting, it's starting right now.
17:25Cool.
17:26So that's starting up, and as that's starting up here,
17:29what we can do is when it comes up, is just resume the job.
17:32That's it.
17:33And again, if we had a startup script
17:36over on our file server for a scheduled task with the trigger
17:39there of on startup, then we could look for this job.
17:42And we can look for any jobs in a suspended
17:44state in that machine and fire them up, doing a resume job.
17:48So file server's up.
17:49Let's do a get-job.
17:50And let's just pipe this to resume job.
17:54Cool.
17:55Now it's back into a running state.
17:57And it'll probably finish pretty quickly.
17:59Yeah, there we go.
18:00Because those other files were pretty small.
18:01And it's done.
18:02And we can verify that it finished, and look at that.
18:04There's the rest of those files that are copied over.
18:07So how cool is that?
18:08We just had failure happen in the middle of nowhere,
18:12but thanks to check pointing we were
18:15able to resume from where it left off.
18:17Just an incredible feature, there.
18:19Let me give you your challenges for this Nugget.
18:21Challenge number one: create a workflow
18:22that retrieves the newest five system
18:24event logs from multiple servers in parallel.
18:26Pretty straightforward, just create a basic workflow,
18:28use a parallel block, and then use the get-event log cmdlet
18:32with the newest five.
18:33Send that across a couple of servers,
18:35and you'll see they will all execute in parallel.
18:37Challenge number two: build on the previous workflow
18:39by accepting an entries parameter to accept
18:41the number of newest entries.
18:42So we're taking this hard-coded five value out, moving it
18:45to a parameter, and then that way
18:47when we call this we'll be able to pass in any number.
18:50So we'll turn that into a variable, there.
18:52Pretty nice.
18:53Can I just gave you an example of what
18:56how you call this workflow?
18:57So I named it get-system event logs, and then
19:00here's your entries parameter, pass
19:01in whatever number of entries you want to retrieve.
19:03And you can send that across multiple machines as well.
19:05Challenge number three: create a workflow
19:07that calls three scripts or commands
19:09and creates a checkpoint in between them.
19:10Run the workflow as a job, and terminate your session
19:12shortly after starting it.
19:13Launch a new session.
19:15View the suspended job, and resume to let it finish.
19:18So same thing that we just saw, only you
19:19can also simulate this by using your session
19:22and just terminating your session.
19:24That will suspend the job, and then you
19:25can open up another PowerShell session and resume that job
19:28and let it finish.
19:29Remember, you can find the answers
19:30underneath these regions.
19:31And you can find all these files in the Nugget Lab files,
19:34downloadable on the right-hand side of the course page.
19:36Good luck.
19:37In this CBT Nugget, we covered workflows.
19:39We saw that workflows is an amazing feature that we can tap
19:42into from PowerShell, that really utilizes the .NET
19:44framework's Windows Workflow Foundation Engine.
19:47And it allows us to take those long-running processes that
19:49involve many tasks, many commands, many scripts,
19:51and have a little more control over them.
19:54We can coordinate them across machines.
19:56We can run them in parallel.
19:57We can run them in sequence.
19:59And we can even checkpoint and save our work,
20:02so we can resume in the face of disaster.
20:04I hope this has been informative for you,
20:06and I'd like to thank you for viewing.
Scripting - Getting Started
0:00Getting started with scripting.
0:01So we've got a handful of scripting Nuggets ahead of us,
0:04and no better place to start than talking
0:06about how to execute scripts.
0:08So we'll look at the basic anatomy of a script.
0:10We'll look at how to execute scripts.
0:11And we'll also get familiar with all the different security
0:14features here in PowerShell.
0:15And at the end here, I'll also show you
0:17how we can sign our script.
0:19We'll look at the process of creating
0:21our own self-signed certificate and then the benefits,
0:24of course, of digitally signing our scripts.
0:26So let's jump right into the virtual NuggetLab
0:28and get familiar with the basics of scripting.
0:30All right.
0:31Let's jump right into the ISE here and get familiar with
0:33the script that we're going to be working with throughout this
0:35Nugget, called test-remote.ps1.
0:37So this script is going to test remoting.
0:40It's going to do so by first seeing
0:41if we can ping the machine.
0:42If we can ping the machine, then it's
0:44going to set up a PSSession.
0:45And this script will tell us if remoting
0:47is enabled on a machine.
0:49Pretty basic script.
0:50But right off the bat, you're going
0:51to notice something that we haven't seen yet
0:53in this course.
0:53This is known as comment-based help.
0:55And it allows us to provide help for our script.
0:57So if someone were to run a Help or a Get-Help
0:59against our script, it would look just
1:01like running Help or Get-Help against the command line.
1:03And it's very simple to set up.
1:05We have a dot followed by keyword and then the value
1:07we want to provide for that.
1:08So if we want to provide a synopsis description,
1:10list out all the parameters, give some examples,
1:13we can easily do that.
1:14Check out the About topic for comment-based help
1:16for more and to see a list of all the different keywords
1:19here that we can provide.
1:20Next up, the first thing we're doing in this script
1:23is setting up a parameter block.
1:24And this is what's going to allow
1:25us to accept parameters to make our script a little more
1:28dynamic.
1:28Very simple, right?
1:29Parameter, open parenthese, close parenthese.
1:31Inside of here we list our parameters, which
1:34are really just variables.
1:36And that's how we're going to use them inside of our script.
1:39And if you want multiple parameters,
1:40you can comma-delimit them.
1:42You can set up mandatory parameters,
1:43optional parameters.
1:44Here we have a default value for our parameter.
1:46So as you can see, our example here, one of these examples
1:49we're not providing a parameter, which
1:51means it's going to execute using the default
1:54value for this parameter.
1:55Now, we're going to get more into parameters.
1:56I'll show you how we can create some pretty big and complex
1:59parameter blocks when we get into our Essentials Nugget
2:01on scripting.
2:02All right.
2:02Let's get into the meat of this script.
2:04So this script has two functions defined, one called CanPing
2:07and one called CanRemote.
2:09And again, more on functions when we get
2:11into that Essentials Nugget.
2:12But just think of a function as a named block of code.
2:15We'd implement code reuse, because we
2:17can wrap all that inside of a function
2:19and call it by name multiple times in our script.
2:21And a function's either going to just do something
2:23or it's going to do something and return a result.
2:26So our first function here, CanPing,
2:28is going to return either true or false
2:30if we can hit a computer.
2:31Our second function isn't going to return anything.
2:33It's just going to do something.
2:34And the reason we did this is because we're
2:36going to run a little if statement in the main block
2:37of our script here that says if CanPing-- in other words,
2:40if this machine is online-- then we're
2:43going to run a CanRemote to see if remoting is enabled,
2:46because why bother even checking if remoting is enabled
2:49if we can't even ping it?
2:50So that's why our CanPing is going to return true or false.
2:52That'll allow us to see the results of this.
2:55And if it's online, awesome.
2:57We'll check remoting.
2:58If it's not, we won't even bother checking remoting.
3:00Now, with our CanPing function, we're
3:01just going to run a test connection
3:03against the variable ComputerName--
3:04or I should say the parameter that's
3:06coming in that we reference here as a variable inside
3:09of our script.
3:10So we'll run a test connection.
3:12And this is going to return-- now,
3:13if you don't include the quiet parameter,
3:15it's going to return a ping object with all
3:17those different properties we can see and query
3:19in the response.
3:20But if we run it with the Quiet parameter,
3:22it's just simply going to return true or false.
3:25And that's exactly what we want for this kind of function.
3:27We just want a true or false value.
3:29Is it online or is it not?
3:30We don't care about all the data that comes back inside
3:32of that ping object.
3:33Also, notice our ErrorAction here.
3:35We're going to get more into error
3:36handling in that Essentials Nugget as well.
3:37But we're just saying if something bad were
3:39to happen, just keep going.
3:40Don't bomb the script out right here.
3:41Keep going.
3:42Just let it return false and that's fine.
3:44That'll tell us that it's not online.
3:45So that's our script.
3:47Let's take a look at how we can utilize this script.
3:49And we're going to do this through the console.
3:51Oh, by the way, that script that we're going to be working with
3:54is up in our NuggetLab files on our file server under 17
3:57scripting1, test-remote.ps1.
4:00So let's just bring that file locally.
4:01That way we have one up there on the file server
4:03and one down here to work with.
4:08All right.
4:09So there we go.
4:09A little copy item, specify our path there.
4:11And our destination will be our current directory.
4:13All right.
4:14There we go.
4:14If we do ls, it should be in here.
4:16And there it is, test-remote.ps1.
4:18Perfect.
4:19All right.
4:19Let's execute our script.
4:20Now, here's one security feature.
4:21You can't just do something like this, right?
4:24That's not going to work.
4:25It's not a command.
4:26That is looking for a command.
4:28So in order to execute scripts, you
4:29need to actually supply a path.
4:31And we can do this using absolute paths
4:34or relative paths.
4:36So this is going to say, in the current directory we can do
4:38a test-- and you can use Tab completion there--
4:40test-remote.ps1.
4:42Let's hit Enter.
4:43Uh-oh.
4:43What's that?
4:44What does that say?
4:46Cannot be loaded because running scripts is disabled on this
4:49system.
4:50And that gets us into security.
4:52Now, before we go down the execution policy rabbit-hole,
4:55let's just take a step back and talk about the security
4:57measures that the PowerShell team put in place here
4:59in PowerShell.
5:00And the first thing to note about that
5:01is that these are not measures that
5:03are here to stop a malicious user from doing
5:05malicious things.
5:07If you have somebody that knows what they're doing
5:10and they want to do something malicious to your system,
5:12they're probably not going to use PowerShell to do it.
5:15And that's also why we have other security measures
5:18in place, principle of least privilege, firewalls, malware,
5:22and virus scanners and detectors,
5:23all that kind of stuff.
5:24That's how you stop malicious users
5:25from doing malicious things.
5:26No.
5:26The security measures in PowerShell
5:28are really to help us, number one,
5:30not shoot ourselves in the foot, and number two,
5:32stop those users who have no idea what
5:35they're doing from doing things that they shouldn't do.
5:38So here's security measure number one.
5:39That's why you saw right here we need to type in a path
5:42to execute a script.
5:44Otherwise it's going to treat it like a command.
5:46And the command is not going to have
5:47the same name as your script, so it's not going to work.
5:49Number two is execution policies,
5:51which we'll dig into shortly.
5:52It brings a lot of benefits here,
5:55especially signing your scripts, because that will do
5:58a lot of great things for us.
5:59And then the third one-- and this is an awesome one.
6:01This is what's going to stop Bob from navigating the company
6:04directory to do something, is-- let's find our script.
6:06Actually, let me do our local one that we did.
6:08Let's just do a start here, bah, buh, boo.
6:11There it is.
6:11So here's our script, right?
6:12All right.
6:13Let's double-click on it.
6:13Hey, look at that.
6:14It just opens it up.
6:15That's an awesome security feature.
6:17It's not going to launch the script
6:18when you double-click on it.
6:19It's simply going to open it up.
6:20Now, that's not going to stop somebody
6:22from copying our code into PowerShell session.
6:24But chances are if they're just a user who
6:26doesn't know what they're doing, they're probably
6:27in the company share, they're not
6:29going to know that that's PowerShell code,
6:31nor are they going to have access to PowerShell.
6:33All right.
6:34Back to execution policies.
6:35So let's do a quick Get-ExecutionPolicy here.
6:38And we can see that we are in a restricted execution policy
6:41mode.
6:42And that is the default. That means
6:43no scripts are allowed to execute on the system.
6:45So no scripts, local or downloaded, can be executed.
6:48We can change that with a Set-ExecutionPolicy.
6:51We've got an ExecutionPolicy parameter here.
6:54And that can be a couple of values
6:56here that we'll look at shortly.
6:57And you also have a scope associated with this.
7:00And a scope is going to determine
7:01if it's the current user, the machine, machine policy based
7:05on group policy, user policy, or if it's based
7:07around the PowerShell process.
7:09Let's just do a help here on Set-ExecutionPolicy.
7:11help, Set-ExecutionPolicy.
7:14Let's look at the full help here.
7:16And let's take a peek.
7:17So here's our parameters for ExecutionPolicy, Restricted.
7:20That's the default. Does not load configuration files
7:22or run scripts.
7:23The next one is AllSigned.
7:25It requires that all scripts, no matter where they came from,
7:28will need to be signed by a trusted publisher
7:30with a digital certificate.
7:32More on that here towards the end of the Nugget.
7:34RemoteSigned requires that all scripts and configuration
7:36files downloaded from the internet--
7:37so whenever you download something from the internet,
7:40it's going to add a header into the metadata for that file that
7:43signifies that it's been downloaded from the internet.
7:45So this just means all of our local scripts,
7:47anything we build on our network locally, will be fine.
7:50They'll be able to get executed.
7:51But anything that's downloaded from the internet
7:53will need to be signed by a trusted publisher.
7:56Unrestricted is something that you never want to use,
7:59because it will allow you to run anything at any time.
8:01And those are going to be your big four right
8:03there for ExecutionPolicy.
8:05And you can set the execution policy in group policy as well.
8:09And just to show you where that is here,
8:11let's fire up Group Policy Management here.
8:14And right into the Default Domain Policy.
8:16I'm just going to hit Edit.
8:17We'll go down here into Computer Configuration, Policies,
8:19Administrative Templates, Windows Components.
8:22And it's down here, Windows PowerShell.
8:25There it is.
8:26So turn on Script Extension.
8:27If we enable this, we can choose Allow only signed scripts,
8:30so there's AllSigned; local scripts
8:32and remote-- Allow local scripts and remote signed scripts,
8:35so there's your RemoteSigned; and then Allow all scripts
8:37is Unrestricted.
8:38So you got those three options to choose from.
8:40So you can easily use group policy
8:41to set your execution policy across the enterprise.
8:45So now that we can execute scripts,
8:47let me show you one really cool feature before we move on
8:49to signing our scripts.
8:50And that is called dot sourcing.
8:52First let's do this.
8:53Let's just run our script again. test-remote.ps1.
8:56And pass in dcnugget-- actually, let's just run it like this.
8:59Perfect.
9:00So this is going to run our script against the local host
9:02using that default parameter.
9:04And when it's done, it's done.
9:05Script has gone.
9:06It's out of memory.
9:07In fact, we can verify that, because if we
9:08try to access that function-- let's try
9:09to access the CanPing function.
9:11Let's just run it.
9:12Look at that.
9:12It can't.
9:13It can't, because it's out of scope.
9:14It's out of scope.
9:15And that's what scope is all about, by the way.
9:17Let's just go in here for a second.
9:18So everything that was in here was scoped at the script level.
9:22So when it was out, when this script was done, it's all gone.
9:26Script is out of scope, right?
9:27And everything within that script is gone, out of memory.
9:30So let's do something interesting, thought.
9:32We're going to put a dot space and then execute our script.
9:37test-remote.ps1.
9:39Watch this.
9:41So same result, just going to execute it
9:42against the local host.
9:44But we did something known as dot sourcing there.
9:47By adding that dot space before the path to our script,
9:52what that did is took everything out and put it
9:54inside of our session scope.
9:55So it left everything that was declared at the script level
9:58there.
9:59Watch this.
9:59CanPing is going to work now.
10:02But everything that was defined at the script level--
10:05meaning this is scoped at the script level, our functions.
10:09This parameter scoped at the script level.
10:11But everything inside of our function, this
10:12is scoped at the function level.
10:14So we wouldn't be able to access this response variable,
10:16because it went in and out of scope
10:18when that function executed.
10:20But watch this.
10:21This is really cool, because now we also
10:23have access to the computername variable, which
10:27was a parameter.
10:28And there i is.
10:28Now, we could even alter it.
10:30Equal-- how about APPNUGGET?
10:32Let's see if our APPNUGGET machine is online.
10:34And now we can do a CanPing against that, because we
10:37modified the variable.
10:38That's dot sourcing.
10:39Dot sourcing is awesome because it essentially takes
10:41everything that was at the script level scope
10:43and brings it into our session so we can use it.
10:45And that's extremely useful for doing things like this,
10:47for testing, because now you can modify those parameters
10:50and still execute your functions and see
10:52what the results will be.
10:53And there's just a lot of other use cases.
10:54I guarantee you, live in PowerShell long enough,
10:56you'll come across certain cases where you're like,
10:59man, I wish I had access to that function or variable
11:01after I executed the script, maybe to use it
11:03in another script or whatever.
11:05So that's called dot sourcing.
11:06And it's a very cool little feature.
11:08So signing scripts gives them two things, identity
11:11and integrity.
11:12Identity, because we're going to sign these things
11:15with a certificate from a certificate authority,
11:17a trusted certificate authority, and integrity because scripts
11:20that are signed can't be modified
11:21by malware or malicious users.
11:24In fact, we can actually see this.
11:25Let's start up the pshome directory here.
11:28And everything in PowerShell here, all these files, all
11:31these format and type files-- in fact, let's
11:32just open up DotNettypes.
11:33These are signed by Microsoft.
11:35Microsoft's a trusted certificate authority,
11:36so they created a code signing certificate
11:38and they digitally signed all these files.
11:41And that's what this is down at the bottom here.
11:42This is their signature.
11:43So this is why we can't directly modify these format files,
11:45because if we did, they would be invalid
11:47and we would break PowerShell, because they are signed.
11:50So that's what we can do to our scripts.
11:53So you can go out and get your own code signing certificate
11:56from a trusted authority, like Thawte or Verisign or whatever.
11:59Or you can also create your own self-signed certificates,
12:02which are great for working in your own environment
12:05and for testing and development purposes.
12:07And you can view these signatures in PowerShell
12:09with Get-AuthenicodeSignature.
12:11So here, let's just do the pshome here.
12:13And let's just pass in, how about types?
12:16There we go.
12:17So if we Get-AuthenicodeSignature here,
12:18check it out.
12:19So we've got our signed certificate,
12:20the status is Valid, and there's a path.
12:22Let's do that against our own here.
12:24If we do this against our test-remote.ps1,
12:28you can see it's not signed.
12:30So if we were to put this on the internet for someone
12:32to download, then if they have their execution policy set
12:36as RemoteSigned, then they wouldn't
12:37be able to execute this script.
12:39But if we signed it with a valid certificate authority
12:42and put it up there on the internet, yeah,
12:43they would be able to execute it.
12:45So let me show you the process here
12:46for creating your own self-signed certificate.
12:49Let's head back into the ISE here.
12:50I'm just going to open up our commands file.
12:52And you can use what's known as makecert.exe.
12:56And you can actually get this through the Windows
12:58SDK, which I also just happened to download.
13:01And I've already got it installed here.
13:03And that will give you access to the makecert utility.
13:04But I put it inside of our installs.
13:06Here it is, sdksetup.
13:07You can run this.
13:08That will install the Windows SDK,
13:09which gives access to makecert.
13:11There's also a commandlet that you can use called
13:15New-SelfSignedCertificate.
13:17There it is, right there.
13:18But this actually in PowerShell version 4
13:20won't work for code signing certificates.
13:22In PowerShell version 5, it does.
13:24So we still in version 4 and prior need to use makecert.
13:26So the first thing we're going to do
13:28is create our own local certificate authority here
13:30using makecert.
13:31That's what the first command is going to do,
13:32so let's execute that.
13:33There we go.
13:33You need to give it a key here, so I'm just
13:35going to put a password.
13:36Oop.
13:37You've got to confirm it here.
13:38All right.
13:40There it is.
13:41And there it is.
13:42All right.
13:42So not that we've created our local certificate authority--
13:45we can actually see this here if we-- let's just fire up
13:47our MMC snap-in here.
13:51And let's just Add and Remove Snap-in here.
13:53Let's just add certificates in here for the local machine.
13:55And we'll do this for-- yeah, we'll do this at the user level
13:58here.
13:59Hit OK.
14:00And here we go.
14:01So here's our trusted root certificate authority,
14:03so if we come in here, we should now have a PowerShell one
14:05here that we just created.
14:06There it is.
14:07PowerShell Local Certificate Root.
14:09So now the next step is to create a self-signed code
14:11signing certificate with that root.
14:14So we're going to run another makecert command here,
14:16which will do just that.
14:17And there we go.
14:18We put in the password.
14:20And now if we head back here, head
14:23into Personal, Certificates, there it is, PowerShell User.
14:26So now we have a certificate.
14:27So now we can sign our scripts with this certificate.
14:30So let's head back here.
14:31And what we're going do is just go ahead
14:33and create a cert object.
14:35And by the way, you can use providers here to view that.
14:37So let's view all of our code signing certs in here.
14:39Let's just execute that little block of code.
14:42And there it is.
14:43So there's our certificate.
14:44So what we're doing now is just create this, put it inside
14:47of a variable.
14:48So there we go.
14:48Now we've got that code signing cert within there.
14:50And now we can use Set-AuthenticodeSignature
14:52to sign our script with that certificate.
14:56And if we do that, now it should be signed.
14:58Now, we could verify that just by running
15:01Get-AuthenticodeSignature again against our file,
15:03against our script.
15:04And we could see, there it is.
15:05There's our SignerCertificate.
15:05Status is Valid.
15:07So we now have signed it.
15:08And then we could also-- let's just cat this.
15:09Let's just take a peek at what it looks like here,
15:11because now that it's signed, it has a digital signature.
15:14So if the script were to change at all,
15:15it wouldn't match the signature and it would no longer
15:18be valid.
15:19Cool.
15:19So now that it's signed, we should be able to execute this.
15:22And let's just head back to the ISE here.
15:24Let's change our execution policy.
15:26Execute that.
15:28Yeah.
15:28We're going to change it.
15:30And now we can execute-- let's execute an unsigned script
15:33first.
15:33So this is our script sitting over on our file server.
15:36And by the way, to execute remote scripts using a UNC,
15:39then you can use the invocation operator here,
15:42otherwise known as the call operator.
15:43And so this will execute this unsigned script.
15:46And what will happen is we'll get an error.
15:47Sorry, this is not a signed script.
15:50But this one is.
15:51And if we try to execute it, look at that.
15:53It's going to work, because it's signed.
15:56Very cool.
15:56So there you go.
15:57Now, you could also export that certificate
15:59if you want to utilize it on other machines in your network.
16:01Or again, you could get a real certificate
16:03from a trusted certificate authority
16:05if you wanted to distribute your scripts
16:07outside of your network.
16:08So there it is.
16:09Let's take a look at your challenges
16:11here to finish up this Nugget.
16:12Challenge number 1, set the execution policy to Restricted,
16:15verify the setting, and execute the test-remote.ps1 script
16:18locally.
16:19What happens?
16:19Obviously, you should get an error message, right,
16:21because you're restricted.
16:23No script execution at all.
16:25Challenge number 2, set the execution policy
16:26to RemoteSigned and execute the test-remote.ps1 script.
16:29Attempt to execute the CanPing function
16:30from outside of the script.
16:32Execute test-remote dot sourcing and execute the CanPing
16:35function from outside of the script.
16:36What did dot sourcing the script do?
16:38So that'll show you how you can take everything
16:41that was at the script scope there
16:43and pull it into session scope so you can utilize things
16:46from outside of the script.
16:47And the big one here, Challenge number 3,
16:49set the execution policy to AllSigned and execute
16:51the test-remote.ps1 script.
16:53And we know that that should fail.
16:54Then generate a self-signed certificate and sign
16:56the test-remote.ps1 script, view the definition to verify
16:58the signature, and execute it.
16:59So the demo that we just saw there, try it out on your own.
17:02Here are all the steps to make it happen.
17:04Again, all these files here are in the NuggetLab files,
17:06downloadable in the right-hand side of the course page.
17:09And as always, good luck.
17:10In this CBT Nugget, we saw how to get started with scripting.
17:13We started by getting familiar with just a basic script that
17:15contains comment-based help, had a parameter,
17:17had a couple of functions, and even a very tiny one-liner
17:20script body down there to utilize those functions.
17:23And then we saw how to execute scripts
17:24and the many security features we have here in PowerShell.
17:28We then took a big look at the execution policy setting,
17:31which is what we're going to need in order to execute
17:34scripts on the system.
17:35Restricted is the default, meaning no scripts are
17:37allowed to execute.
17:38We took a look at all the different options
17:40there and even saw how to create a signed script
17:43and saw the benefits that that brings to us.
17:45I hope that this has been informative for you
17:46and I'd like to thank you for viewing.
Scripting - Essentials
0:00Scripting essentials-- so now we're really
0:02get into the meat of scripting.
0:04And I'm talking about the core language concepts here,
0:08things like variables, things like conditional logic,
0:12how to control the flow of code within your scripts
0:14by using if statements and switch statements.
0:17I will talk about looping, do-while loops, for-loops,
0:20for-each loops.
0:20And it's important to understand the difference between these
0:23so you choose the right tool for the job when it comes time
0:26to write your scripts.
0:27We'll also get into air handling, and, of course,
0:29we'll talk about functions.
0:30And at the end here, we'll bring it all together
0:31with a pretty cool script that will monitor our network
0:33and send us email notifications when any servers go down.
0:37So let's jump into the Virtual Nugget Lab and get coding.
0:39And we're back in the Virtual Nugget Lab.
0:41Let's bring up the ISE and let's start here with variables.
0:44Now, variables are very important when
0:45it comes to scripting because it's how we store information.
0:49A lot of the times when you're writing
0:51these big, long one-liner pipelines,
0:53you don't need variables.
0:54You don't need to store anything.
0:55You're doing it all in one shot.
0:56But with scripting, we need to put our data somewhere.
1:00Take this as an example.
1:02We get a bunch of services through getService.
1:04We store that in a variable, and then now we
1:06can do something with that variable.
1:08We can analyze it.
1:08We can get a count.
1:09How many services did that return?
1:10We can loop through it one at a time because that'll contain
1:13a collection of variables.
1:15So we can loop through one at a time,
1:16interrogate it, make decisions on it.
1:18Is it stopped?
1:18Let's try to start it.
1:20If it doesn't start, let's wrap error handling
1:22code around it, and maybe output that
1:24to a log file or a web page or an email,
1:27perhaps, for some kind of notification.
1:29But that's really why we need variables.
1:31We need variables as a place to store our stuff.
1:33So we've been using variables quite a bit
1:35throughout the course.
1:35But we haven't actually talked about them.
1:36So let's talk about them a little more.
1:38Any time you declare a variable, you
1:39give it a currency symbol followed by a name.
1:41And then you can also set it equal to a value,
1:44kind of do it all one shot here, which is what we're doing.
1:47And this how you'll see variables declared a lot.
1:49And when you're doing quick things,
1:51it's generally OK to do this.
1:54And what we're doing here-- I'm going
1:56to go ahead and create that variable,
1:57and now I'm going to view it.
1:59There it is.
1:59The value of 10.
2:00But what we're doing here is PowerShell's
2:02actually going to analyze that value going in
2:05and infer the data type.
2:07Meaning it's going to figure out which data type is best
2:08suited for the data that's going in,
2:10and that's the data type it's going to get.
2:11So if we'd run it getMember against this,
2:13it's going to say, oh, yeah, his is an int 32.
2:14That's what it decided the data type for this variable
2:17should be, based on the value we assign, which is great.
2:19But I've got to say, I'm a fan of strongly typing out
2:22variable.
2:22Sure, that's great for quick jobs.
2:24But when you're writing big complex scripts,
2:28it just makes it a whole lot easier
2:29to read to strongly typed your variables.
2:31And what that means is you are defining the kind
2:34of data that goes into it.
2:35So what do you think is going to happen here?
2:37If we say this variable A that we're creating,
2:39we're going to say it's of integer data type,
2:42and we're going to put a character data type [INAUDIBLE]
2:44of it, a string.
2:45What do you think is going to happen here?
2:45Yeah, it's going to bottom out, right?
2:47It's going to fail.
2:48No, sorry, you're trying to put something
2:50that isnt' an integer into a variable
2:51that you declared that's going to be an integer.
2:53So we would have to then, of course,
2:55declare this as a string in order to get it,
2:57and there we go.
2:57Now, if we look at A once again, now it's
2:59a string data type because, by the way,
3:01we overwrote the one that we had previously.
3:05So I like to use strong typing not
3:07only for readability purposes, but also because you
3:10will get access to all of the members of that data type.
3:14And here's an example.
3:16Say that we were going to run a getDate,
3:17and we're going to put in a variable,
3:19and we strongly typed it as a strength.
3:21It's going to be a string data type,
3:22so we wouldn't be able to call any of the members
3:24on the actual date that is returned from here
3:28because it was converted to a string when
3:29it was put inside of here.
3:31Case in point, if we execute this,
3:32we're not going to get anything out
3:34of it because it's a string.
3:35It doesn't support that day-of-week method.
3:38Where if we strongly type it is a date time to getDate,
3:41or not at all, which, in this case,
3:42would infer it to a date time, then we
3:45would be able to call the day of the week function, which
3:47return the current in the week, which is Tuesday.
3:50So let's imagine we have a handful of commandlets, which
3:51will give us a little more control over our variables,
3:54just to show you a list of these-- clear-variable,
3:55get-variable, new-variable, remove-variables, set-variable.
3:58So you have a little more control,
3:59especially when creating them.
4:00For example, let's say we wanted to create a read-only variable,
4:03we could use the new-variable commandlet, pass in the name.
4:06That's going to be dirs, so we'll reference it
4:07with a dollar sign dirs, or we could
4:09use get-variable and pass in dirs without the dollar sign.
4:12assign a value to it, get-child item, blah-blah-blah,
4:14and then option read-only.
4:16So you can create read-only and write-only variables,
4:18all that kind of stuff, which is nice because now,
4:20just to verify that we have the dirs variable here,
4:23which is a collection of directories, by the way,
4:25and here are those directories all stored
4:27inside of that variable.
4:28But just to show you, if we try to write to it,
4:30it's going to say, no, sorry, that
4:32is a read-only variable there.
4:34So those are user-defined variables,
4:35variables that we can create and work with.
4:37We also have automatic variables.
4:39These are all the variables that PowerShell creates on start up.
4:43And so these are configuration variables here
4:46for the shell, lots of them in here.
4:48And you can use the variable drive there, the provider,
4:50to see those.
4:51And, of course, we have environment variables as well,
4:53which you can also view the provider drive
4:56there to see all the environmental variables
4:58on the system.
4:59Moving onto conditions, conditions
5:02are what allow us to make decisions in our code.
5:05So we can do some branching.
5:07We could say, if this condition is true,
5:09execute this block of code.
5:10If it's not true, execute this block of code.
5:13And the first one we're going to look at here is if-else.
5:16So if-else is great because it allows us
5:18to just make a simple decision.
5:19So here we're going to create a variable.
5:21And I know I'm not following-- I'm not strongly typing it.
5:24But it'll result in less code, easier to look at.
5:27So, in this case, it'll be all right for learning purposes.
5:29So we're going to create a number variable, put 100 in it.
5:32So that's going to get inferred to an integer data type.
5:34And then we're going to run an if-statement;
5:36if this number is greater than 100,
5:39it's going to pipe to the screen using a right host
5:41num is larger than 100.
5:43If it's not, then it's going to say,
5:45num is less than or equal to 100.
5:47Let's just highlight all this here, hit Execute,
5:50and what do we get?
5:51Yeah, 100 is less than or equal to 100.
5:54So the if-statement analyzed this expression right
5:58here, num greater than 100.
5:59And it said, you know what?
6:00100 is not greater than 100.
6:01It's equal to 100.
6:02So it skipped this block of code.
6:04That never ran.
6:05And it ran our else, this block of code right here.
6:07That's the if-else statement at the most basic level.
6:11We also have an if-else-if statement.
6:13In other words, we can have many else-if conditions within here,
6:16so we can analyze multiple conditions in one go.
6:18So the same thing here-- we're going
6:20to leave our num in memory there at 100.
6:21And here we're going to say if num is greater than 100,
6:24then num is larger than 100-- there we go-- else
6:27if num is equal to 100, it's exactly 100,
6:30else it's a less than 100.
6:31So we're just really just expanding this less than
6:33or equal and putting them in their own code blocks,
6:36and that's what else-if helps us out there,
6:38with multiple conditions.
6:39And there it is.
6:40So 100 is exactly 100, so it ran this block of code right there.
6:45Now things can get a little crazy
6:47when we have a lot of conditions.
6:49Like this is almost unreadable, right?
6:52And this is what you kind of want to avoid
6:55when you're building scripts.
6:56Because unless you're the only one maintaining them
6:59and you're cool with it, then cool, but if you're on a team,
7:02and people are going to be utilizing your scripts,
7:04they're going to put things in your milkshake
7:06when you're not looking because it's not
7:08fun to read this kind of code.
7:10But what this is going to do is we're
7:13going to prompt the user here.
7:14What size milkshake would you like?
7:16And they're going to type in small, medium, large, extra
7:18large or something that isn't any one of those.
7:21And we've got lots of else-ifs in here
7:24to analyze all the potential values
7:26that they could type in to the console
7:28and give us something back.
7:29So let's try out.
7:30Let's hit Enter.
7:31What size milkshake would you like?
7:32Let's say, I'm feeling like a large today.
7:34And it's going to say, living large.
7:36And we can do that again.
7:37Let's run that again.
7:38And now let's just typing in a bunch of gibberish,
7:40and it says, that's not size we offer.
7:42So, yeah, be careful when you have a lot of conditions.
7:46There's a much better way to do it.
7:47And that much better way to do it
7:49is with the switch-statement.
7:50So it's much less code.
7:52So here we're going to create an integer variable here called
7:54value.
7:55We're going to do readh-host, what
7:56size milkshake would you like?
7:57Give them a little instruction here.
7:58Type in the number that corresponds to your milkshake,
8:01and then we'll do a switch, which is going to analyze this.
8:04If it's one, it's going to run this code block.
8:06If it's two, it's going to run this code block.
8:08Three, four, so on and so forth, and default
8:10if they enter something that isn't any of our choices.
8:13But the switch-statement's awesome
8:15just because it's far less code.
8:16It's perfect for making a lot of decisions.
8:20So let's run this, and let's type in extra large.
8:22All right, great, extra large, that's exactly what we wanted.
8:26Let's do another one.
8:27Let's type in eight.
8:29That size is not available.
8:31Cool, so those are your conditional statements
8:34for making decisions, branching off code, and really
8:36controlling the flow of code within your scripts.
8:39Let's move on to loops.
8:40Now, loops are very, very powerful.
8:42This is what's going to allow us to execute
8:44the same block of code over and over, until either
8:46a condition is met, until we're at the end of the collection,
8:49or otherwise.
8:50We have really full control.
8:51Which one of those loops we want to execute
8:53is going to be dependent on what we need to do.
8:55But just to give you an idea here, the first one,
8:57this is not using the language construct.
8:59This is using the command line.
9:00So this is good for pipeline stuff.
9:01I just wanted to put it in here for reference.
9:03So here we're saying, from 1 to 10, do a for-each.
9:06So for each item in a collection,
9:08meaning it's going loop 10 times,
9:09starting at one, then two, then three, all the way up to 10,
9:12it's going to output this right here.
9:13So just to give you an idea here, let's go ahead
9:16and execute this.
9:16And there it is executing-- 1, 2, 3, 4, 5, 6, 7, 8, 9, 10.
9:19But again, that's the pipeline commandlet.
9:21What if we wanted to loop within our scripts?
9:23Generally what you're going to do
9:25is you're going to have a getter for the for-each loop.
9:27And a for-each loop, by the way, loops through a collection,
9:30starting at the beginning and going to the end.
9:33So generally you're going to have a little getter
9:35to go get something.
9:35You're going to put it in the variable.
9:36Like here, this is a perfect example.
9:38We're going to go get a bunch of files.
9:39So let's just execute that, and actually, let's just
9:42view it right here.
9:43Let's take a look at the files.
9:44And they're there.
9:45There's all the files.
9:46So we've got a bunch of files and directories here stored
9:49inside of this variable.
9:50Then we're going to say for-each,
9:52and here we're going to say, File In Files.
9:55So here's our collection of multiple files,
9:58and this file is a placeholder variable.
10:00Meaning for each time we go through this loop,
10:03this file's going to represent one of those files.
10:05The first file it's going to represent is this one.
10:07Then in the next iteration of the loop,
10:09it's going to be this one, then this one, then this one.
10:11And this is going to allow us to do things
10:13to each file in that collection.
10:15So a lot of the times when you're in a loop,
10:17you're going to, again, you're going
10:18to interrogate that object or that item,
10:21figure out what you want to do with it.
10:22And then maybe you'll have some logic statements,
10:25some conditional statements down below this
10:27that will say, hey, if this file is in this state,
10:29let's do something to it, that kind of thing.
10:31But this one we're just going to output the name of the file.
10:33So let's just highlight our loop here.
10:34It's going to loop through each one and just return the name.
10:37So that's the for-each loop.
10:38It's all about just looping through a collection from top
10:40to bottom.
10:41Here's a more are real world example of using
10:43a for-each loop with a conditional statement,
10:46our switch statement.
10:47So the first thing we're going to do
10:49is store all of the disks from get-cimInstance.
10:52We'll get all the disks here from the Win32 logical disk
10:54class.
10:55And let's see what we got in there.
10:57So we've got three disks in here-- A, C, and D.
11:00Now we're going to write a little for-each.
11:02We're going to see for each drive in the disk--
11:04or you could do something like this;
11:06that doesn't make any sense.
11:07I like doing this-- disk in disks.
11:09And we would store disk.
11:10There we go.
11:11That makes a lot more sense to me.
11:13So our disks is our collection of disks.
11:15And then we're going to represent each disk
11:17through this disk variable right here.
11:19And now we just need to replace all of these with this disk--
11:23perfect.
11:24So now inside of the loop we have a little switch statement.
11:27It's going to look at the drive type, which
11:29is going to come back as a number one through six.
11:32If it's one, it's going to output unknown, two,
11:34floppy removal, all the way down here to RAM disk.
11:37So it's just simply looking at the drive type,
11:40and then it's going to return back the device ID as well
11:43as that name.
11:44This is a pretty cool one.
11:45So let's go ahead and just run that for-each,
11:47and what do we get?
11:48We're going to get those three drives back.
11:49First one is A, it's a floppy removal.
11:52C is a hard drive.
11:53D is a CD drive-- exactly what I have in my local system here.
11:56Next up we have a do-while loop.
11:57And do-while loops are good when you want to run something
12:00until a condition is met.
12:02So you don't know how many times you want to run it.
12:04You're going to run it.
12:05You're going to run a block of code, which you're
12:06going to put after the Do inside of this is block here,
12:09and it's going to run it.
12:10It's going to then analyze, after that code is ran,
12:13the condition in the While.
12:14So it's saying loop while this condition is true.
12:18So it's going to continue to loop
12:19until this condition is true.
12:21If the condition value is false, it's
12:22going to run that block of code again and again and again.
12:25So this is good for running things
12:27until a state of something is flipped
12:30or until whatever condition here is met.
12:32So in our example here, we're going
12:33to ask the user for some input, and they're
12:35going to be stuck in an infinite loop
12:37until they guess what the magic number is.
12:39And we put the magic number here as 1337.
12:41So it's just going to run this block of code,
12:44ask the user for a number.
12:45They're going to type in a number.
12:47If they type in the right number,
12:48great, it's going to exit the loop and say, whoa,
12:50you got lucky.
12:51If they enter a number that isn't our condition,
12:54then it's going to run that block of code again and again
12:56and again.
12:57So let's try this out.
12:58Let's go ahead and execute this.
12:59Hey, oh, and by the way, this always
13:02confuses me when I look in the shell.
13:04This is actually just our block of code that's running here.
13:06But here, guess the magic number to escape.
13:08Let's do it.
13:09Let's type in 30.
13:10Is that the magic number?
13:11No.
13:1140?
13:12No.
13:13No, no, no, no-- I could guess all day long, until it's 1337.
13:17And then, hey, you got lucky, and it exited the loop.
13:19So that's what do-while loops are for running it
13:21until a condition is true.
13:23The last loop we have here is our for-loop.
13:25And this is for when you want to run
13:27it a specific number of times.
13:29So you have your initializer here as the first type.
13:31We define all these variables here inside of our for block.
13:34So our initializer is what a variable starts out as.
13:37We're saying i is going to start out at one.
13:39Then we have our condition; loop until this condition is true.
13:45As long as i is less than or equal to 10,
13:47it's going to continue running this block of code,
13:49and increment it-- this is our incrementer here--
13:51and increment it by one every single time.
13:54So this loop is going to run once.
13:55This value is going to become two.
13:57It's going to evaluate the condition.
13:59Is two less than 10?
14:00No, run it again.
14:01OK, it's going to run it again in increments of three.
14:03Same thing-- less than three?
14:04Nope, it's going to keep going until it's 10.
14:07And then it's going to run it and exit the loop.
14:11So let's try this out.
14:12We'll execute this.
14:13It's going to run all the way up to 10.
14:15Once it hits 10, it's going to exit it out.
14:16So for is good for when you want to run something
14:19a specific number of times.
14:20So for-each looping through collections, do-while looping
14:23until a condition is met, for looping
14:25a specific number of times.
14:27Let's move on to error handling.
14:28So error handling is how we're going to trap for errors
14:31here in our code.
14:32And generally what you'll do is you have a block of code that
14:34could potentially cause and error, especially when
14:36you're dealing with a network or dealing
14:38with files and directories.
14:39If something bad were to happen that's unexpected,
14:42we can gracefully recover from that error,
14:44try to do something about it before trying more code.
14:47Now, I just want to mention these here.
14:49We've got our errorVariable and errorAction common parameters.
14:52Common parameters are those parameters
14:54that are common to every single commandlet out there,
14:57so these are on every commandlet.
14:58And what we can do is use the errorVariable common parameter
15:01to store that error inside of a variable,
15:03and then maybe do something with that variable down the road.
15:05Or we have an errorAction, which we can say,
15:07this is what we want to happen, or how
15:10do we want to continue on an error were to occur.
15:12Continue means it'll still throw the error,
15:14but it'll just continue executing our code.
15:16Stop, on the other hand, would stop.
15:17It'll immediately halt execution of our script.
15:21And that is going to be useful when
15:23we get into try-catch-finally.
15:25This is really how we're going to handle errors here
15:27in PowerShell.
15:28With the try-catch-finally block, as we call this.
15:32And what we're going to do is wrap
15:34potentially error prone code inside of a try-block,
15:38meaning try this code.
15:40And if that code were to fail and we
15:42have an errorAction of stop, it's
15:43going to stop immediately right here
15:45and jump down to the first catch block.
15:47And what we can do now is we can trap for specific errors,
15:50like we're doing here.
15:51We're saying run this block of code,
15:54if that error that was thrown is of this type.
15:57So it's going to analyze the exception type on that error .
16:00And if it's an item-not-found exception, which
16:02we will get from this because this file doesn't
16:03exist, by the way, then it's going
16:05to run this block of code.
16:06So we can trap for specific errors in our catch blocks
16:08and then maybe do something about it.
16:09Say, hey, user that file doesn't exist.
16:11Go create it.Or maybe, if we're totally
16:13in control of this process and that file doesn't exist,
16:15we would create it.
16:16And then we could continue on with our code.
16:18Or we can catch generic errors.
16:20If we don't know the kind of error that's
16:21going to be thrown, then we could just run a catch block
16:24and then give them a nice message; sorry,
16:26couldn't complete the process.
16:28Please try again-- that kind of thing.
16:29And then you're finally block is going
16:31to run no matter what, great area here for clean up,
16:34destroying those database connections
16:36or releasing things back to the file system, closing
16:39files, that kind of thing.
16:42So let's run this block of code.
16:43What's going to happen?
16:44What do you think is going to happen here?
16:45Is this first line going to run starting some code?
16:47Yep, sure is.
16:48Is this line going to run?
16:49Yes, but it's going to throw an error.
16:50And what happens when it throws an error?
16:51It's going to stop.
16:52Does that mean this line is going to run?
16:54No, we should never see this line of code
16:55because this is going to jump here to our first catch,
16:58and you can have many catches inside of here.
17:00If you want to catch for many different kinds of exceptions,
17:02you can certainly do that.
17:03But it's going to run this one, and this
17:05will be the type of error that is thrown.
17:08So that's why then it should run this code.
17:10This will not run because we already caught it.
17:12And then our finally block will always run.
17:14So let's go ahead and try this out here.
17:16Let's run this and see what we get.
17:18So it's just showing us our block of code in here,
17:20and here's what happened.
17:21Starting some code, check the path to your file,
17:24and have a nice day.
17:25So it started some code.
17:28An error occurred, and it was caught and sent
17:31to the first exception.
17:32And it matched the exception type,
17:34so it said, hey, check the path to your file,
17:37and then the finally ran.
17:38So that's error handling.
17:39Definitely wrap try-catches around code
17:42that could potentially cause an error.
17:44The last thing we're going to look at here is functions,
17:45and functions are awesome.
17:46This is what allows us to get a little bit of code reuse
17:49inside of our scripts.
17:49So especially if we're calling the same block of code
17:52over and over, why duplicate that code?
17:53Why not put it into a function that we can use?
17:56A good thing to do is to create a utility script
18:00with all your functions in it.
18:01You can put that in your profile script, and that way every time
18:03you launch the console, you have these functions
18:05available to you, and you can just
18:06call them whenever you need to.
18:08So here's an example of a very simple function
18:10called get-computerInfo.
18:11You would use the function keyword, give it a name.
18:14We're going to specify a parameter
18:15block as well because you can accept parameters in functions.
18:17And we're going to accept an array of computer names.
18:20Then we're going to specify two commands here-- get-service ,
18:23where the status is running, and get-process,
18:25where the CPU is greater than one.
18:27And we're going to pass in from the computer name
18:29parameter to the computer name parameter
18:32here on these invoke commands.
18:33So we're going to highlight all this and create the function.
18:36Now that we have the function created, it's in memory,
18:38and now we can run that function,
18:40call all those commands by using the name get-computerInfo,
18:42the name of the function, and we'll
18:44pass in as the parameter here a couple of servers.
18:47So let's hit execute, see what happens.
18:49There it is.
18:50Both of those servers-- there it is.
18:52It's still running across all those servers.
18:54But there it is.
18:55Just ran that block of code by the name
18:58that we have it when we defined that function-- very cool.
19:01Here's a little more of an advanced function here.
19:03This one, and this is useful, and this
19:04is one I use all the time, is called Send Gmail Message.
19:08So here's a function I threw together
19:10that will actually send a message
19:12through Gmail, so a little more involved
19:15with our parameter declaration because we're
19:17specifying that we want this first parameter
19:20to be mandatory.
19:21So we can set up a parameter attribute up her,
19:23specify the property mandatory equals true.
19:26That will make the recipient parameter mandatory.
19:28That's how you can create mandatory parameters.
19:30Also are from parameter here has a default on it,
19:32so that means we don't need to supply it.
19:34If we do, it'll override it.
19:35If we don't, it'll pick up the default here in the from.
19:38Then we have a subject and a body.
19:39These are optional parameters because we
19:41didn't specify any sort of parameter attribute above them.
19:44But that's it.
19:45So we're accepting all these different kinds of parameters.
19:47And now here's a really cool technique called splatting.
19:49This is great.
19:49Because rather than type out all of the individual parameters,
19:53and especially when you do stuff like this,
19:55when you start specifying parameters,
19:57and then we use the tilde be there
19:59to make it more readable instead of just one long line.
20:02It gets pretty ugly with all these still tildes, right?
20:04Well, we can get away from that entirely by using
20:06splatting, a really, really cool little feature that
20:08allows us to just wrap all the parameters,
20:10just as long as we match their names-- just
20:12use their names in here-- inside of kind
20:16of like a hash table here, where we have an ampersand.
20:19Then we have an open close bracket.
20:20Then we specify all the parameters and their values
20:22within here.
20:22Put that inside of a variable and pass that variable using at
20:27and then the name of the variable to your commandlet.
20:29It will match up everything inside of the hash table
20:32here to all the parameters inside of your commandlet.
20:35Again, that's known as splatting,
20:36and that's just an awesome technique.
20:38Definitely use that because it makes code much more readable.
20:41So this is a very simple little function that does a lot.
20:45Now, the only thing with Gmail, it has to be sent on port 587,
20:48have to have SSL enabled here, and then we need credentials.
20:52So this is actually going to be an interactive function
20:55because it's going to prompt the user for their credentials.
20:57But let's go ahead and create this function.
20:59All right, good, it's created.
21:01And then we can call it Send Gmail Message.
21:04Here's a recipient-- I'll send it to my Nugget Lab account--
21:06subject, and here's a body.
21:08Let's go ahead and see if this works.
21:09Now, it's going to prompt me for my credentials, which is cool.
21:12I can do that.
21:14And as long as we don't get any errors back,
21:16that should have worked.
21:17All right, we can verify that.
21:19Let me bring up the browser here.
21:21Wow, that was quick.
21:22There it is, done.
21:24There it is-- test from function.
21:26Hello, from PowerShell 4 Foundation.
21:28So we just sent a Gmail.
21:30We sent an email through Gmail, using a function.
21:33All right, let's bring this all together
21:35with a cool little script called get-serverStatus.
21:38So this going to email a machine status report.
21:40It's going to generate an HTML email with the machine status,
21:43being online and offline and up time.
21:46So we've got a couple of parameters in here.
21:48One, it's going to be an array of computers.
21:50And the other's going to be a switch called offline only.
21:53So here's how you build a switch parameter.
21:55Just give it the type here of switch.
21:57So what we're seeing here with this
21:58is it's only going to send the email if they're unresponsive,
22:02if they're offline.
22:03We've got two functions in here, and then we've
22:06got a body that's going to generate some HTML,
22:08and then send the email using the function we just created.
22:11So let's go through this line by line here.
22:13Start here with our first function.
22:14This is called get-computerUptime.
22:15And what this is going to do is accept a computer name
22:17parameter which will flow in from our upper script
22:20here when we call this function.
22:21So we're first going run get-W on my object
22:23to get the Win32 operating system.
22:25And then we're going to use the convert-to-date-time method
22:28that is on the get-wmiObject and pass in the property last boot
22:32up time.
22:32So that's going to give us the last time
22:34this machine was booted up.
22:35And to get the up time, we're just
22:36going to subtract that from the current date and time,
22:38and that'll give us how long this computer has been
22:41up and running-- pretty cool.
22:42And then we're going to use the static method here,
22:45called format-on-the-string object, or the string type,
22:48I should say.
22:48And we're going to pass in a big string,
22:50and this is how you can do formatting here.
22:52This is really, really cool formatting.
22:54So we're saying this is the first one, second one,
22:58third one, fourth one.
22:59This is going to map here to one, two, three, four.
23:01That's how you map the values into this string.
23:05That's all it is, so first, second, third, fourth, first,
23:09second, third, fourth.
23:11So that's how we're going to get days, hours, minutes,
23:12and seconds.
23:13And this is the format string we're going to use,
23:15so zero, zero is just saying format this
23:17with two places in the number.
23:20That's it.
23:20So this is actually just going to return that value
23:24as a string.
23:25Our next one here is our send Gmail message
23:26that we just looked at, same exact thing.
23:28The big difference, though, what I want to show you is right
23:30now this is interactive.
23:32We can actually make this totally automated.
23:36We can use that kind of a cool technique here
23:38that will get the credential, save it to an XML
23:42file on the local machine.
23:43It'll hash it out and store it securely,
23:45and we can read that file in any time we
23:47want to reuse that credential.
23:49In fact, let's just improve this function right now.
23:52This is super useful real world stuff.
23:53In fact, I had a buddy from CBT Nuggets, one of our sys
23:56admins call me up last week.
23:57Kurt, shout out to you, buddy.
23:59And he said, hey, Garth, I've got this PowerShell script.
24:02It needs to prompt for credentials.
24:05How do I get rid of that prompt and automate this?
24:07That interactive thing just won't work for this script.
24:09And I'm like, hey, you came to the right place, buddy.
24:11Let me show.
24:12And here's how it works.
24:13We'll do a cred, get-credential.
24:15So we're going to prompt ourselves right now.
24:17And then we're going to pipe that to export CLI XML.
24:21Let's just put this in a file on our local machine
24:24here called, how about, pass.dat.
24:27There we go.
24:28And now let's call this.
24:31Put my stuff in here.
24:33This is the only time I'll need to do this.
24:35And there we go.
24:36Now, we should have that on the file system.
24:38Check this out.
24:39Let's go in our C drive.
24:41There it is-- pass.dat.
24:42Let's open this up with Notepad, and there it is.
24:45There's our credential object.
24:46Notice, the password?
24:47Yeah, that's right; it's hashed.
24:48Not only is it hashed and secure,
24:50but it's hashed on this machine.
24:51It's tied to this machine.
24:53So if we were to move this file, or somebody
24:55were to get a hold of it and move it to another machine
24:56and try to use it, wouldn't work.
24:57It's tied to this machine-- Awesome stuff.
24:59So now that we did that, we can get rid of this.
25:02And now right here, we can just do an import CLI XML.
25:08There we go.
25:09that's it.
25:10Now we went from an interactive script to one
25:12that we can totally automate-- very cool.
25:14All right, so those are functions.
25:16We've got those both inside of our script ready to go.
25:18Now the next thing we're going to do
25:20is we're going to create a little for-each loop here.
25:22And the results of this for-each loop
25:24are going to be our own custom object with the computer, which
25:28is going to contain the name of the computer, if it's online
25:30or not.
25:31We're going to do that running our test connection, which
25:33is just going to return true or false because we're
25:36using the quiet parameter here against the computer that's
25:38currently in the loop.
25:39So if we pass in 10 computers, this
25:41is going to create a PSCustomObject
25:42for each computer that was passed in,
25:45and each object will have these three properties--
25:48name of the computer, whether it's online, true or false,
25:50and then the uptime, which we'll call our function of above,
25:52pass in the computer, give us the up time for that computer.
25:55All of that will get stuffed.
25:56The results, meaning we'll have however many computers were
25:58passed in, that number of custom objects
26:00stored, inside of this variable.
26:02Then we're going to create some HTML here.
26:04Now this is kind of interesting.
26:05See this right here-- the beginning
26:07and end here surrounded with an ampersand?
26:09This is known as a here-string.
26:10This will allow us to create a big block of character,
26:15of text, without having to terminate it and do
26:18all kinds of crazy stuff with multiline entry.
26:20So this is great when you have a big block of text or whenever
26:23that you want to store.
26:24So that's what we're going to; we're
26:24going to store our HTML header in here,
26:26which contains our CSS, our Cascading Style Sheet there.
26:29There we're going to generate some HTML.
26:31Before we do that, we need to use an if-statement
26:33to see if that offline only parameter is passed in.
26:35Because if it was passed in, we're
26:37going to put a little where condition in here that says,
26:40we only want to work with objects that are offline.
26:43Hence the word object online equals false.
26:45And I did this just for readability.
26:47There's a much better way to do this
26:48because of all the duplicated code we have in here.
26:50But for readability purposes, a nice simple if-statement
26:53to say, if that online only, offline only flag was piped in,
26:57then we're only to work with computers
26:58that are not responding.
27:00Otherwise, if it wasn't passed in,
27:02then we're going to get all the machines
27:04that the user passed in.
27:06So what that'll do is generate some HTML here using
27:09convert to HTML.
27:10We'll pass our header in.
27:11We'll pass our pre-content, which will happen first,
27:14then our post-content, which will happen last.
27:16pre-content's just going to say server status report.
27:18Then our post-content's going be generated
27:21and the date that it was generated, with our header
27:23being our CSS.
27:24And then everything else is going
27:26to be the results because that's what we're piping over
27:29to our HTML commandlet there.
27:32And finally, we're going to say, if the results that count
27:34is greater than zero-- we've got to have results.
27:37Otherwise, why send an email?
27:38Then we'll use our send Gmail function
27:40to send our server status report via email.
27:43So that's our script.
27:44Let's save it.
27:45So let's execute it.
27:46Let's fire up a shell here, and let's
27:47just check our execution policy real quick just to make sure.
27:51OK, I did.
27:51I removed it from all sign back to remote sign-- good deal.
27:53So we're good.
27:54We'll be able to execute this.
27:55Then we'll use our call or indication operator.
27:57There it is.
27:58And since this script is sitting on a remote file share here,
28:01we need to do that.
28:02FS Nugget PS V4.
28:04This is 18.
28:07Scripting to, and the name of the script is
28:09get-serverStatus.ps1.
28:12Now we want to pass in some parameters here, ready?
28:14What parameter is that?
28:16Uh-oh, did I-- yep, computer name.
28:18I was going to say, it's not auto-completing.
28:19I didn't type the path in.
28:20But I did, because there it is, computer name.
28:22What do we want pass in?
28:24Let's test out all our computers here-- DCNugget, AppNugget ,
28:26and FSNugget, all our servers.
28:28Hit Enter, and it's going to run, and it's done.
28:32How do we know that that did anything?
28:35Maybe we should add some output or some logging to our script.
28:39definitely easy to do, but we'll keep it simple here.
28:41Well, we can check because we can go to my inbox
28:43here and see.
28:44We've got an email.
28:44Let's see what we've got.
28:46Check it out.
28:46Now, unfortunately, Gmail is our email client here,
28:50and it's not a fan of HTML emails.
28:53You could do it.
28:54It's still even trickier.
28:55There's a lot of gotchas.
28:56But if you wrap your CSS to an inline CSS, it can work.
29:01But even that's iffy.
29:02So let's do this.
29:03Let me just copy our code here.
29:05And let's fire up Notepad and paste it in here.
29:09We'll save this as server-report.html right
29:16on the desktop.
29:16And let's see what we've got.
29:19Hey, there's what it looks like, cool.
29:21So all of our computers are online, which is true.
29:23And here is their up time, which is accurate because we just
29:26rebooted FS Nugget in a previous Nugget not long ago, very cool.
29:29So this would be a good script to turn
29:31into something like this.
29:32Instead of emailing this, we could maybe generate a report
29:37for each machine, put that in an IS server somewhere.
29:39And then any time we need to check
29:40the status of that machine, we could just
29:42hit that machine's specific page.
29:44I'll save that one for a future Nugget or maybe our real world
29:46course, or maybe it'd be good project for you
29:48to try out on your own.
29:49Well, let's finish this Nugget up with a look
29:51at your challenges.
29:52Challenge number one, write a function
29:54that accepts a computer name parameter and retrieves stops
29:56services with the startup type of automatic
29:58for the machines passed in and call the function
30:00Pretty straightforward here-- it's just
30:01going to be a one liner.
30:02Write a one liner to get-services
30:04that have a status of stop and start a type of automatic.
30:08But we're going to wrap a function around this
30:10and then accept a parameter.
30:11So really just kind of getting you familiar with writing
30:13your own function,
30:14Then challenge number two here's going to build on this.
30:17Write a script that utilizes the previous function
30:19and stores the results in a variable.
30:22Loop through the services variable
30:23and attempt to start them, utilize error handling
30:25to catch errors that may occur.
30:28So store the results of that function inside of a variable,
30:31then loop through it one a time, which
30:32is going to be what kind of a loop?
30:34Because we're looping through a collection,
30:35it's going to be a for-each loop.
30:36Loop through it and try to start each one of those services
30:39inside of that loop and also wrap that with a try catch.
30:43So that way, if any errors occur,
30:44you can decide what to do.
30:45Do you want to continue trying to start other services?
30:48Do you want it to totally stop executing?
30:50What do you want to do then?
30:51And of big one here, challenge number three--
30:53write a script that generates an HTML file--
30:55this sounds familiar-- containing information,
30:58services, and event logs, accept parameters for the computers,
31:01type of event log and status of services.
31:04This is a fun one.
31:04So the whole idea here is that you're
31:06going to have a file any time you execute
31:09this, one for each machine.
31:11And it's also, as the name implies
31:13here, the naming convention-- day dash month dash year
31:16underscore machine dot HTML.
31:18So you're going to use WMI or CM or both to capture
31:20machine information-- get things like the operating system,
31:23the number of disks or what disks are on a system.
31:25That kind of stuff-- stuff we've worked with.
31:27Then, step number two, you're going
31:29to use get-service to capture service information,
31:31pass a parameter to the status value
31:33so that way whoever's running the script can say, hey,
31:36I want stop services.
31:36No, maybe I won't run any services, or maybe I want both.
31:39Then, step number three, use get-eventLog to capture
31:41event logs.
31:42Again, pass a parameter here for the log type.
31:44So if they want to retrieve the system or the application,
31:47or maybe they want to retrieve them all,
31:48you can put some logic in there to say,
31:49if they don't pass anything in. we're
31:51going to give them all of the event logs.
31:53And then finally, you're going to use Convert HTML to generate
31:55that HTML file, and you can use methods of get-date
31:58to name the file here.
31:59So use get date dot day dot month dot year,
32:02and then you can use your computer
32:03name to name the file, and output that wherever
32:06you want-- maybe in the temp directory or wherever.
32:08But there you go.
32:09There's your challenges for this Nugget.
32:10As always, good luck, and you can find the solutions
32:13underneath these regions.
32:14All these files are, again, downloadable
32:16on the right-hand side of the course page.
32:18In this CBT Nugget, we covered the scripting essentials.
32:21We took a big look at all the core language constructs there.
32:24We took a look at variables.
32:25We saw how to work with things like control of flow statements
32:29or ifs and your switches.
32:30We looked all the different looping constructs out there,
32:32talked about error handling, and saw
32:34how to write some functions.
32:35And at the end here, we pulled it
32:36all together in a fun little script
32:38to monitor the server status of all the servers on our network.
32:41I hope has been informative for you,
32:43and I'd like to thank you for viewing.
Scripting - The Real World
0:00Scripting-- The.
0:01Real world.
0:02In this Nugget, we're going to have some fun.
0:03We're going to look at two scripts, one simple one
0:05to import users in Active Directory and one that's
0:07a little more complex that will monitor
0:11all the servers in our network.
0:12So the goal of this Nugget is number one, to have fun.
0:14Number two, to learn how to decipher other people's scripts
0:17and read code that isn't necessarily your own.
0:20And number three, I'm going to show you how to debug scripts.
0:23So let's jump into the Virtual Nugget Lab and get to it.
0:25Welcome back to the Virtual Nugget Lab.
0:27Let's jump over to our Nugget Lab files here.
0:29And what I want to do first is just give you a little context
0:32around what we're going to do.
0:33Script number one, we are going to import users
0:35into Active Directory.
0:37So I've got a bunch of users here.
0:38We've got a CSV file containing a bunch of users.
0:42And you may have recognized some of these users.
0:45That's right, we're going to import some Star Wars
0:47characters.
0:47Good times.
0:48So how's it going to work is let's flip over
0:50to our domain controller here.
0:52And inside of Active Directory Users and Computers,
0:54we've got a couple of OUs.
0:55We've got a Light Side OU and we've got a Dark Side OU.
0:57So the whole idea here is to import Dark Side users
1:00into here.
1:01We'll also create a group on the fly
1:02and put our admins into a group.
1:04And we'll do the same thing over here for the Light Side.
1:07So back over to our client machine here.
1:09This is what our CSV file looks like.
1:11You can see we've got fields such as our given
1:13name, surname, initials name.
1:14Their Sam account, the department they belong in,
1:16the forceID-- which is our employee ID
1:18so know that that's not going to line up with any field
1:21inside of Active Directory.
1:22The side that they're a part of, Light or Dark.
1:25The role.
1:26If they're an admin or a user.
1:27This can help us determine what group they go into.
1:29And then if their account is enabled.
1:31And we'll give them a default password here.
1:33So this is our CSV file.
1:36Let's jump into PowerShell.
1:37And here is the script that we're going to look at.
1:40So I tried to keep this one as simple as possible.
1:41This could certainly be optimized.
1:43There's a lot of things we could do to make this a lot better.
1:45But just to get us a simple script
1:47to work with here to see how to import Active Directory Users
1:49and create groups and add users to groups,
1:51this will definitely do for round one.
1:53We'll look at a more complex script here coming up shortly.
1:55So the first thing we're going to do here
1:56is just define a parameter block.
1:57We're just going to accept one parameter, the CSV path.
1:59So when we call the script, we're
2:00just going to pass in the path to wherever that CSV may be.
2:03Then we're going to create some groups.
2:05We're going to create a Light Side admin group
2:07and a Dark Side admin group.
2:08So we can throw the admins for those users into these groups.
2:12So the first thing we're going to do is to check.
2:14We need to make sure that these groups don't exist.
2:16Because we don't want to create them if they already exist.
2:18We'll get an error if that's the case.
2:19So we'll create a variable here called Light Side Group.
2:22And we're just trying to get AD group where the object name is
2:24the same name that we're going to use
2:26to create the group with.
2:27If it doesn't exist-- and we can check
2:29that by comparing it to the null value,
2:31meaning this object doesn't contain anything-- then
2:34we will run the new AD group commandlet
2:37and pass in everything we need to make that group.
2:40So the name, the Sam account, name the category, the scope.
2:43And then we've got some other ones here, such as the path.
2:45We want it to go inside of the Light Side organizational unit
2:47that we have created there in Active Directory.
2:50And if that all successful, if we create it,
2:52then it'll output to the screen Light Side Group created.
2:54So that's step one.
2:55Create the Light Side Group.
2:57Then we do the same exact thing for Dark Side Group.
2:59You know, we could actually just test all this out right now.
3:01Just this block right here.
3:02Let's highlight that block of code.
3:04Let's run the selection and see what happens.
3:07Cool.
3:07Light Side Group created.
3:08Dark Side Group created.
3:09We could verify that by heading over to-- here
3:12we go-- our domain controller here.
3:14And let's just refresh.
3:17Right there.
3:18Hey, look at that.
3:18We've got our Light Side admins.
3:19And if we head up the Dark Side here, we can refresh in here.
3:22And we've got our Dark Side admins.
3:23And here's the data.
3:24We included those Imperial jerks.
3:26And there's our members.
3:27We have no members in it yet.
3:29So once we add those users in, we
3:30will add the members that have the admin role in their record
3:34in that CSV file to this group.
3:37Now if we ran that again, we should get nothing.
3:41Yeah, nothing happens, right?
3:42Because it's already created.
3:43So it hit this IF statement, and it wasn't null
3:46because this returned a value.
3:48In fact, we can just test this out as well.
3:50And we see that's going to return something.
3:52So that object would not be null, meaning this IF statement
3:56would fail.
3:57And it would just skip the block entirely.
3:59So that's why it would only ever get created once.
4:02Now the next block here is creating our users.
4:05So we're going to run an import CSV against that CSV path
4:08and pipe all of those records into the
4:10for each object command line.
4:12Meaning this block of code right here, all of this,
4:16is going to run once for each record inside that CSV file.
4:19So the first thing we're going to do is set up a little
4:20splatting here.
4:21That way, it'll make it very easy
4:22to pass all these parameters into the new AD user
4:26commandlet.
4:27So you've just got to make sure that these all
4:29line up with the parameter names inside of that commandlet.
4:31So this is a good thing to do just
4:33because it makes it more readable
4:34than a big long command line.
4:37But also makes it easy to do things like this.
4:39Right here, employee ID.
4:40I'm going to map that force ID.
4:42And we saw another way to do this using custom properties
4:44in our Pipeline Two Nugget when we revisited the pipeline.
4:48And so this is just another way to do that using splatting.
4:51Same result, though.
4:52So we're just passing all of those objects, those properties
4:55of those objects, into what will be
4:57the parameters to new AD user.
4:59And also notice this right here.
5:01This is interesting.
5:01So we're setting up the path.
5:02So we make sure that those users go into the right side.
5:05And we're using what's called the sub-expression inside
5:07of here.
5:07Makes it a lot more readable and easier
5:09than concatenating strings together,
5:11especially when you need to stuff
5:12something in the middle of a string like we're doing here.
5:15So this will resolve to either a Light or Dark,
5:17and that'll put them in the proper organizational unit
5:19depending on the side of the property of that record object.
5:25So cool.
5:25And another thing we're doing here,
5:26this is another interesting thing,
5:28is we have the value true.
5:29Let me open up our CSV again.
5:31See this value here?
5:32It's true.
5:32But it's actually a string coming in.
5:34So we need to convert that string to a Boolean,
5:37and that's why we're prefixing this property with Boolean.
5:41That will convert that.
5:42So you'll see yourself doing that quite a bit
5:43when you need to convert to and from data types.
5:46The only other thing that's interesting here is-- oh yeah.
5:48Let's see.
5:49The account password.
5:50We need to convert this, because it's
5:52plain text, to a secure string to pass it in here.
5:54And we're also going to force the user
5:55to change the password at log in.
5:58So we wrap this new AD user inside a try catch block.
6:01Good thing to do because if any data was invalid or something
6:04that Active Directory didn't like, it would cause an error.
6:07And if we didn't wrap this in a try catch block,
6:09it would bomb the whole process.
6:10It wouldn't continue on because we have
6:12the error action stop here.
6:14So that's why we're going the try catch around this.
6:16And a real good thing to do inside of the catch
6:18here would be to set up some logging.
6:20So we could output anything that did happen,
6:23any errors that occurred, we could upload it to a log.
6:25And then maybe do some manual intervention
6:26for those users that didn't make it in or fix their records
6:28and rerun the import kind of thing.
6:30Now back up here.
6:31If the import of that user was successful,
6:33then we're going to check the role.
6:35If they're in the admin role, then we're
6:36going to run the Add AD group member
6:38and add this, this member here based on their same account
6:42name, to the appropriate group.
6:45And we're using the Sam account name.
6:46There's a bunch of ways that you can identify a group here,
6:49one of them being the Sam account name.
6:50And this is the Sam account name of the group
6:52that we defined above.
6:53So it's either going to be Dark Side admins or Light Side
6:55admins.
6:56And we're doing the same thing we did here
6:57in organizational unit two to build this string using
7:00a sub-expression.
7:01And when it's all said, it's just
7:02going to say Import Complete.
7:04Now, there are some things missing from the script
7:06that I'll challenge you to add on your own.
7:07Number one, what if we ran this multiple times?
7:10And that user already existed.
7:11It would probably throw an error,
7:11which wouldn't be a big deal because we
7:12have a try catch around here.
7:14But one thing you could do is run a query
7:16against Active Directory to see if that user already exists.
7:18And if it does, maybe run a set rather than an add.
7:21So that way if anything changes in that spreadsheet over time,
7:24you can just rerun it and it'll just
7:26update those specific properties in Active Directory.
7:29Another good one would be to set up a profile path.
7:32So if you have users' profiles on network share somewhere,
7:35you could easily set that up and tie that to their Active
7:39Directory account.
7:40There's a lot of things you could do with this script
7:41to expand it.
7:42But just a couple of things to think about there.
7:44So I think we're ready to rock here with this script.
7:46Let's flip over to commands.ps1, and let's
7:48give this script a whirl.
7:49And it's executing, creating groups,
7:51even though it skipped the group creation.
7:52Then created Active Directory Users.
7:54Import Complete.
7:55If we head over to our domain controller
7:57and refresh our Dark Side organizational unit,
7:59check it out.
8:00There's all of our Dark Side employees.
8:02And if we head into our group there,
8:04Dark Side Admins, head into Members, there there.
8:06We have Vader and Emperor.
8:07Because if we head back to our CSV file here,
8:10we'll see we have the admin flag turned on here for Skywalker
8:13and Princess Leia, as well as Vader and the Emperor.
8:17Everybody else there is a user.
8:20So back to our domain controller.
8:21If we head down to the Light Side,
8:22let's do a refresh here just to make sure everybody made it.
8:25They did.
8:25Head into our Admin group.
8:27Check out our Members.
8:28And there they are.
8:28Very cool.
8:29So there you go.
8:30Just a simple little script just to show
8:32how easy it is to import users from a CSV
8:34into Active Directory.
8:35Moving on here, let's take a look at the next script.
8:38Now, this next script is really cool.
8:39And it's not one that I wrote.
8:41This is actually in the gallery over on TechNet.
8:43And this is a very popular script
8:45that will monitor all the servers in your network.
8:48In fact, this individual here, shout out
8:51to Ben Wilkinson who made this.
8:53This is just a fantastic script.
8:54It's a good script for learning.
8:55It's a good script to use in production.
8:57It's just a great script all around.
8:59And the reason I liked it and I wanted to use it in this Nugget
9:01is because he uses a lot of great techniques in scripting,
9:04a couple of them that I want to point out and show you.
9:07And this is just a great script that you
9:08can use in your environment.
9:10It's tried, true.
9:11It's tested.
9:12And this is actually the old version
9:13I'm going to walk you through.
9:13There's a new version out with a lot more bells and whistles.
9:16It's a little more complex.
9:18I wanted to use the first version here
9:19because it's a little easier to walk through and understand,
9:21especially for beginners here in PowerShell.
9:24So this has been used across a few hundred servers
9:28and it does work very well.
9:29I would totally agree with them.
9:30I've used this quite a bit myself.
9:31And it's just a fantastic script.
9:33So I've downloaded this and I've got it here in our network.
9:35Let's go ahead and open it up here.
9:37It's in the Virtual Nugget Lab here
9:38for this Nugget in the directory called Start, Monitor, Online.
9:42So the goal of the script is to essentially just
9:46run in a big loop this script all day long.
9:49And it's going to run and it's going
9:50to monitor all the servers in your network
9:52just by doing one ping.
9:53It's going to send a ping.
9:54And if that ping doesn't respond,
9:56then it's going to do some more pings.
9:58And if those pings don't respond,
10:00then it's going to send an email.
10:01But what's really cool about this script is number one,
10:03he uses a do while loop.
10:04This whole script just runs on a do while loop.
10:07So another reason I wanted to show you this,
10:08because it's a great implementation of how to use a
10:11do while.
10:12So rather than create a script and put it
10:14on a schedule to run every five minutes
10:15or whatever, you can use a script like this,
10:18have it fire up on startup, and just let it run all day long.
10:22That's the design that I absolutely love here.
10:26And he's got another great technique
10:29that he uses, it that he initializes
10:31all the variables inside of the loop,
10:34meaning we can do things while the script is running.
10:36And every cycle, it'll pick up those changes.
10:40So let's start at the top here.
10:41Now, all of these variables outside of the loop,
10:43they're going to get initialized.
10:45They're declared outside.
10:46So the scope is we can see them throughout the whole script.
10:49But they're initialized once, when the script starts.
10:51And that's it.
10:52Everything then inside of the loop
10:54is again refreshed on each cycle.
10:57But the first variable we have here is outage hosts.
11:00So this is how we're going to keep track of the hosts that
11:03are not responding.
11:04We've got an email time out.
11:06This is the time you want email notifications resent
11:08for hosts that are down.
11:09So if we have a host that's down,
11:11we don't want to keep spamming ourselves with email
11:13every time the script cycles.
11:15And right now, the script is set to cycle every 45 seconds.
11:18So obviously we can tune these all to our environment.
11:21In fact, I did make some changes to this script
11:22so it works with Gmail and a few other little things
11:24I'll point out.
11:25But that's the next variable here, is the sleep time out.
11:28Meaning after the loop finishes, how long
11:31do we want to wait before we ping all the machines
11:33in our network again?
11:34And the default here that he has it set up at is 45.
11:37We also have the max outage count.
11:38This is the maximum number of hosts
11:40that can be down before the script is completely aborted.
11:42So if we have a network problem, if we have many hosts that
11:44go down, we don't want this to keep running and spamming
11:47emails all over the place.
11:48So we have the maximum host set at 10.
11:50And so if we only have three servers in our network,
11:52I'm going to put this down to three.
11:54Three servers.
11:55So if all three servers are down,
11:56we're going to abort this script entirely because obviously
11:59we've got bigger problems here.
12:01Then we've got our notification to and from.
12:03I set this up to go to my Nugget lab account
12:05from the admin Nugget lab account.
12:07And we've got our SMTP server settings as well here.
12:09Notice we're using our credentials
12:10that we stored in a previous Nugget
12:12here to verify or validate or authenticate,
12:16I should say, with Gmail to send the email.
12:18So those are our global variables here,
12:21our script level variables.
12:23Then we start the big old loop right here.
12:26We're going to set up a variable.
12:27This is going to get refreshed every time
12:29the loop cycles through.
12:30So this is going to store the list of available hosts, ones
12:33that are responding and the ones that are not responding.
12:36Then the first thing that's going to happen
12:37is we're going to write the data out to the screen.
12:40So this is the script that we could
12:41leave running on a monitor somewhere so we could always
12:44see it fire off.
12:45Or we could put this, again, on a scheduled job
12:47and just let it do its thing under the hood and email
12:49whenever things are down.
12:50Now, the next thing it's going to do
12:51is it's going to run a get content.
12:53So we need a file out there with a list of servers.
12:55This is our control file with all of the servers in it.
12:59So these are the servers that you
13:01want to test for connectivity in your network.
13:03So you'll have a big list of all your servers
13:05that you want to test.
13:06And a nice little thing you put in here
13:08is if you put a hash here or a comment sign in front
13:12of any server-- maybe you're doing maintenance
13:14and you don't want that server checked for whatever reason--
13:16if you put this hash sign in front of it, it'll skip it.
13:19So this is only going to grab all the servers where
13:22the match does not equal this.
13:24So it just runs to where it'll only
13:26pull up those servers where it doesn't
13:27have a hash inside of it.
13:29So that's what this little block here is all about.
13:32Then it's going to loop through all those objects.
13:33So all those servers.
13:34It's going to do this one server at a time.
13:35The first thing it's going to do is test a connection.
13:37Just do one ping.
13:38One ping, we've got error action to silently continue
13:41so it keeps going without worrying about any errors.
13:43This is either going to return true or false.
13:45So if it's true, meaning the servers are online, great.
13:48Then it's just going to output it to the screen
13:49that the servers are online.
13:51And it's going to store that server inside of an array
13:53here, inside of our available variable
13:55that we have declared above here.
13:57So that's just going to put all the servers that
13:58are available in there.
13:59But more importantly, it's just going
14:00to write it out to the screen that yeah,
14:01the host is good to go.
14:02And that's it.
14:03It'll then go to the bottom of the loop.
14:06Now, if for whatever reason that server isn't online or not
14:09responding, then it's going to go to this else here.
14:12It's going to write, OK, we've got an unavailable host here.
14:15And so it's going to do one more test just to make sure.
14:17Maybe the network was slow.
14:18Maybe that just didn't respond in time for whatever.
14:20So it's going to run one more test connection
14:22to ping it four times.
14:23And we know if we don't get anything back after four pings,
14:27we know something is definitely wrong.
14:29So we're going to say this host is officially.
14:32We'll write unavailable host to the screen.
14:34Change the background color to red,
14:36the foreground color to white so we can actually
14:37see it in the console there.
14:39And then we'll pop that server name
14:41into the not available array.
14:43Now is where the fun begins.
14:44And this is the real guts of the loop right here.
14:46So we're going to look at this outage host variable.
14:48And we're gong to say does this not equal null,
14:50meaning we've already initialized a variable.
14:52We've already had a host that was down that was in here
14:55at some point.
14:56Then it's going to run this big block code
14:57we'll look at here shortly.
14:58But if we haven't, meaning this is the first time
15:00anything's gone down since we've started the script,
15:02it's going to run this little else block, which
15:04is going to initialize the variable, add the server,
15:06add the date that that server went down, and send the email.
15:09Now if that's already happened at some point,
15:12then the next cycle in here is going
15:13to run this block of code.
15:14Because outage host will no longer be null.
15:17It'll not equal null, which means
15:19it's going to start this block of code.
15:20And it's going to run a contains key against this collection.
15:24And it's going to look for the server name.
15:26That's what this always represents,
15:27the current object that we're working with in the loop.
15:30And that's because we ran a for each object.
15:32So it's just sending these objects in one at a time.
15:35But it's going to look for that key inside of outage host.
15:38And if it doesn't exist, it's the first time
15:40this specific server went down.
15:42So it's going to add this server into the host.
15:45Again, date stamp it next to it.
15:47And then it's going to send the email.
15:49Now if this server was already in the list,
15:52then it's going to run this else block here.
15:53And this little else block is going to say, you know what?
15:56This server is already in the list.
15:57And what it's going to do is do a
15:59get date minus whatever the date of that server
16:02was inside of that list and grab the total minutes
16:05of the result of that.
16:06And if that total minutes is greater
16:08than our email timeout of 30 seconds,
16:11then it's going to remove it from the list.
16:13So that way, it'll come back in the next cycle.
16:14It'll get a next email, and it'll go through this again.
16:16But if it was underneath the email time out,
16:18it's just going to skip all of this
16:19and go through again and again and again
16:22until it hits this block of code and it removes it.
16:25So that's all this code here does.
16:27The else just initialize the variable.
16:29It's the first time anything's been down.
16:31And it adds it to the list and sends the email for that host.
16:33And then on subsequent runs here, cycles,
16:36it's just going to check to see if that server is in there.
16:38If it is already in there, then it's
16:41going to check to see if that email timeout has passed
16:44and do nothing.
16:44If it has passed, then it's going
16:45to remove it from the list so it'll
16:46get back in on the next run.
16:48So if it's not in there, that's when it gets added to the list
16:50and it sends an email.
16:51And that's what this big block of code is all about.
16:54All right, make sense?
16:55If not, I'll show you an easy way to make it make sense.
16:57And that is with debugging.
16:59Debugging scripts is the coolest thing
17:00ever because it allows us to pause scripts during execution,
17:03analyze variables, change variables.
17:04We can do so much during debugging.
17:06So hang on for that.
17:07I'll show you that, because it's extremely valuable in writing
17:10scripts or even trying to learn somebody else's
17:12scripts because you can walk through it
17:14line by line to see this stuff happen.
17:16So after all that logic is run-- and we're still in the loop
17:19here-- it's going to output just a bunch of information
17:21to the screen here.
17:22The available count, the not available count,
17:23the not available host by putting that outage
17:25hosts variable to the screen.
17:27And then it's going to say, hey, we're
17:28going to take a nap here for whatever your sleep time out
17:30is, which, again, the default is 45 seconds.
17:32So it'll say sleeping for 45 seconds.
17:34That's literally what it's going to do.
17:35The loop is going to take a little nap for 45 seconds.
17:37And when it wakes up, it's going to do one more comparison here.
17:40It's going to say the outage hosts dot count.
17:43So if we have three hosts down, and that's
17:45greater than our max outage count--
17:47which we have set at three.
17:48In fact, we should probably change this for us.
17:50We'll put an equal there.
17:51If our count is greater than or equal to the max outage count,
17:55then it's going to set exit equal to true.
17:58This is our way out of the loop here.
18:00And it's going to generate an email here just
18:02to let us know, hey, something really wrong is going on.
18:05So I'm going to totally abort the script for now
18:07until you figure that out so we don't continually
18:09spam you with emails.
18:10And the last thing we're going to do is our while.
18:13This is our condition.
18:14So as long as exit does not equal true,
18:15it's going to keep going.
18:16It's going to keep cycling through these loops.
18:18But if for whatever reason the only way out of the script
18:21is for us to manually stop it or if our hosts are greater
18:24than our max outage counter.
18:25In our case now, greater than or equal to our max outage count.
18:28So that's the whole script.
18:29Let's go up here and modify this a little bit.
18:31Let's actually change this to two
18:32so we can bring down two servers and see what it looks like.
18:35And then our sleep time out.
18:36Let's push this down to about 10 seconds here.
18:39And everything else looks pretty good.
18:41Let's save it.
18:42Now let's flip over to our commands file here.
18:44And let's go ahead and let's just execute our monitor.
18:47Let's start it up.
18:48Let's see what happens.
18:49And look at that.
18:49So here it goes.
18:50Here's what happens.
18:51It looped three times through each one of our servers
18:54that we have defined inside of our list-- which, by the way,
18:56I have up on our own file server here.
18:59Here it is, Files.
19:00So here's our server list.
19:00We just have all three of our servers in here.
19:02So that's our control file.
19:03And what I really love about this,
19:05and why he initializes and reads this file
19:08during every single cycle is we could
19:09come here and change this.
19:11Maybe we're taking our file server down.
19:12We could do that.
19:14We could save it.
19:14And then it'll skip that for as long as that is there.
19:17We could add servers on the fly.
19:18We could remove servers on the fly.
19:20So that's what's really neat about this script,
19:22is we can change things on the fly.
19:23And every cycle, it'll pick up those changes.
19:25So look at that.
19:26It's still going.
19:27It's still going.
19:27Everything's great.
19:28Now what I'm going to do is I'm just going to fire this up.
19:31Let's stop our computer here.
19:33Let's stop-- how about App Nugget.
19:35Let's bring down App Nugget.
19:36And we got to force it here, just
19:38in case users are logged in.
19:39It won't let us do that.
19:40So we'll force that.
19:41Now it's down.
19:42And now let's see what happens here with our script.
19:44Let's see if it picks that up.
19:45And I should also get an email here as soon
19:48as that happens here.
19:49Let's do this.
19:50There we go.
19:51So I've got new emails over here.
19:53Oh, unavailable host.
19:54So that's the first ping.
19:55The first ping, it didn't.
19:56So it's trying four more pings now.
19:58And once those four pings fail, we should get an email.
20:01And it should output that host to the screen and the time
20:04it went out and all that good stuff that we saw there
20:07at the end of that loop.
20:08So there it is.
20:09Unavailable host App Nugget.
20:11And now it's sleeping for 10 more seconds.
20:12And there it is.
20:13So there is the outage host variable outputted
20:15to the screen right there.
20:17See, it just has two fields inside of there.
20:18It's got the name of the server and the time that it went down.
20:20And that's what it uses for its comparison.
20:22And I just saw an email come through over here too.
20:24There it is.
20:25App Nugget has not responded for five pings.
20:27And there is the time date that it has not responded.
20:29So now the next time it's going through here,
20:32we're not going to get another email
20:33because we have this sleep timeout set out at 30 seconds.
20:37So it's going to see that.
20:38And there it is.
20:38So it didn't see it again.
20:40But because we were under that time out,
20:42it just ignored removing it from the list.
20:45So it's just going to stay inside of this list
20:47and we're not going to get any more emails until that time out
20:50happens.
20:50Al right, let me stop this.
20:52Now let me show you something incredibly useful here.
20:54How to debug a script.
20:56So let's say we want to walk through this line by line.
20:58We want to see things happen.
21:00We want to change variables on the fly,
21:02read variables on the fly.
21:03This is just a great way to learn what scripts are doing
21:06and to watch it execute.
21:07So we're going to add a break point.
21:09Now, we could do this at the very top
21:10and just watch it from the beginning and step through it.
21:12That's certainly one thing we could do here.
21:15But what I want to do here is let's
21:16say we're having a tough time understanding what
21:19the heck this part does.
21:21So what we're going to do is set a break point right here.
21:24Toggle break point.
21:25You could also use F9 on your keyboard here.
21:27Definitely get used to all of these.
21:29Your favorite ones are going to be
21:31F11 to walk through line by line and F9 to set break points.
21:34And also to stop the debugger here, Shift-F5,
21:37and to start it up, F5.
21:39But let's do this.
21:40We got a break point here.
21:41Let's also set one up here.
21:43How about right about here.
21:45Yeah, this looks good.
21:46So toggle break point.
21:47Perfect.
21:47So what we should see here is this
21:49will be the first one that hits.
21:51Simply because App Nugget's down.
21:53We're going to leave App Nugget down.
21:55It's totally shut down right now.
21:56So this will be the first thing that happens.
21:57So what I'm going to do is I'm going to start this up.
22:00Let's fire it up.
22:00What's going to happen is when it's-- and this is also when
22:03I'm debugging, I like to go back to split screen mode here
22:05because we can do both.
22:07We can work with the script as well as
22:10do some debugging down here and view variables and things.
22:12So that's going.
22:13It still hasn't hit our break point.
22:15And it'll turn yellow when it does.
22:17And we should see this is the first thing
22:18that it's going to hit, because App Nugget's down.
22:20And look at that.
22:20So unavailable host App Nugget.
22:22So the last thing that happened here was right here.
22:24Unavailable host App Nugget.
22:25It outputted that with a background color
22:27of red, foreground color of white.
22:29And then it ran out little IF statement here
22:32and then it went down into our ELSE,
22:33because this is the first time that it hit this.
22:37Because outage hosts was not equal to null.
22:40It was null.
22:41So that's why it jumped down here to our ELSE.
22:43And now it's going to write out the next thing when
22:45I hit F9 on a keyboard-- or excuse me,
22:47F11, which is the same thing here as stepping into,
22:50meaning it's just going to execute the next line of code.
22:52This line of code.
22:53Watch this.
22:53F11.
22:54See that?
22:55Adding App Nugget to outage hosts.
22:57I'm going to hit it.
22:57Now, if we were to take a peek here at outage hosts,
23:00it should be empty.
23:01Outage hosts empty.
23:03But if we hit F11 again, now we've
23:06initialized that variable.
23:07Let's do that again.
23:08Let's take a peek at outage hosts.
23:09And there it is.
23:09So this line right here added App Nugget along with the date
23:13that it was added in here.
23:14And that's going to set us up for when we get back
23:17into this and cycle again, then it's
23:19going to use that date right here,
23:20the total minutes to see if it's passed our email time out.
23:23So I'm going to keep hitting F11 here.
23:25And it's going to create the body of the email.
23:27And let's say, oh, we want to see what that body of the email
23:30looks like.
23:30Make sure everything looks OK.
23:31Let's do body.
23:33And there it is.
23:33It's the same exact text we got in our email.
23:35So now it's actually going to send the email here.
23:37I'll hit F11.
23:37I'll take a second.
23:38It's authenticating with Google servers, sending the email.
23:42And now it's done.
23:43So now it's going to cycle through again
23:44for the next server.
23:45and we're going back up to the top, cycling through, cycling
23:49through, testing the connection, so on and so forth.
23:52And now it was done.
23:53It went through all the servers.
23:55And now it is.
23:56And the reason that it didn't go through DC Nugget
23:58because we set our break point right here.
24:00And DC Nugget was up.
24:01It was fine.
24:02So it went through.
24:03Then it did App Nugget.
24:04We were actually in the second cycle by the time
24:06it hit our break point for the first time.
24:08Cool.
24:08So it's going to keep going.
24:10I can keep hitting F11 or I can hit F5 to continue on.
24:14And now it's going to go until it hits another break point.
24:17So it's doing its thing right now.
24:19And the next break point it should hit now is right here.
24:22Because outage hosts, we know that it's not
24:24equal to null anymore.
24:26There's something in there.
24:27App Nugget's in there.
24:28So it's actually sleeping right now for 10 seconds.
24:31And then it's going to go through this.
24:33And the next thing it should hit is right here.
24:36So we'll give it a second to do that.
24:38It's still pinging away there.
24:40Oh, you know what it's doing?
24:42It's pinging App Nugget again.
24:43Yeah, see?
24:44So it went through DC Nugget fine again.
24:46And then it pinged App Nugget.
24:47And now we stopped right here because outage hosts
24:50had some data in it.
24:51So now it's going to look for the key for App Nugget.
24:53Is that key in there?
24:54You bet it's going to be in there.
24:56So it's going to jump down here and run our little check.
24:59This App Nugget, it's already in the list.
25:02So we need to check, is the total minutes here
25:04greater than our email time out?
25:06And it wasn't.
25:07So it didn't remove it from the host,
25:09meaning it's not going to spam us with another email.
25:12Cool.
25:12So that's it.
25:13That's debugging.
25:13Set break points.
25:15Walk through your code line by line.
25:16You have full access to the debugger
25:18down here, so you can analyze every single variable in here.
25:20You can even change them.
25:21So if while we're debugging, maybe because we're
25:23spending some time in here, we want to expand that time out.
25:27We want to expand the sleep time out.
25:28So we can come here and do just that.
25:30We can expand the sleep time out to say, maybe, 60 seconds.
25:33There we go.
25:34Now we've just changed it, and it'll
25:35sleep longer when we're debugging.
25:37So I just hit Shift-F5 which stops the debugger
25:39and stopped the script.
25:40You could also do that in the Debug menu.
25:42But I'll tell you, learn how to debug.
25:44It's an invaluable tool, not only for your own code
25:46and your own scripts-- because when things aren't doing what
25:49you expect them to do, you can easily figure it out
25:51by walking through line by line and analyzing your variables--
25:54but it's especially an incredible learning
25:56tool for learning other people's scripts.
25:59And let's face it.
26:00PowerShell isn't going anywhere.
26:02More and more companies are jumping
26:03on the PowerShell train.
26:04There's going to be PowerShell scripts everywhere
26:06in the future.
26:07And chances are good a script is going to land in your lap
26:10that you didn't write.
26:11You're going to need to figure out what it's doing.
26:12And no better way to do it than run that script against a test
26:14environment and walk through it line by line
26:17to see exactly what it's doing.
26:18So I'm not going to give you any challenges for this Nugget.
26:20You've probably seen enough code for now.
26:22But if you do want to do something, take
26:24this startmonitoronline.ps1 script
26:26and set it up in your environment.
26:27Or set it up in our Virtual Nugget Lab environment
26:29and play around with it.
26:30It's a truly fun and useful script to get the hang of.
26:34In this CBT Nugget, we looked at scripting in the real world.
26:36We took a look at a couple of fun, real world scripts there.
26:39One that imported users into Active Directory,
26:41and another that monitored all the servers in our network.
26:44We also saw how to debug and walk
26:46through the code in our scripts.
26:48I hope this has been informative for you,
26:50and I'd like to thank you for viewing.
Desired State Configuration - Getting Started
0:00Getting started with Desired State Configuration, by far
0:03the coolest technology to hit since PowerShell.
0:06And the fact that we can utilize it from PowerShell,
0:09leveraging our existing PowerShell skills,
0:10is just icing on the cake.
0:12So it's all about declarative management.
0:14And by the end of this Nugget, you're
0:15going to say to yourself, where have you
0:17been all my life, declarative management?
0:19Because it's really cool stuff.
0:20And it's really easy to use.
0:22So we're used to standing up servers on our own.
0:24We get a server up, we go and we install the software on it,
0:26we configure it.
0:27We do it all manually by hand.
0:29But why?
0:29Machines know how to install software.
0:31Why do we need to hold their hand
0:32and walk them through the process?
0:33Wouldn't it be great if we could just
0:34describe that state of the machine
0:36in a file using PowerShell?
0:38And then just send that file over, and let
0:41DSC take care of the rest.
0:43And not only install it and configure it for us,
0:45but ensure that that machine stays in that desired state.
0:48That's what DSC is all about.
0:50And that's we're going to learn about in this Nugget.
0:51So let's get to it.
0:52So DSC is a management platform, management being an umbrella
0:55term for all the things we do to a machine, installation,
0:58configuration, deployment, everything; in PowerShell
1:01for declaratively configuring a machine state.
1:04That's the key word here, declaratively.
1:06Because once again, machines know the how.
1:08They know how to install software.
1:09So why do we need to do it for them?
1:11Wouldn't it be great if we could just tell them the what,
1:13and they do the how?
1:14That's what it's all about.
1:15And on top of that, ensuring that it stays that way.
1:18DSC solves a couple of problems that we've just kind of
1:21dealt with, we've accepted it.
1:23It's one of those, it-is-what-it-is kind
1:25of things.
1:25That's where we've been.
1:27But DSC changes that entirely.
1:29And one of those big challenges was configuration drift.
1:33We get a machine up and running.
1:34We get everything exactly the way we want it.
1:36We get all the software we want on it, all the services.
1:38We get everything configured the way we want it.
1:41And then over time things happen.
1:44We're fighting fires, or we've got
1:46a lot of hands in the cookie jar here,
1:48making changes, configuration changes.
1:50And over time that machine looks nothing
1:52like it did when we set it up.
1:54That's known as configuration drift.
1:56And that can cause a lot of problems down the road.
1:58So that's one of the big problems that DSC solves.
2:01Another really big plus here is the separation
2:03of state and machine.
2:04This is the world that we're heading to, especially
2:06with the cloud.
2:07Is machines should just be dumb pieces of hardware.
2:10And we should easily be able to take
2:12this state, the environment, the software, configuration;
2:15everything that's on that machine,
2:16and just spin up another machine in that state.
2:19Wouldn't that be a dream?
2:20Because I remember the old days.
2:21Oh, do I remember the old days all too well, where you really
2:23cared about your machines.
2:24You had, take a web server for instance, you have IAS,
2:27you've got .net, you've got ASP.
2:29You've got all this other supporting software.
2:31And if something were to happen to that web server,
2:33if that baby were to go down, that's a project on your hands,
2:36spinning up another server and trying to get it
2:38to that exact same state.
2:40So separation of state and machine is a dream come true.
2:43Because now our environments are portable.
2:46Everything that's on that hardware,
2:48portable, awesome stuff.
2:49And finally, this is enabling a whole new level of management
2:53at scale.
2:53Need to stand up a farm of SharePoint Servers,
2:56SQL servers, web servers?
2:57No problem.
2:58We can take one configuration, send it over
3:00to all those machines in one go.
3:02All right.
3:03Let's get familiar with DSC at a technical level here.
3:05And then we'll jump into the Virtual Nugget Lab,
3:07and I'll show you what a pleasure it is to work with.
3:09So first before we even dig into all the components,
3:11we'll do this as we go along here.
3:13But Microsoft has a phased approach to DSC.
3:16And that first phase is the authoring phase.
3:20So we are going to author our configurations in PowerShell
3:24using PowerShell scripts.
3:26And here's an example of a configuration.
3:27So this is what we're going to be building in PowerShell,
3:30it's simply just a PS1 file, just a PS1 script
3:32with some special keywords that describe
3:34the state of a machine.
3:36So we start everything off here with a configuration keyword,
3:39and we give our configuration a name, more on that shortly.
3:43Then we have this node parameter down here,
3:45which is the computer that we want
3:48to apply this configuration to.
3:50And you can hard code computers, so any time you run the script
3:53then it will generate a configuration
3:55file for that machine.
3:56Or you can use parameters.
3:57Because it is a script after all.
3:58And we can make it dynamic.
3:59So that's what we have here.
4:00We have a dynamic configuration.
4:02Once we build what's known as the MOF file,
4:04more on that shortly as well here,
4:06it's going to apply to that machine.
4:09And then we have what are known as resources.
4:11So we have three resources here in this configuration, a file
4:14resource.
4:14And we're saying here is we want this directory to live
4:19on that machine.
4:20So when we apply this configuration,
4:21it's going to create this scripts directory.
4:24We can also say we want this service, the Windows Update
4:27service, to be a running state.
4:29And we also want this Windows feature to be installed,
4:33to be present here, and also include all sub features.
4:35So you'll notice something familiar here.
4:37We've been working with commandlets
4:38throughout the course.
4:39You'll notice that these are properties
4:40of those objects that come back from those commandlets.
4:44Get child item.
4:45We get a file object.
4:46Yeah, these are all the properties on that object.
4:49The service object, we've got a name, a startup type.
4:51We've got a state, yeah, just properties
4:53that we can manipulate.
4:54The Windows feature commandlet allows
4:56us to install Windows features.
4:58We can do that here as well.
4:59So that's all these are, these resources-- and there's
5:01a list of them I'll show you when
5:02we get into the Virtual Nugget Lab--
5:03these are configurable resources.
5:05We declare what those resources are, and what they look like.
5:08And when we apply this configuration to a machine,
5:11it's just going to run through and get it in that state,
5:13get all these resources that we define in that specific state.
5:17So step one is to create your configuration.
5:19Step two then is to call the configuration,
5:22pass in any parameters.
5:23And it's going to create an MOF file.
5:25And this MOF file is the compiled version.
5:28It's what DSC understands.
5:30It's what the local configuration
5:31manager understands, more on that shortly.
5:34So step one is author.
5:35Step two is stage.
5:36And that's really just a matter of generating the MOF file,
5:39or taking that MOF file and putting it somewhere.
5:42Putting it somewhere so we can either push it to servers,
5:45or we can have servers pull it.
5:48There's two deployment models here, push and pull.
5:50So we're going to look at the push model
5:52here, in this Nugget.
5:54And then we'll take a deeper look at both push
5:56and pull in another Desired State Nugget
5:58called Desired State Configuration, Making it So.
6:02And by the way, that's the last phase here.
6:04It's called the make-it-so phase or the execution phase,
6:08a little Jean-Luc Picard down there saying, make it so.
6:12But that's really the process.
6:13We offer these configuration files,
6:15which is just us defining the state of the machine.
6:18We then compile them by calling them by name,
6:22and passing in any parameters.
6:23And it will generate an MOF file.
6:25In this case, if we passed in three computers,
6:27we'd get three MOF files, one for each machine.
6:30Then we take those MOF files, and we send them,
6:32and start them up with the local configuration manager, which
6:35by the way is on every machine.
6:37And we have control.
6:38There's a lot of settings we'll get
6:39into in the local configuration manager.
6:41But that's just simply kind of the controller.
6:43It's the one that's going to take these MOF files
6:45and apply them.
6:46And then another thing we can do is we can set up the LCM here
6:50to monitor that machine.
6:52And then auto correct, as you'll see is one of the settings.
6:55And it will actually take a look at the state of that machine.
6:57By default, it's every 30 minutes.
6:59And it will say, hey, if this machine is not in the state
7:04that this MOF file here, our configuration says
7:07it should be in, then it will reapply the configuration
7:09to put it back into that state.
7:11How powerful is That
7:12Just to illustrate how powerful it is here,
7:14let's get a web server up here.
7:15Say we've got a web server.
7:17We've got IS on it.
7:18We've got .net on it.
7:19We've got ASP on it.
7:21We've got websites underneath IS with some virtual directories
7:24down here that contain our website content.
7:26And some joker gets on this machine,
7:28and tries to ruin our day, deletes our website content
7:32directories, deletes those websites, uninstalls IS, .net,
7:35ASP; just totally trashes our machine.
7:38And then the LCM comes along and says, hey, wait a minute.
7:41This isn't in the desired state.
7:44Because it compares that with our configuration, and then
7:46it reapplies it.
7:47It will take that, reapply it, and get it
7:48back to the desired state.
7:51And now the joke is on the joker.
7:54I know that's an extreme example.
7:55But it works all the same.
7:56Because that's how awesome DSC is.
7:58All right.
7:59You're probably ready to see this stuff in action, huh?
8:01Me too.
8:02Let's jump over to the Virtual Nugget Lab and make it so.
8:04All right, let's jump right into the ISE
8:06and look at a configuration.
8:08So I've got a configuration here called Nuggetlab-Config.ps1.
8:11The name of the configuration is NuggetlabConfig.
8:13So that's what we will do we call this.
8:15It's just like a function.
8:16We're going to put this configuration in memory.
8:19We're going to call this just like we want a function.
8:21And that's going to generate those MOF files.
8:23You'll notice we're also accepting parameters here.
8:25So we can pass in a bunch of computer names.
8:26And it'll generate an MOF file for each computer.
8:28And if we don't pass in one, it's
8:29going to just default to the local host.
8:31And that's what will get fed in here to the node block.
8:34So we've made this dynamic.
8:36You could also hard code specific computer names
8:38in here.
8:39And it'll generate the MOF file then for that machine.
8:42So this is purely, all this stuff
8:44here is just for creating the MOF files.
8:47When we pass parameters in here, we're
8:49just simply defining how we want to create that MOF file,
8:52and for what machine we want to create it for.
8:54Now inside of the node block is where
8:56we define our resources, and the state of those resources.
8:59And I'll show you can get a list of all the resources out there,
9:02and even how to get all the resources.
9:04But we've got the File resource, the Service resource,
9:07and the WindowsFeature resource that we're utilizing inside
9:09of here.
9:10So you declare the resource, and then you give it a name.
9:13And this is the name you'll reference if you set up
9:15resources with dependencies.
9:17So a lot of these have a DependsOn property
9:19that you can use.
9:20See that?
9:20DependsOn, and that means that resource must
9:22exist before this resource.
9:24So you can set up dependencies, and set up
9:26the order in which they need to get installed or configured.
9:29All right.
9:30So here's our File resources.
9:31And what this is going to do is just
9:33pull down the installs directory onto the local machine,
9:36and ensure that it stays there.
9:37We also have-- we're going to show you that the Windows
9:39Update service is running.
9:41And then we're going to ensure that this feature, the Windows
9:44Server Backup feature, is installed.
9:46So a very simple configuration here,
9:49but you kind of get the idea of how this stuff works.
9:51Configuration, accept parameters, specify a node,
9:55specify your resources, and their properties.
9:57And when you're all done, then you just
9:59call it just like you would a function,
10:00passing in any parameters.
10:01And that's going to generate the MOF file.
10:04So let's do that.
10:04Let's go ahead and run this.
10:06We didn't treat it like a function, and run this first.
10:08So let's get that configuration created in memory.
10:12There we go.
10:12And now we can call it.
10:16And now when it's done, it'll show us that it made it.
10:19And we passed two computers in there, DCNUGGET and FSNUGGET.
10:21So it created two MOF files for that.
10:24And we can actually see them.
10:25Let's just do a start here in our directory.
10:27And it's going to create a directory.
10:29See that?
10:30So here it is, NuggetlabConfig, if we go inside of here,
10:32there it is, DCNUGGET.mof, FSNUGGET.mof.
10:35And you can actually look inside of these.
10:37Let me show you here.
10:39And see that it's going to generate a little comment here
10:42for who generated it, when and what,
10:44and what machine it was on, and what our target node is.
10:46And then here it is.
10:47Here's the actual version that the local configuration manager
10:51understands is what's it's going to use then
10:53to apply this configuration.
10:55We're going to deploy this configuration.
10:56We're going to push it over to these machines
10:59to the local configuration manager.
11:00And it's going to apply it.
11:02All right.
11:02So that's how to create a very simple configuration,
11:05and then generate your MOF files.
11:07Let me show you a few other things here.
11:08First let me show you all the commandlets here for DSC.
11:12So Get-Command with the Noun dsc wildcard, and here they are.
11:16So Get-DscResource will give us a list of resources.
11:19And we can also see all the configurable properties
11:21for that resource that we can use in our configurations.
11:23We also have a bunch of DSC configuration commandlets.
11:27So Get will show us the current configuration on a node.
11:30We've got Stop, which will stop it;
11:32Test, which will test for configuration drift
11:34to tell us if the machine is currently not in the desired
11:36state; Start, which we'll be using here shortly to send
11:39a configuration to push it over to a machine; and Update.
11:42And we'll also talk about Get and Set
11:43DscLocalConfigurationManager.
11:45There's some other ones in here as well, like New-DsccheckSum.
11:48We'll be using that when we get into pull deployments.
11:51All right.
11:52So that's that.
11:52Let's take a look at all the resources on the system here.
11:55So if we just do a Get-DscResource, here they are.
11:58So check it out.
11:59We've got things like file.
12:00Hey, and there's the one we just created, NuggetlabConfig,
12:03Archive, Environment, Group, Log, Package, Registry,
12:05Script for a catch-all here.
12:06If none of these resources line up,
12:08you can just set up and run a script as a resource.
12:11Service, User, windowsFeature, windowsProcess,
12:12and you can get a lot more of these.
12:15In fact, if you look in the PowerShell Gallery,
12:17it's all resources.
12:19They start with an x, which stands for experimental.
12:21And Microsoft releases them in waves.
12:24And so there's a ton of them out there.
12:26You can go, go out there to the PowerShell Gallery.
12:29I'll give the URL for that.
12:30And take a look at all the different resources.
12:32And you'll treat them like modules.
12:33You'll add them into your modules directory, import them,
12:36and then you can start using them here in PowerShell.
12:39And you could also, there's actually
12:41a dynamic one called import-dsc, DscResource right here,
12:47so you also need to use that to import the module
12:49to get all the resources inside of your configuration
12:52or to get specific resources in the configuration.
12:55But back to our commands here, let's say
12:57that we wanted to take a deeper look at that service resource.
13:00We can pipe this to select and expand the properties.
13:02Because if we look here, we've got this properties over here.
13:05Those are all the configurable properties.
13:06Well, let's expand that out so we can see it for service.
13:09And you'll see here's all the ones that we can set,
13:11State, StartupType, DependsOn, Credential, BuiltInAccount,
13:14and the name of the service.
13:15We can do the same thing here for the file resource
13:17that we configured there in our configuration.
13:19And here's a lot of things.
13:21So we use SourcePath and DestinationPath.
13:24We also Recurce, set up the recurse flag on it,
13:27so pretty cool.
13:27And it also shows you the values you
13:29can provide for them as well.
13:30So you can get a lot of good information
13:31here for the resources.
13:32All right.
13:33Back to where we were.
13:34Let's say that we wanted to deploy this to our machines.
13:36First, let's go take a peek at those machines just
13:38to show you.
13:39Here's DCNUGGET, just to show you
13:41we have no magic trickery going on.
13:43If we go-- if go into the C drive,
13:45there should be no installation folder.
13:46There's no installs folder here.
13:48Also let's just fire up PowerShell,
13:49and let's do a get-windows feature, get-windows feature
13:52for windows-server-backup.
13:55See if this feature is installed.
13:56It is not.
13:57See that?
13:57That's not installed.
13:59And then the last thing here, let's do a get-service.
14:01And we want to look for the display
14:03name here of windows update.
14:07And that is currently stopped.
14:10So our goal is to ensure that this is always installed,
14:13ensure that this is always running,
14:14and ensure that our installs directory is always
14:16on here with those files that live on the file server.
14:19And the domain controller will do the same thing then
14:22to our file server, and same thing.
14:24There's no install directory here.
14:25The Windows Update service has stopped.
14:27And what Windows Server Backup is not currently installed.
14:29So let's go back to our client machine here.
14:31And all we do is a Start-DSCConfiguration.
14:34We're going to pass in the path here to our NuggetlabConfig.
14:39Let's do it.
14:40And there it is.
14:41See it spins up a job.
14:42So now we can get the job here.
14:43We can see it's probably to be running for a little bit here.
14:46Because it's going to install those services
14:47on those machines, and also copy down that installs directory
14:50and start the Windows service.
14:52There it is.
14:52Completed.
14:53That didn't take too long.
14:54But now we can verify this a couple of ways.
14:56But let's just do it the easy way here.
14:57Let's go over to DCNUGGET.
14:59Let's open up the file system here, and go into the C drive.
15:01And look at that.
15:02There's our installs directory, looks good.
15:04What about let's fire up PowerShell here,
15:06and let's just do a get-windowsFeature.
15:08And let's look for that windows-server-backup.
15:11There it is.
15:12It's installed.
15:13And finally let's do a get-service
15:14here against our display name of windows update.
15:20And that is currently in a running state.
15:22So awesome.
15:24That worked.
15:24And the same thing happened over on our file server.
15:26There's our installs directory.
15:28And we know the other ones are there as well.
15:30So pretty nice, pretty nice, right?
15:33It did everything we told it to do automatically.
15:36Now here's the real cool thing.
15:37The real cool thing is if we were
15:39to delete something, let me take the installs directory off
15:41of FSNUGGET here, let's just get that out of there,
15:43get it totally out of here.
15:45And now let's go back to our CL8 Nugget machine here.
15:48And let's run a test configuration.
15:49Let's run this against FSNUGGET.
15:51This is actually going to test the configuration that's
15:53over there on that server.
15:54And look at that.
15:55It's not in the desired state.
15:57What if we did that against DCNUGGET though?
15:59We didn't make any changes over there.
16:02Look at that, True.
16:03It's in the desired state.
16:04So that's just a great little commandlet
16:06to run to see if we have any configuration drift going on.
16:11We can also see the current configurations over
16:13on those machines by running a Get-DscConfiguration
16:14and passing in the name of the machine
16:16here, for your Sim session.
16:18And it's going to show us what our current configuration looks
16:21like.
16:21And here it is.
16:21They're there.
16:22So here are all three.
16:23We're ensuring that these are present.
16:25We're ensuring that the Windows Update
16:28service is in a running state.
16:29And we're also ensuring that the Windows Server Backup is also
16:33present.
16:33So really nice.
16:35Now I do want to mention that this is heavily
16:37reliant on remoting, as most things are,
16:38most of these big features are in PowerShell.
16:40So make sure that remoting is enabled.
16:42It's the only way you'll be able to do this.
16:43And then the other thing is that working
16:45with the local Configuration Manager,
16:48again this is the component that does all the work.
16:50So if we do a Get-DscLocalConfigurationManager
16:53here, and let's just get them for both machines.
16:55This is going to show us our settings.
16:57And here's our settings for DCNUGGET.
16:58Here's our settings for FSNUGGET.
17:00Let's go over some of the big ones here.
17:02ConfigurationMode, this can be one of three values.
17:05And this is what determines how the LCM applies
17:07our configuration, and whether or not it
17:09checks for configuration drift.
17:10So the three values are Apply, which just simply means
17:13it will apply any new configurations that we
17:14push over.
17:15Or if it detects any new configurations on a pull
17:18server, it'll pull them down and apply them.
17:20ApplyAndMonitor, which is the default,
17:22means it will do everything we just talked about with Apply,
17:25as well as monitor for configuration drift.
17:26And if it detects any configuration drift,
17:28it will output it to a log file.
17:31The last setting is ApplyandAutoCorrect,
17:33which is the ultimate in ensuring that your machines
17:36stay in the desired state.
17:37Because not only will it do everything with Apply,
17:39but if it detects configuration drift,
17:41it'll reapply our configuration to get it
17:43back to that desired state.
17:44We also have our configuration mode frequency in minutes,
17:46how often it checks for configuration drift.
17:48The default and minimum value here is 15 minutes.
17:51Let's see.
17:52What else do we have in here?
17:53We've got RebootIfNeeded.
17:54So that Windows feature that we just installed,
17:58the Windows Server Backup, that actually
17:59required a reboot afterwards.
18:01But we have the setting at false.
18:02So it didn't reboot.
18:03If we have to true, it would have rebooted the machine
18:05after that feature was installed.
18:09And we also have ActionAfterReboot.
18:10There's ContinueConfiguration, and there's also
18:12StopConfiguration.
18:13Let's see another one here, RefreshMode,
18:15you can see the default here, which is PULL.
18:17And we also have RefreshFrequencyMinutes.
18:19This is only relevant if you are in a refresh mode of PULL.
18:23That's how often it will check the pull
18:25server for new configurations.
18:27Now how we change the settings of an LCM
18:29is very similar to creating a configuration here.
18:31So let me open up another script I have here, called LCM-Config.
18:34And it's very, very similar.
18:36So we set up a configuration block, give it a name.
18:37We can optionally set parameters.
18:39So we can create, again, these are
18:41going to be meta.mof files that we create that contain
18:44all the settings for LCM.
18:45So we can create them for multiple machines,
18:47set up a node block, and here's the important part,
18:49LocalConfigurationManager, put in the name of the property,
18:52as well as the setting.
18:53And then we generate this.
18:54Let's go ahead and put this in the memory here.
18:57And now let's run LCMConfig, and let's generate this
18:59for both DCNUGGET and FSNUGGET.
19:02That generated, as you can see here, meta.mof files.
19:05And now instead of calling Start-DscConfiguration,
19:08we call Set DscLocalConfigurationManager,
19:12pass into the path to that directory,
19:13which contains both of those meta.mof
19:15files that we just generated.
19:17And that's it.
19:17Now it applied them.
19:18Now we can verify that it applied them,
19:20again by running a Get DscLocalConfigurationManager.
19:23And we should see that we are now
19:24in ApplyandAutoCorrect mode.
19:26So what that means is within 15 minutes
19:30on our FSNUGGET machine, the LCM is going
19:32to detect configuration drift.
19:34And then it's going to re-run that configuration, which
19:37is going to re-download that installs directory
19:40onto this machine.
19:41And we'll be back at the desired state
19:43that we specified there in that configuration file.
19:45So what do think of Desired State Configuration?
19:48Pretty incredible stuff, right?
19:49I mean extremely powerful for how simple it is to get up
19:52and running.
19:52And again, check the internet.
19:54Look at the PowerShell Gallery for resources, or just
19:57Google search for desired state configuration resources.
20:00There's a ton of them out there for almost anything
20:03that you can think of.
20:04And we're only going to get more and it's only
20:06a better over time.
20:07All right.
20:07Let me give you your challenges for this Nugget.
20:09Challenge number one, create a basic configuration
20:11to ensure the BITS service-- that's
20:12the Background Intelligent Transfer Service-- is running.
20:15Compile an MOF, and push it to the machine.
20:17We covered all that in this Nugget, very simple.
20:19Create that configuration function.
20:21Call it with the target machine that will generate the MOF
20:23file for that machine.
20:24And then use Start-DscConfiguration to apply
20:27it.
20:28Step number two, stop the BITS service,
20:30and check for configuration drift on the machine
20:32you applied the configuration to from above.
20:35So remember how to check for configuration drift?
20:37Right, it was the Test-DscConfiguration command
20:39line.
20:40And challenge number thee, create
20:41an LCM configuration for the target machine
20:43you used in the previous steps.
20:45Change the configuration mode property
20:46to ApplyandAutoCorrect.
20:47Set the configuration on the target machine
20:49and stop the BITS service, checking after 15 minutes
20:52to ensure the configuration was reapplied.
20:54So this is just so you can see the whole process in action.
20:57You can watch the LCM fix the configuration drift
21:00that you caused by stopping the BITS service.
21:03All right, so again, you can find the solution
21:06underneath these regions.
21:07You can find all these files in the Virtual Nugget Lab files
21:09downloadable on the right-hand side of the course page.
21:12And as always, good luck.
21:13In this CBT Nugget, we saw how to get started with Desired
21:16State Configuration.
21:17We defined what DSC is.
21:19We saw some of the challenges that it solves,
21:21namely configuration drift.
21:22We got familiar with the components.
21:24We saw Microsoft's phased approach
21:26for developing and working with DSC.
21:29And that is the authoring phase to generate their script
21:32and generate the MOF file.
21:33We saw that the staging phase is all about taking that MOF file
21:36and deploying it to a machine.
21:39And then we saw that the make-it-so phase
21:41is how it applies the configuration to the machine.
21:44From there, we jumped into the Virtual Nugget Lab.
21:46And we got a nice little demo here to see the whole process,
21:48from creating our script, to generating the MOF file,
21:51to applying it through the LCM, the Local Configuration
21:54Manager.
21:54I hope this has been informative for you.
21:56And I'd like to thank you for viewing.
Desired State Configuration - Making it So!
0:00Desired State Configuration-- making it so.
0:02In this Nugget, we're going to look
0:04a little closer at the deployment models here in DSC.
0:06We'll compare and contrast the push
0:08and pull deployment models, and then
0:10we will get into the Virtual Nugget Lab,
0:11and I'll show you how we can set up a pull server to orchestrate
0:14all of our deployments from one centralized location.
0:17Let's begin.
0:18So we've got two deployment models
0:20in Desired State Configuration-- the push deployment model,
0:22and the pull deployment model.
0:23We took a good look at the push deployment model
0:25in our Getting Started with DSC Nugget, where we
0:28saw it's really simple, right?
0:29It's a very manual process.
0:31We generate the MOF from our configuration function,
0:34and then we manually push it over there with a Start DSC
0:37Configuration.
0:38That sends it over, and then applies it, and then
0:41potentially monitors it based on our configuration mode.
0:43So total manual process.
0:45No centralized server orchestrating deployments.
0:47We simply author our configuration script,
0:51and then run it to generate and compile that MOF file,
0:54and then we just push it over there,
0:56and it gets applied by the LC on the Local Configuration
0:59Manager.
1:00So this is good for small setups, right?
1:03If you don't have a lot of servers
1:04and a lot of configurations, then this
1:06will be great because you don't have the scaling problem.
1:09On the other hand, if you do have a lot of configurations,
1:11you have a lot of servers that need to be in a specific state,
1:13then this could get a little hairy to manage,
1:15and that's why we have a pull deployment model.
1:18So in this model we have a centralized server
1:20that hosts our MOF files.
1:22The LCMs on the target nodes will then
1:25pull that server based on a refresh interval
1:27and grab any new configurations if it's changed.
1:30So it's a little more difficult to setup
1:32because we need to configure that pull server,
1:34but it's a lot easier to scale if you
1:36have many configurations.
1:37So there's a couple of ways that we can set up our pull server
1:39here.
1:40We can use SMB, HTTP, or HTTPS, and how
1:44this works is SMB and HTTP are going
1:46to be good for private networks.
1:48SMB for small, simple private networks.
1:50You know, once you start involving
1:52subnets and firewalls, then you can get
1:53into some problems with SMB.
1:55HTTP is going to be good for those complex,
1:58private networks, and HTTPS is what
2:00you're going to want to use when you have
2:01to do any sort of public communication
2:03because all of our configurations
2:05are getting transmitted over in clear text.
2:07So we want to reduce the chances of those potentially getting
2:11messed with because that could cause a whole host of problems,
2:13right?
2:14So I'm going to show you in our demo
2:15here how to setup an HTTP pull server.
2:17Now, just a couple of differences
2:19I want to point out in the process
2:20from authoring to staging.
2:22In the push deployment model, when we run our configuration
2:25it's going to generate that MOF and name it after the node,
2:29right?
2:30So if we were to generate a configuration for APPNUGGET,
2:32it would be APPNUGGET.mof.
2:34Over here in the pull deployment model,
2:36that's still going to happen, but we
2:37need to change the name of that to a random unique identifier,
2:41and I'll show you how we can create
2:43a GUID, global unique identifier, here, and rename
2:45that file before we push it over to the staging,
2:49and then when we set up our LCMs,
2:50we're actually going to use that GUID,
2:52and that's what's going to tie the LCM to that configuration
2:56on the pull server, and yes, we can use that one
2:58GUID across many servers.
3:00If we have a farm of servers that all need the same state,
3:02then we can tie them all to that one configuration file.
3:05Another thing we need to do is generate a checksum
3:08on our MOF file, which is what clients
3:10are going to use to validate the integrity
3:12of that configuration.
3:14So, just a couple of extra steps here before we
3:17stage that MOF file to our pull server,
3:19but it's really not that bad.
3:20All right.
3:20Let's jump into the Virtual Nugget Lab,
3:22and see how to set up a pull server.
3:23Welcome back to the Virtual Nugget Lab.
3:25So there's a few ways to set up a pull server.
3:27The current recommended way of doing this
3:29is using DSC to configure DSC.
3:32In other words, we're going to download the resource
3:34kit, which will give us access to the DSC resource, the PS
3:37Desired State Configuration resource,
3:39that we can then use to set up a pull server.
3:41Currently, this is the best way to do it.
3:43Now, keep in mind, all this DSC stuff is still very young.
3:46There's a lot of areas that still need to get fleshed out,
3:49and this is one of them, but you'll
3:50see as time goes on it's just going to get better and better.
3:53So, let me take you over to the script center here,
3:55and here is the DSC resource kit.
3:56It contains all the waves that Microsoft has released,
3:59and if we scroll down here, you can
4:00get a look at all the different resources that are in here.
4:04So if we head down here, there's something for Azure,
4:06Active Directory pack up there, DHCP server disk, Exchange,
4:10there's a big one for Exchange in here, and let's see.
4:12There's some Firefox.
4:13There's one for Chrome.
4:14There's one for Hyper-V.
4:15We're going to work with this one here in this Nugget.
4:17XInternetExplorerHomePage, that'll be a fun one,
4:19and then what we're really looking for
4:21is this one right here, PSDesiredStateConfiguration.
4:25Contains improvements to built-in DSC resources, as well
4:27as resource for configuring a DSC
4:30pull server, exactly what we're going to be doing.
4:32So I already downloaded this, and popped it
4:34into our modules directory here.
4:37C: Program Files or system drive Program Files,
4:39Windows PowerShell, Modules, exactly
4:41like we would install any other module.
4:43Here is the zip.
4:44So I just extracted all of those resources into here.
4:47Now we could do something like this.
4:49Watch this.
4:49Let's just do a get-DSCResource here,
4:53and now, instead of just those core resources,
4:56we should have all of these new resources that are inside
4:58of the resource kit, and look at that.
5:00We've got tons of them to work with now.
5:02So we could create configurations
5:03around virtually anything.
5:05All right.
5:06So now that we've got that ready to go, let's take a look at
5:09set up a pull server.
5:10Just like creating a standard DSC configuration.
5:12We started off with configuration.
5:13Give it a name.
5:14This is what we'll call when we generate the MOF file.
5:17Then we're going to import the DSC resource.
5:19We're actually going to import all the resources inside
5:21of the PSDesiredStateConfiguration
5:24module, then we're just going to target our APPNUGGET node.
5:26We already have IIS on that node,
5:28and that's going to be required here,
5:30because we're going to end up creating two web services.
5:32We're going to add a Windows feature
5:34and create two web services, a pull server web service as well
5:37as a compliance server web service,
5:38and just to show you APPNUGGET here,
5:40you can see we do not have the DSC service currently
5:43installed.
5:44Here it is.
5:44This is what's going to do all the heavy lifting here for DSC
5:47and for our pull server.
5:48We do have IIS installed, and I also
5:50wanted to mention here, we needed to copy the DSC resource
5:54kit over here onto this machine as well,
5:56since this is where that configuration is going
5:58to be running, it's going to need access to those resources
6:01that we're using inside of this configuration for setting up
6:04the pull server.
6:05So that's why this also needs to be on the machine that is
6:07going to be your pull server.
6:09We just happen to be doing all this on our client machine.
6:11All right, so the first thing we going to do, then,
6:13is add that Windows feature, the DSC service windows feature.
6:16Then we're going create our pull server,
6:18and now this pull server is just a web service,
6:20as you can see right here, that's
6:21going to run inside of IIS.
6:23So we're going to ensure that this is true.
6:24Here's going to be the endpoint name.
6:26Here's going to be the port that it listens on,
6:28and then it's going to create this as the physical path
6:30there, instead of IIS' virtual directory, there, wwroot,
6:34and this is going to be unencrypted HTTP traffic.
6:37So it's just standard HTTP web service here,
6:39and then we also have our module path.
6:41More on this when we get into creating a configuration
6:45because if we have any modules, which we will
6:48because we're using a custom resource.
6:50You don't have to worry about this if you're
6:51using all the built-in resources,
6:53but if we're using a custom resource,
6:55we need to ensure that the LCM can download it
6:58on the target machine so it can use it locally.
7:01So we're going to need to zip up the resource that we use,
7:05generate a checksum for it, and put that into this directory.
7:08We also have our configuration path.
7:10This is where we're going to, again, create our MOF files.
7:12Once we rename them with a GUID, unique identifier,
7:15we're going to put them into here,
7:16and then we're also going to generate a checksum for them.
7:18So these are the two directories you'll
7:20be working in to put your resources,
7:22any modules that you're configurations will need,
7:25as well as the MOF files themselves.
7:27All right.
7:27So we're going to ensure that the state is started,
7:30and this is going to depend on the service.
7:33So we're setting up order here.
7:34We're saying that this must run before our DSC web service
7:39resource runs, all right?
7:40And then the next one here, the last one,
7:42is our compliance server.
7:44Now, there isn't much we can do with this right
7:46now because this is one of those areas that really
7:48needs to get fleshed out, but think of this as just
7:49kind of a database that all the targets are going to report to.
7:52Eventually, I can imagine us getting a nice web
7:54interface that will allow us to monitor configuration drift
7:58and manage our configurations in real-time on top of this data,
8:01but we can still get it up.
8:02So we can start tracking that data now.
8:04You can get at some of the data in here,
8:06but it's not extremely useful, and it's
8:07kind of difficult to get at.
8:08So I just want to point that out.
8:10So, we're still going to set it up, ensure present.
8:13Here's the name.
8:14This is going to listen on port 9080.
8:16Here is the directory here for the compliance server,
8:18just standard HTTP server, again.
8:20It's going to be started, and here's the big one--
8:21IsComplianceServer.
8:22Set that to true, that'll set this up as a compliance server,
8:25and we have two dependencies here, the service
8:27as well as our pull server.
8:29So this will go off last, here, for our configuration,
8:31and that's it.
8:32So let's go ahead and put this into memory here.
8:35All right.
8:36Function is created, and now let's create our pull server.
8:39So this will create APPNUGGET.mof.
8:42There it is, and now let's do it.
8:45So this is going to start it, and also, by the way,
8:47the weight parameter here will pipe out everything
8:50to the screen.
8:50So it won't fire it up as a job.
8:52Without the weight parameter, as we
8:53saw in our Getting started with DSC Nugget, when
8:55we push those configurations over, we did it without weight.
8:58So it spun it up as a job.
8:59So this will make it easier.
9:00You won't have to get the status of the job,
9:02receive the job if anything goes wrong to view the messages.
9:05This will just pipe it all to the screen for us.
9:07So let's do it.
9:09Let's spin it up.
9:10So here it is.
9:11Now, it'll shoot back any errors right off the bat
9:13if you have any resource configuration errors.
9:15So if you didn't copy everything over
9:16to this modules directory over here,
9:18for instance, you'll definitely get some errors back,
9:20but hey that looked like it worked.
9:22It worked, and we can verify that because we can head over
9:24to APPNUGGET here.
9:25Let's go right into wwroot.
9:26Look at that.
9:27We've got our directories here, and let's just verify our DSC
9:31service is installed.
9:32It is.
9:32There it is, and then, oh yeah.
9:34Let me fire up Internet Information Services Manager
9:36here as well just to make sure that those sites were created
9:40and they're up and running.
9:41There they are.
9:42Excellent.
9:42Both running.
9:43Very good, and one more thing.
9:46That's going to create a DscService directory.
9:49Here it is.
9:50So this is our pull server.
9:52This is where we're going to plant those MOF files.
9:54This is where we're going to need
9:56to zip up and plant any modules or resources that our clients
10:00will need to download to run their configurations,
10:02all right?
10:03So, good.
10:04Everything looks like it's set-up perfect from our pull
10:06server side.
10:07Now, it's time to test it all out, right?
10:10And the first thing we're going to do,
10:12because eventually we're going to need
10:13to configure all the LCMs on those machines,
10:16set their configuration to pull, and then I'll
10:19show you that configuration last,
10:21but first let's create something here.
10:23Let's create a simple configuration
10:25that we're going to deploy and stage onto that pull server.
10:29So we've got a configuration named SetIEHomePage.
10:31We're going to acceptt some parameters here,
10:33the first one being mandatory, the start page
10:35URL, the second one being secondary start page's URL.
10:37So how this works is, when we fire up Internet Explorer,
10:39it's going to fire up two tabs.
10:41One with the start page and then another one
10:42with the secondary start page.
10:44So that's all we're doing here, and we're
10:46going to use that custom resource inside of the DSC
10:48resource kit xInternetExplorerHomePage
10:51to do so.
10:52So we'll import that module.
10:53Doesn't matter what name we have here
10:55because we're going to overwrite it with the GUID anyway,
10:57but here's the resource that we're utilizing here.
11:00We're calling it IEHomePage, and then
11:01we're just tying these to the parameters that
11:03are getting passed in, and here is
11:05how we will generate the MOF file
11:07that we're going to need to deploy to our pull server.
11:10So we'll just call this.
11:11We'll set up the start page as CBTNuggets.com
11:13and the secondary URL as Bing.com.
11:15So let's go ahead and create this.
11:18Put that in memory, excellent, and now
11:20let's create our MOF file.
11:22There it is, localhost.mof.
11:23Again, the name does not matter because it's going to our pull
11:26server, and here's how we're--
11:27the next step is what we're going
11:28to need to do to the name.
11:29We're going to change it to a globally unique identifier.
11:33So we're going use the static class here,
11:35and we're going to tap right into the .NET framework to hit
11:38the GUID class and call the static method newGUID() on that
11:41type, all right?
11:42So we'll do that.
11:43That's going to generate it and spit it back into the screen
11:45here.
11:46Here, just, I'm going to copy this
11:46because we're going to need this here
11:48when we get into configuring the LCM, all right?
11:51Cool.
11:52So we got that down.
11:53Now the next we're going to do is copy
11:54that MOF file up to our pull server with this GUID
11:57that we just generated that's inside
11:59of this variable as the name.
12:01So we're going to set up our source here as that MOF
12:03file we just created.
12:04Our destination, we're going to go right through
12:06the administrative share over there on our APPNUGGET machine,
12:08and plant this right into that configuration directory with
12:11the GUID that we just generated .mof.
12:15So let's run this.
12:15That's going to copy it up, copy it over there,
12:18and rename it to the GUID that we just created.
12:20All right.
12:21Excellent, and now we need to generate the checksum for that
12:25as well.
12:26Perfect, and you know what?
12:28Let's just verify that real quick.
12:29Let's go over to APPNUGGET, PowerShell, DscService,
12:34Configuration, and look at that.
12:36There is our mof file.
12:37It made it.
12:38Awesome.
12:38So, and a checksum.
12:40So, perfect.
12:40Now, at this point, we could go and change the settings
12:43to pull and see it all in action, but it wouldn't work.
12:46It would fail because we're using a custom resource.
12:48If you were using one of the built-in resources,
12:50you'd be done at this point.
12:51you just configure the LCM for pull, and it'd be good to go,
12:54but because we are using a custom resource
12:56we need to do an extra step, and that is provide this resource
12:59to the pull server so clients can download it and use them
13:04on their local machines.
13:06So that's what we're going to do next.
13:07We're going to zip up this xInternetExplorerHomePage
13:11module, which is right here by the way.
13:13Let me go into PowerShell, modules, and xIE.
13:19There you are right here.
13:20So we need to zip this up.
13:21See this, here it is, the resource with the psd1,
13:24and here is the actual resource involved.
13:27There is the schema.
13:28There is the module.
13:29So this is what we need to send over.
13:32So we need to zip this up, and name it with the naming
13:35convention that it expects, which
13:36is the name of the resource underscore version, all right?
13:39So that's what we're going to do.
13:40So this is a reference to the resource, the actual directory
13:43where they all live that we were just looking at.
13:45Here is the new name, the zip file name underscore
13:481.0.0.0.zip, and here's the destination.
13:51We're going to put it inside of the modules directory
13:53over there with this name.
13:55Now, in PowerShell version 5, it's very easy to zip up files.
13:58There's a brand new command called,
13:59I believe it's create_archive, or create-archive.
14:03Not so much in version 4.
14:05We need to do the old school method of tapping right
14:08into the .NET type.
14:09So we're going to add this type, and then we're
14:11going to call the static method on that type
14:13to zip up our file.
14:15All right, and then we're going to copy it right up there,
14:16and then we'll generate the checksum for it as well.
14:19So let's do all that in one shot.
14:20Ready?
14:21All right, that looks like it succeeded.
14:22Let's verify that.
14:23Let's head over to APPNUGGET here.
14:24Let's head to DscService, right into modules, end, hey.
14:28Awesome.
14:28There is our resource all zipped up.
14:30There's the checksum, and now we're
14:31ready for the final step, which is configuring
14:35the LCMs on our machines that we want to hit that pull server
14:38and pull that configuration down from.
14:40So, simple enough, right?
14:41We've done this in our Getting Started DSC Nugget.
14:43We're going to set up an LCM pull config.
14:45We're going to have a couple of parameters here.
14:47The first one is for the computer name
14:49so we can pass in multiple machines
14:50and generate a meta.mof file containing all those settings
14:53for each machine, and here's the important part, the GUID.
14:56So we're going to set up in the configuration ID--
14:58this is one of the settings in the LCM--
15:00this is how we tie the local LCM on the machine
15:03to hit that package up on the pull server.
15:06That's how it all gets tied together.
15:08And normally I'd have this all in one script
15:10so we could just flow that GUID variable all the way through,
15:13but I broke it out.
15:14So you can kind of see the steps here,
15:15and that's why I copy the GUID to the clipboard.
15:17So that's one of the big settings.
15:18The other one here is the refresh one.
15:20We need to set this to pull.
15:22Remember, push is the default. So we set it to pull,
15:24and then we need to point this LCM at our pull server.
15:28So we're using HTTP.
15:29So we're going to specify WebDownloadManager
15:31as the DownloadMangerName here, and we're just
15:32going to point it to the server URL, which
15:34is going to be the web service, APPNUGGET port 8080.
15:37Here is the name of that service.
15:38This is also where you'd set-up SMB.
15:40So if you wanted to set up an SMB fileshare as a pull server,
15:45then you would set that up and specify the UNC path
15:47to that sharing, and you'd be good to go.
15:49All right, so let's go ahead and create this configuration.
15:53Awesome, and now let's go ahead and create those meta.mof
15:57files, our settings files for both of these machines,
16:00and there they are.
16:02Perfect.
16:02So, now the last step is to set it, right?
16:05And what's this going to do?
16:07Boom, it's going to send those configurations over,
16:10and now we can verify that with a get local configuration
16:13manager, and look at that.
16:14It worked.
16:15So our DC Nugget's in pull mode.
16:17Our FS Nugget is in pull mode, and our refresh frequency
16:19minutes is 30.
16:20So every 30 minutes, it's going to check that pull
16:22server for a new configuration.
16:26If that configuration's changed, if checksum has changed,
16:28it's going to pull that down and apply it.
16:30Also notice that we're in ApplyAndAutoCorrect.
16:32So if somebody were to change our home pages,
16:34within 15 minutes it would get changed right back.
16:37All right.
16:37Let's head over to our FSNUGGET and see if it all worked.
16:41Now one thing you can do to kind of check
16:43to make sure that the resource phase worked,
16:45because when you're doing custom resources
16:47there's a lot of little things that
16:48can happen along the way there.
16:50So run a Get-DscResource.
16:52If we see that resource in here--
16:54hey, look at that--
16:54that's generally a good sign that it made it over.
16:58All right, now let's really verify here.
16:59Let's fire up Internet Explorer.
17:01What do we get?
17:01Hey, hey.
17:02Look at that.
17:03It worked.
17:03Well, we've never used Internet Explorer over here apparently.
17:06So here we go.
17:08There it is.
17:08Yeah, yeah, yeah.
17:09We'll add them all in here.
17:10Oh, boy.
17:11I should just turn that off, huh?
17:12That's annoying, but there we go.
17:14So there's our main page, CBTNuggets.com, and here
17:17is our secondary page, Bing.com.
17:19Very, very cool, and if we were to change these settings, which
17:23is difficult to do for the secondary page.
17:25It's a registry setting.
17:26So no user's probably going to go turn that off,
17:28but anybody go in the settings and turn the home page off,
17:31and within 15 minutes it will get auto-corrected and put it
17:33right back to it.
17:34All right.
17:35Very good.
17:36Now, troubleshooting.
17:37If you try this stuff on your own,
17:39because there's a lot of moving parts here,
17:40all this stuff is still, again, relatively new,
17:43it's inevitable that you're going to come across issues.
17:46So the Event Viewer is your friend.
17:49There is an event log here for DSC
17:51underneath applications and service
17:52logs, Microsoft Windows.
17:55All of our machines, clients, and the pull server
17:57will have a Desired State Configuration log here.
18:00You've got an admin log, and you've got an operational log.
18:02So check these out if you have problems,
18:05and that will help you hunt down where
18:07the problems are coming from.
18:09All right.
18:09We're going to skip the challenges for this Nugget
18:11because that was a pretty big demo,
18:12and if you really want to try this out, do it on your own.
18:15Do it in our Virtual Nugget Lab if you have access to it.
18:17If not, try it on your own equipment.
18:18It's a lot of fun, and I would advise, for your first time,
18:22just use one of the built-in resources
18:24to get it all working, and then you
18:25can start introducing custom resources into it
18:27and add those extra steps in.
18:28In this CBT Nugget, we saw how to make it
18:30so with Desired State Configuration.
18:32We started with a quick overview of both deployment models,
18:35push and pull, and then we jumped into the virtual Nugget
18:37lab, and took a big demo on how to setup an HTTP pull server,
18:41and we went through the whole process
18:42from author to stage to make it so.
18:45I hope this has been informative for you,
18:47and I'd like to thank you for viewing.
Tips, Tools, and Resources
0:00Tips, Tools and Resources.
0:02We're going to finish this course off
0:03with this real quick Nugget here to show you
0:05how to use profile scripts, talk about some
0:07of the popular tools that are out there that will assist you
0:10in building PowerShell scripts and just making it generally
0:13easier to work with PowerShell, and some excellent resources so
0:16you can continue your journey to becoming a PowerShell master.
0:21Let's do it.
0:21We're going to start this one in the Virtual Nugget Lab
0:23because I want to get you up to speed on profile scripts first.
0:26So profile scripts, what are they all about?
0:28Well, if you find yourself doing a lot of the same things
0:30every time you launch a session, whether that's
0:32in the ISE or the Shell, then it may
0:34be a good candidate put in your profile script,
0:36because it'll automatically load all these things up
0:38for you every time you launch a session.
0:41So things like customizing the Shell, things like functions,
0:44if you find yourself running a function all the time,
0:46put it in your profile script.
0:48It'll automatically be available.
0:49You won't have to manually load up that function.
0:51Setting up PS drives, importing modules, all kinds of things
0:56are good candidates for your profile script.
0:58But what I want to do is show you the About topic
1:00here, About_profile.
1:00This is great because there are actually multiple profile
1:04scripts that you can create at different scopes.
1:06So Current User, Current Host.
1:08Right, host being the ISE or the Shell,
1:11the actual PowerShell.exe down here.
1:13The Current User All Hosts, All Users Current Hosts,
1:17All Users All Hosts.
1:19So if you run the profile variable by itself,
1:23it's going to return the path that you'll
1:24need to create your profile script in for the Current User,
1:28Current Host.
1:29Our host right now is the ISE.
1:30That's why it sent back this one.
1:31If we did it for something specific
1:33like All Users, All Hosts, this one
1:35is going to show us that, oh, yeah, we'll
1:37need to create this inside of the PS Home Directory.
1:40Now it doesn't create it for you automatically
1:41because if we were to test this path,
1:42this is going to return false.
1:44See that.
1:44Because it doesn't exist.
1:45It's just showing us where that file should be,
1:49and what it should be, if we were
1:50to create that profile script.
1:52So that's why we're going to do a new item,
1:53specify the path as the profile variable, automatic variable,
1:57.AllUsersAllHosts.
1:58Type File and Force in, in case it already
2:00exists, which we know it doesn't, and now it'll
2:02create it.
2:03And now it's created.
2:04And if we a test path against it again, it will return true.
2:07Awesome.
2:08Let's go and start that up and we're
2:09going to throw some interesting commands in here.
2:12One common thing you'll do is customize your environments.
2:15We'll set up the window size, the buffer size,
2:17here's where you can do your foreground and background
2:18colors and all that.
2:19And we'll change the window title to PowerShell Ninja.
2:21And then we'll set our location as the C Drive.
2:23We'll clear the host, because we need to see that
2:25every time we launch the Shell.
2:26And then this is super fun.
2:27I advise you to put this in your profile script
2:29because it's great.
2:30So this will get a Random cmdlet, right.
2:32Get-Random cmdlet is awesome.
2:34And this will get a random About Topic,
2:36and then we'll put a nice message every time
2:38we launch the Shell.
2:38Welcome to another fabulous session.
2:40Here's your random cmdlet.
2:41Here's your random About Topic, and you'd
2:43get Help against those variables to see Help
2:46for either of those topics.
2:49These are variables that will be available
2:50throughout the entire session.
2:52So I'm going to copy this right up to here,
2:54I'm going to piece that into our profile script.
2:57Since we did this for All Hosts, now we
3:00should just be able to launch the console here.
3:03And look at that.
3:04There it is.
3:05Welcome to another fabulous session, oh, look at that.
3:07Our random cmdlet was Update Help.
3:09That's funny.
3:09And then our random About Topic was about operators.
3:11Let's try that again.
3:12Whoosh.
3:13Hey, this time it's Disable-Scheduled Job.
3:15And again, these are variables that are available to us.
3:18Now we can just do a get-help, pass in cmdlet,
3:21and there we go.
3:22We get the help topic for that cmdlet.
3:24Awesome.
3:25So that's profile scripts.
3:26Pretty simple, pretty straightforward
3:28and extremely useful, especially again
3:30if you find yourselves doing a lot of the same thing
3:33every time you launch the Shell.
3:34Toss it in your profile script.
3:36You'll save yourself some time down the road.
3:37How about some tools here to make your lives easier
3:40when working with PowerShell.
3:41The Script Browser and Script Analyzer are great.
3:43These are add-ons to the ISE, so you can head over
3:46this link to download them.
3:47There's also, by the way, if I just
3:48show you real quick in the ISE.
3:50The add-ons menu, you can open the Add on Tools web site.
3:54There's a ton of add-ons out there,
3:55so you can certainly make your experience
3:58in the ISE that much better.
4:00Lots of them out here on this page,
4:02so again you can access this right through the ISE.
4:04There's all kinds of good ones in here
4:06to, again, help you increase your productivity there inside
4:09of the ISE.
4:09We also have PowerShell tools for Visual Studio.
4:12So if you're a fan of Visual Studio--
4:14I'm a big fan of Visual Studio.
4:16I love it.
4:17There's a great extension out now for Visual Studio 2015,
4:20and you just get access to PowerShell
4:22through Visual Studio.
4:23So it's a lot easier for debugging.
4:24If you build your own cmdlets, it's
4:26obviously going to be the tool of choice for doing so.
4:30It's basically the ISE on steroids
4:33because you can do so much more with it than you
4:35can with the basic ISE.
4:36And then PowerGUI.org, which is right here,
4:39is another really nice tool there.
4:41Dell actually took it over and this
4:43will redirect you to Dell's website
4:44and you can download it.
4:46You can essentially write your scripts
4:47without writing any code at all.
4:49It's totally graphical.
4:50If you don't like writing code, you
4:52like clicking around in the GUI, then you
4:54got access to all of your cmdlets in visual form,
4:57and you can just fill out their parameters and stuff here,
5:00using GUI tools and it'll generate the scripts for you.
5:04And another really popular one is Pester, which
5:07is a unit testing framework.
5:09This is another very popular and very good
5:11tool for unit testing your PowerShell scripts.
5:14Now on the resources front.
5:16I'm going to give you one of my all time favorite PowerShell
5:17for resources.
5:19It's right here.
5:19Print these out because they will save you a ton of time
5:23and they're just a fantastic learning tool and reference
5:27tool.
5:27So I going to actually show you this.
5:28Let me head over to Microsoft's web site.
5:30Here's where you can download it from.
5:31Hit the Download button here.
5:32And it's got reference guides for virtually everything
5:35in here.
5:36I downloaded all of them here.
5:37Let me show you the Language Reference Guide.
5:39This is just so cool.
5:40If you find yourself working with PowerShell every day,
5:43print these out, put them wherever you may be
5:46and you'll thank me later, because they're great.
5:48Useful Commands, here's a list of all the Operators in here.
5:51Scroll down.
5:52Here's Arrays, Comments, Strings, Variables, Object
5:55Properties.
5:56It just gives you every possible way you can think of,
5:58of working with these things, just
6:00an incredible quick reference.
6:02Look at this, all the methods over here.
6:04Here's all the variables and a description of them.
6:07Let's see, Automatic Variables, Preference Variables, the list
6:11goes on and on.
6:11Resources at the bottom.
6:13It's just an incredible, incredible tool.
6:15Here's the ISE reference.
6:16God, I love this one too, right.
6:18Here's all your general shortcuts, Script Pane
6:20shortcuts, Execution, Debugging shortcuts, and so on
6:23and so forth, just good stuff.
6:25What else do we have in here, DSC.
6:26Yeah, we love Desired State Configuration.
6:28Check it out.
6:29Here's a quick overview of DSC, and some quick examples here
6:32of how to work with all of the core resources, which
6:36is fantastic, little bit on some of the cmdlets, and here's
6:38your Local Configuration Manager.
6:40So there you go.
6:42Download this one.
6:42It's a big, big time saver and just a great learning tool
6:46around.
6:46Obviously we've got the Technet Scripting Center.
6:48We've used that quite a bit throughout the course here.
6:50That's a great reference.
6:51And then, PowerShell.org, one of the greatest non-profit sites
6:54out there.
6:54Great community and they keep it up to date pretty good.
6:57So check that one out as well.
6:59That's it for Tips, Tools, and Resources
7:01and that also concludes our course here
7:03on PowerShell 4 Foundations.
7:05I hope you learned a ton.
7:07I hope you had fun.
7:08And I hope you stick around because PowerShell
7:10is going to be in our lives for the foreseeable future.
7:13So stick with it.
7:14Never stop learning and stay tuned
7:15to CBT Nuggets for more PowerShell goodness
7:18down the road.
7:19I hope this has been informative for you
7:20and I'd like to thank you for viewing.
Team training path
Turn this skill into assignable team training
This free skill is a preview of the courses your team can assign, track, and report on with CBT Nuggets.
$708
seat / year