Bb Brass Part for Blame it on the Boogie - Jackson 5Descripción completa
Primear tarea del curso Linux
"The Closers Part 1," the keystone of Ben Gay III's world-famous series of books, cassette programs, newsletters and seminars is the most powerful book on selling ever written. With over 2,0…Full description
"The Closers Part 1," the keystone of Ben Gay III's world-famous series of books, cassette programs, newsletters and seminars is the most powerful book on selling ever written. With over 2,0…Full description
Comparar al menos 5 herramientas de código comercial con sus similares herramientas de Software Libre. Nada complicado, pero no te limites a enumerar, debes comparar ventajas, desventajas, c…Descripción completa
It's a lab report about automobile
EXPERIMENT MANUAL FOR THE BIOCHEMICAL ENGINEERING LABORATORY R. Mark Worden and Andrew B. Kinney Department of Chemical Engineering and Materials Science Michigan State University Revised August 2002Full description
spccFull description
Full description
cvgsFull description
A written lab manual for drilling fluids. Describes the ways of creating drilling mud and obtaining a desired mud weight, as well as the different equipment used for the mud creation.
This manual is very useful for conducting various laboratory tests on soil as per Indian Standards (IS Bureau).Full description
PowerShell for the IT Administrator, Part 1 Student Lab Manual (v1.1)
Conditions and Terms of Use Microsoft Confidential - For Internal Use Only
This training package is proprietary and confidential, and is intended only for uses described in the training materials. Content and software is provided to you under a Non-Disclosure Agreement and cannot be distributed. Copying or disclosing all or any portion of the content and/or software included in such packages is strictly prohibited. The contents of this package are for informational and training purposes only and are provided "as is" without warranty of any kind, whether express or implied, including but not limited to the implied warranties of merchantability, fitness for a particular purpose, and non-infringement. Training package content, including URLs and other Internet Web site references, is subject to change without notice. Because Microsoft must respond to changing market conditions, the content should not be interpreted to be a commitment on the part of Microsoft, and Microsoft cannot guarantee the accuracy of any information presented after the date of publication. Unless otherwise noted, the companies, organizations, products, domain names, e-mail addresses, logos, people, places, and events depicted herein are fictitious, and no association with any real company, organization, product, domain name, e-mail address, logo, person, place, or event is intended or should be inferred.
Microsoft may have patents, patent applications, trademarks, copyrights, or other intellectual property rights covering subject matter in this document. Except as expressly provided in written license agreement from Microsoft, the furnishing of this document does not give you any license to these patents, trademarks, copyrights, or other intellectual property. Complying with all applicable copyright laws is the responsibility of the user. Without limiting the rights under copyright, no part of this document may be reproduced, stored in or introduced into a retrieval system, or transmitted in any form or by any means (electronic, mechanical, photocopying, recording, or otherwise), or for any purpose, without the express written permission of Microsoft Corporation. For more information, see Use of Microsoft Copyrighted Content at http://www.microsoft.com/about/legal/permissions/ Microsoft®, Internet Explorer®, and Windows® are either registered trademarks or trademarks of Microsoft Corporation in the United States and/or other countries. Other Microsoft products mentioned herein may be either registered trademarks or trademarks of Microsoft Corporation in the United States and/or other countries. All other trademarks are property of their respective owners.
Lesson 1 Demonstration : Introduction Introduction The way this lesson is presented is a little different to what you might be used to. You would have noticed that there is no workbook and that we are starting with the lab manual. What we are going to do is walk through some examples as an instructor led lab format and then you will complete some lab exercises by yourself.
Objectives After completing this lab, you will be able to:
Understand the basic use and capabilities of Windows PowerShell
Meet the pre-requisites and install Windows PowerShell
Run basic PowerShell commands
Use PowerShell help to get help about PowerShell commands
Prerequisites To complete this lab, you need:
A Windows 7 workstation logged onto with administrator credentials. You can logon as contoso\administrator. The password is P@ssword
How to use the Examples in this Workshop The way with lesson will be presented will be a little different to what you may be used to. You would have noticed that there is no workbook and that we are starting with the lab manual. What we are going to do is walk through the examples together as an instructor led lab format, and then you will do some more lab exercises by yourself. There are three options you can choose from for following the examples:
Manually type in the commands
Open the command files in the PowerShell Integrated Scripting Environment (ISE) and execute each command by selecting each one
Using the automated start-demo PowerShell script to run each command automatically
Each option is a matter of preference. The first option will familiarize you with the commands. This is the slowest option and you may have problems keeping up with the instructor, but this is a great option to run through after the workshop at your own pace to consolidate your learning. The second and third options are easier as they do not require type each command. However, as you are not typing each command you may miss some commands. If you use the second option, the command file can be opened and commands can still be typed using the command pane. This allows you to run some of the command from the file and type others. The third option is the easiest option to run the demo commands. However, you cannot enter additional commands manually. This can be easily solved by opening a second PowerShell console and typing the additional commands.
Option 1: Run Commands Manually This option is to type the command in manually as they appear in the code blocks of each example. You can use tab completion in PowerShell to reduce typing time. Also You can use the up arrow to select the most recent commands executed if you need to build from the previous command.
Option 2: Use of Command Files and the ISE To use the ISE and the command files, change the default view of the ISE to maximize the Real Estate screen. To maximize the Real Estate screen, 1. Select the Start button to open the PowerShell ISE. 2. Type ISE and run the Windows PowerShell ISE. By default, it will appear as follows:
In this view, 1. Open the command file, or files for the lesson. 2. Select each line that does not start with #. 3. Press F8 or right-click and select Run or click the
icon on the toolbar.
Option 3: Use of Start-Demo Script Using the start-demo script is the easiest option. To use this option, your PowerShell console should be opened as normal and the location should be changed to C:\Pshell\part1\lesson1 for lesson 1. 1. To change the location, type: set-location c:\pshell\part1\lesson1
2. Now type the following command to load the start-demo.ps1 script function into the memory: . .\start-demo.ps1
The dot and space before .\start-demo are required.
Exercise 1: Windows PowerShell Objectives In this exercise, you will:
Learn what Windows PowerShell is
Open Windows PowerShell and run some basic commands
Scenario Welcome to Windows PowerShell. Windows PowerShell is both a command shell and a scripting language. A significant difference between PowerShell and other shells is that it is an object-oriented shell. This aspect of PowerShell will be discussed in detail later. The use of Windows PowerShell can be divided into two main areas:
Running commands from the command shell interactively
Running scripts
Running scripts will be discussed later. For now, we will discuss running commands in the shell. Both categories of use of PowerShell are powerful. Depending on the task being performed will determine which category to use. For example, Exchange 2007 or 2010 administrators will be familiar with running commands in the command shell but they may not be familiar with running scripts. We will start with opening PowerShell and running commands in the console.
Task 1: Log on to the VM Environment 1. Log on to the Windows 7 client. 2. Open Windows PowerShell and run the required commands.
Task 2: Open Windows PowerShell for the First Time There are different methods to open Windows PowerShell. Each method has its own purpose. The first one we use is the simplest. 1. Open PowerShell. 2. On the Windows taskbar, click
(PowerShell icon).
The PowerShell window appears. You will notice that it looks different to the standard command prompt. It should have a blue background and white text. It will also have the text PS C:\users\administrator> PS indicates that you are using PowerShell and not the CMD shell.
Task 3: Run the First Command 1. Type the following command: dir
You will see that now you have displayed the files and folders that are available from your current location. Let us compare the PowerShell display and the CMD shell display. 2. Click Start > Run, type cmd and press Enter. 3. In the CMD shell, type the following command: dir
4. Compare the output of PowerShell and the output of the CMD shell. You will notice that they are very different. The main advantage of PowerShell is that it is easy to change the view.
Task 4: Change PowerShell View 1. In the PowerShell console, type the following command to display the file system objects: dir | format-table name, lastwritetime, length
You will see that we now have the same information but it appears very differently. Now let us open PowerShell from the run box. It will look different. 2. Click Start > Run, type powershell and press Enter. The PowerShell prompt appears, but this time you will see it looking more like the CMD shell, as it has the black backgorund and the grey text. Note that it will have the PS C:\users\administator> prompt. 3. In the PowerShell console, type the following command to display the file system objects: dir | format-table name, lastwritetime, length
You will notice that the output is the same as in the blue background window. Now, close the black background window and let us run another command in the blue background window. 4. Type the following command to display processes. get-process
A list of all the processes running on your machine appears. Now, run the same command from the command prompt. 5.
Click Start > Run and type the following command: powershell –command get-process
You will see the command run and produce the output, but the window closes as soon as it finishes running the command. To prevent this, you have the option of keeping the window open after you run the command. You will do this now using the noexit option. Note that this needs to be before the –command option. 6. Click Start > Run and type the following command: PowerShell –noexit –command get-process
You will now see that the command is executed and the window stays open. You can explore other options for running PowerShell.exe and commands by typing PowerShell /?
Exercise 2: The PowerShell Integrated Scripting Environment (ISE) PowerShell v2.0 comes with its own graphical scripting editor known as the ISE. The ISE is a fully integrated scripting environment that both aids in using PowerShell and enhances it. The ISE is installed by default on Windows 7 machines, and installed automatically on workstations as part of the Windows management framework package (that includes PowerShell v2). On Windows Server 2008 R2, it is a feature that you have to enable, or select to install on other operating systems. Once you have the ISE available then it can be run. 1. On your workstation click Start > Run and type PowerShell ISE and press Enter. The PowerShell ISE opens and you will see the three parts of it.
Figure 3
Script Pane Allows you to create and run scripts. You can open, edit, and run existing scripts in the Script Pane.
Output Pane Displays the results of the commands and scripts you have run. You can also copy and clear the contents in the Output Pane.
Command Pane Allows you to type commands. You can run a one-line command or a multi-line command in the Command Pane. Press SHIFT+ENTER to enter each line of a multiline command, and press Enter after the last line to execute the mult-line command. The prompt displayed on top of the Command Pane shows the path to the current working directory. From here, we can run PowerShell commands and view the results.
Task 1: Run PowerShell 1. Click the Command pane and type the following command: dir | format-table name, lastwritetime, length
You will now see in the output pane the results of the command. This is just like having a PowerShell console open, but we are running these commands from within the ISE. Now will we run some commands from the script pane. 2.
Click the Script pane and type the following: get-process
You can open the file _ISE-commands.ps1 if you do not want to type the commands. 3. On the next line, type the following command: dir | format-table name, lastwritetime, length
4. On the next line type the following: write-host “Hello from PowerShell!”
You will notice that the ISE will now color code the different parts of each command. This is to help identify the different parts of each command such as the command part, and strings code blocks.
Task 2: Run All Commands You can now run all commands using the Run button(or press F5) or select the line or part of the line to be run. 1. Drag and select the text you want to run. 2. Use the Run selection button or press F8 to run the command. 3. Select the first line that has get-process and select the text. 4. Select the Run selection button or press F8 to run the command. You will see that in the output pane, you have the results of the get-process command. 5. Select the second line with dir | format-table name, lastwritetime, length and run this selection. The output for this command appears in the output pane.
6. Click the Run button or press F5 to run all the commands. You will see the output of all commands. 7. Keep the ISE open and run commands in it, or close the ISE and run commands in the PowerShell.
Exercise 3: PowerShell V2.0 Installation and prerequisites Before you run PowerShell, you must make sure it is available. PowerShell v2.0 is installed by default on Windows 7 and Windows Server 2008 R2. Therefore, for these operating systems you do not have to do anything additional to make PowerShell available. For operating systems other than Windows 7 and Windows Server 2008 R2 , you will need to download and install the Windows Management Framework package. It is available from http://support.microsoft.com/default.aspx/kb/968929. This package will install Windows PowerShell 2.0, WinRM 2.0, and BITS 4.0. The update can be installed on the following operating systems:
Windows Server 2008 with Service Pack 1
Windows Server 2008 with Service Pack 2
Windows Server 2003 with Service Pack 2
Windows Vista with Service Pack 2
Windows Vista with Service Pack 1
Windows XP with Service Pack 3
Windows Embedded POSReady 2009
Windows Embedded for Point of Service 1.1
In addition to the Windows Management Framework package, the .NET framework 3.5 SP1 is also required on the system to install PowerShell v2.0. Although PowerShell v1 is available, there are many new features of PowerShell v2.0 that should be considered. PowerShell v1 is available for the following systems:
Windows Server 2003 with Service Pack 2
Windows XP with Service Pack 3
PowerShell v1.0 is installed by default, on Windows Vista and as a feature for Windows Server 2008. The requirements for PowerShell v1.0, are that the .NET framework 2.0 is installed on the system. At this stage, it is not recommended that PowerShell v1 be installed, as v2 has many additional features available. By default, all versions of PowerShell will have the execution of scripts disabled. This has to be turned on either by the command set-execution policy or via group policy/registry settings. For PowerShell v2, PowerShell Remoting is also disabled by default. This has to be enabled with the command enable-psremoting or via group policy/registry settings.
Task 1: Determine the PowerShell Version There are several ways you can determine the version of PowerShell you are currently running, or is available on a machine. We will look at several of these and a few things of note.
Use of $host.version 1. In the PowerShell console, type the following command to display the version: $host.version
This will now display the version number of Windows PowerShell. The number to take the most note of is the major version number.
Use of $psversiontable 1. In the PowerShell console, type the following command to view the ps version table: $psversiontable
This table of version numbers not only gives you the version of PowerShell installed but also lists the version of other related components. This is useful when you start looking at some of the advanced features of PowerShell such as remoting. The number to take interested in here is the PSVersion number.
Use of Registry You can also check the version of PowerShell installed on a machine by checking the registry. This can be very useful, as it will allow us to check the version of PowerShell installed on a remote machine without having to run commands in a PowerShell console. 1. In the PowerShell console, type the following command to get the version information from the registry: get-itemproperty HKLM:\software\microsoft\PowerShell\1\PowerShellEngine
You will now see the information from the registry key. The properties to take note of are the runtimeversion and the powershellversion number. You can use the same path on a remote machine to check the PowerShell version installed on the target. This will be discussed later.
Use of PSSnapins By looking at the versions of the PowerShell snapins you can determine the version of PowerShell and see the versions of each snapin that makes up the collections of PowerShell Cmdlets. 1. In the PowerShell console, type the following command to list the PowerShell snap-ins: get-pssnapin
You will now see the current PowerShell snapins and their PowerShell version numbers.
Points to Note About PowerShell v2.0 There are a few things to take note of when looking at PowerShell and its version. Several things such are registry paths, file extensions and install locations did not change between PowerShell v1 and PowerShell v2. These can cause confusion about the version of PowerShell that is in use. First to note is that the file extension .PS1 is still the script file extension for PowerShell v2.
The next is the PowerShell install location. 1. In the PowerShell console, type the following to set the location to the PowerShell install location: $pshome
This variable contains the path to the PowerShell install location. Note that even on a machine with PowerShell v2 installed, this still points to %systemroot%\ System32\WindowsPowerShell\v1.0. The registry path for PowerShell v2 is also HKLM:\software\microsoft\PowerShell\1\.
Exercise 4: Basic PowerShell Commands In this exercise, you will run some basic PowerShell commands. PowerShell allows you to run both PowerShell commands, many of these called Cmdlets, and external commands such as executable. First, you need to create a transcript to record all the commands you type. This will log all commands and the output they produce. 1. In the PowerShell console, type following command to start a transcript start-transcript PowerShell_transcript.txt
This will now start the transcript recording our commands. You will get a quick list of the commands available to run in PowerShell. To do this, use the Cmdlet called get-command. Transcript commands will not work if you are running the demos from within the ISE
2. In the PowerShell console, type the following command to list the commands available. get-command
A list of commands available to you under the current PowerShell console appears. However, you will notice that this list contains different types of commands. For now, you need only Cmdlets. Use get-command to display only the Cmdlets. 3. In the PowerShell console, type the following command to list Cmdlets: get-command –commandtype cmdlet
This will now list just the Cmdlets. You will notice it is a much shorter list than before. In fact you can use PowerShell to tell exactly how many Cmdlets there are. You can do this easily using two different methods. 4. In the PowerShell console, type the following command to count the Cmdlets available: get-command –commandtype cmdlet | measure-object
The count of available Cmdlets appears. By default, in Windows 7 the count should be 236 at the time of writing. There is another way to do this. 5. In the PowerShell console, type the following command to count the Cmdlets available: (get-command –commandtype cmdlet).count
The number of Cmdlets appears. However, this time you will see only the number. Now let us run some more commands. 1. In the PowerShell console, type the following command to get the current date: get-date
The current date and time appears. You can change what appears by using some parameters in the command.
2. In the PowerShell console, type the following command to get just the date: get-date –displayhint date
Only the date appears. 3. In the PowerShell console, type the following command to get only the current time: get-date –displayhint time
Only the time appears. You can also view different time formats. 1. In the PowerShell console, type the following to display the short date format: get-date –displayhint time –format d
2. In the PowerShell console, type the following command to display the long date format: get-date –displayhint time –format D
3. In the PowerShell console, type the following to display the short time format: get-date –displayhint time –format t
4. In the PowerShell console, type the following command to display the long time format: get-date –displayhint time –format T
5. In the PowerShell console, type the following to display the date in a given format: get-date –displayhint time –format yyyy/MM/dd
This will display the date in the given format. Note that this is case sensitive. Note also that you should always use ISO8601 for dates rather than a specific locale. 6. In the PowerShell console, type the following command to display time in a given format: get-date –displayhint time –format hh:mm:ss
This will display the time in the given format. Again, note that this is case sensitive and the lower-case ‘mm’ produces minutes, whereas the upper-case ‘MM’ produces the month. Let us look at something more interesting. 1. In the PowerShell console, type the following command to list the current processes: get-process
A list of the currently running processes appears. We can do the same with services. 2. In the PowerShell console, type the following command to list the services on the system: get-service
A list of services and their statuses appears. However, you might be interested in only one service. You can view this by typing its name after get-service. Microsoft | Services
3. In the PowerShell console, type the following command to get information for just the bits service: get-service bits
Now you will see information about only the bits service 4. In the PowerShell console, type the following command to generate a random number between 1 and 10: Get-random –Minimum 1 –Maximum 10
Exercise 5: Running External Commands The great thing about PowerShell is that you do not have to call the external command with anything special to get them to run. You can run the command by typing the name of the command and pressing Enter. 1. In the PowerShell console, type the following command to get IP configuration information: ipconfig
You will now see that you have the same output that you would have had if you run the command in the CMD shell. 2. In the PowerShell console, type the following command to get all IP configuration information: ipconfig /all
You will again see the same output as the CMDshell. 3. In the PowerShell console, type the following command to get system information: systeminfo
This will now list a summary of the system information of the current machine. What may be useful is to write this information to a file. Just like the CMD shell, you can use the > and >> symbols to redirect the output. > will overwrite the output, whereas >> will append the output. 4. In the PowerShell console, type the following command to redirect output to a file: systeminfo >systeminfo.txt
This will now write that information to a text file for us. To view it lets use notepad 5. In the PowerShell console, type the following command to open the text file in notepad: notepad systeminfo.txt
You will now see the information from the command in the text file. This not only works for external commands, but also for Cmdlets. 6. In the PowerShell console, type the following command to redirect the Cmdlet output to a file: get-service > services.txt
7. In the PowerShell console, type the following command to read the file: notepad services.txt
The information about services appears. You can also get PowerShell to run multiple commands in a sequence. This can be useful as you can put multiple commands in one line and PowerShell will run these in a sequence. This
is especially useful if you have a command that takes a while to run and you do not want to wait until it is finished. To do this, use the semicolon character. This is the statement terminator for PowerShell. 1. In the PowerShell console, type the following command to run multiple commands, add multiple items to a text file and open it in Notepad: ipconfig /all > systemconfig.txt; systeminfo >>systemconfig.txt ; get-service >>systemconfig.txt; notepad systemconfig.txt
The three commands to get information about the system will now run, and each of these will put information into the systemconfig.txt. Finally, open Notepad to view this information. The $lastexitcode variable can be very useful when working with external commands. This variable contains the exit code or errorlevel value from the external command. In general, an exit code of zero is a success and anything non-zero is considered an error of some type. However, this may not be true depending on the program you are running. Let us look at a simple example using the ping command. 1. In the PowerShell console, type the following command to ping the local machine: ping localhost
2. In the PowerShell console, type the following command to check the status of the previous command: $lastexitcode
You will now see that the value of the $lastexitcode is now zero. This is because we were able to ping the localhost. 3. In the PowerShell console, type the following command to ping a non-existing host: ping fakeserver
4. In the PowerShell console, type the following command to check the status of the previous command: $lastexitcode
You will now see that the value of the $lastexitcode is now one. This is because, you were unable to ping the fakeserver host, as it does not exist.
Exercise 6: List PowerShell Commands You looked at listing available PowerShell commands quickly a little while ago. But it is worth spending a little more time on this as it is difficult to remember around 236 or more commands. There will be a number of Cmdlets that you will use repeatedly, and some you may never use. To help you find Cmdlets in PowerShell we have the get-command Cmdlet. This can be used in a number of ways to find the commands that you are interested in. 1. In the PowerShell console, type the following command to list the commands available: get-command
You will now see a list of Cmdlets, functions and alias. This does work a little differently in PowerShell v1 and v2. In v1 you would have only seen Cmdlets by default. 2. In the PowerShell console, type the following command to list just Cmdlets: get-command –commandtype cmdlet
You will now see a list of just the Cmdlets available. Now, let us look for commands that start with get. 3. In the PowerShell console, type the following command to list all the command that start with get: get-command
get*
A list of commands that start with get appears. You will notice that most of these are Cmdlets. However, there are some external commands such as getmac.exe and gettingstarted.exe listed. This is because, these are commands that PowerShell can run. You will notice that these external commands are listed as the type of application. This tells you that it is an external command. If you combine the last two options, commandtype and get* you will see only the Cmdlets. 4. In the PowerShell console, type the following command to list just Cmdlets that start with get: get-command –commandtype cmdlet get*
Now, you will see just Cmdlets that start with get. There is an easier way to do this. You can use the -verb option to look for Cmdlets or functions. 5. In the PowerShell console, type the following command to list Cmdlets with the verb get: get-command –verb get
You will now see any Cmdlets and functions that have the verb get in their name. We will go into more details about the naming of Cmdlets later, but you will find that the names of the Cmdlets follow verb-noun in their names. This makes it easy to know what a Cmdlet might do, but also makes is easy to find the Cmdlets.
6. In the PowerShell console, type the following command to list Cmdlets with the noun service: get-command –noun service
7. You will now see all the Cmdlets that are related to services. We can also do this with a wildcard search. 8. In the PowerShell console, type the following command to get all commands that end with service: get-command *service
Exercise 7: Getting Help with PowerShell One of the useful things with PowerShell is that it has a great built-in help system. All Cmdlets have a help topic and these topics have both, a consistent format and a consistent method for accessing it. This is all done with the Cmdlet get-help. In addition, to having help information for Cmdlets, there are also additional help topics covering PowerShell concepts, 1. In the PowerShell console, type the following command to display the help details: get-help
The help information for the get-help Cmdlet appears. You will notice that information follows a particular format. The good thing is that this format is the same for all Cmdlets. 2. In the PowerShell console, type the following command to get help on the get-command Cmdlet: get-help get-command
The help information for the get-command Cmdlet appears. You can expand on this by using two options. 3. In the PowerShell console, type the following command to get a detailed help on getcommand: get-help get-command –detailed
Some of the same information as before appears on top of the display. However, as you scroll down you will find more information such as the parameter descriptions and some examples. Let us do this again with a different Cmdlet. 4. In the PowerShell console, type the following to get detailed help on get-service Cmdlet: get-help get-service –detailed
The detailed help information for the get-service Cmdlet appears. There is another option that is useful, the –full option. This will display all the help information for the Cmdlet. 5. In the PowerShell console, type the following to get all help on get-service Cmdlet: get-help get-service –full
The full help information for that Cmdlet appears. Another option that can be a great way to jog your memory about how a Cmdlet works is the –examples option. This will display some examples of how to use the Cmdlet. 6. In the PowerShell console, type the following command to get just examples of the getservice Cmdlet: get-help get-service –examples
In addition to getting help on Cmdlets, there are many other help topics available. To see them we will use the following command.
7. In the PowerShell console, type the following command to list all help topics: get-help *
The full list of help topics available appears. You will see the alias, the functions, Cmdlets and finally the helpfile topics. You will notice that all the helpfile topics all have the name about_ this allows us to look just at them. 8. In the PowerShell console, type the following command to list just the about topics: get-help about
Only the information about helpfile topics appears. 9. In the PowerShell console, type the following command to display the wildcards help topic: get-help about_wildcards
The information about PowerShell wildcards appears. Note that there is no –full or – detailed option with the about topics.
Exercise 8: Explore Command History One of the things that can help a lot in the early stages of learning PowerShell is to look at the history of the commands that you have run. This can be done in a few different methods, but we will look at the two main methods. The first is using the get-history Cmdlet to display the previous commands run. 1. In the PowerShell console, type the following command to view the command history: get-history
The previous commands run up to a default maximum of 64 commands. You will notice that each command has an ID associated with it. This ID can be used to re-run a particular command. 2. In the list of commands, locate the ID for the get-help and get-service commands. 3. In the PowerShell console, type the following command to invoke the command from history: invoke-history –id
The command executes again. This can be useful when you have complicated lines of code and you do not want to use the up arrow to go through all commands again. The previous commands can also be exported and later imported to use again. 1. In the PowerShell console, type the following command to export the history to a csv file: get-history | export-csv myhistory.csv
The command history is exported to a CSV file. 2. Open a new PowerShell console and type the following command to view the current history: get-history
As this is a new PowerShell session, you will see that there currently are no commands in the history. You can now import the commands from the CSV file we created to include some history commands that can be invoked. 3. In the new PowerShell console, type the following command to import the history from the other session: import-csv myhistory.csv | add-history
4. In the new PowerShell console, type the following command to view the current history: get-history
You will now see that there are commands loaded into the history and can be invoked. Notice that the IDs will not be the same as the session that we exported the information from.
One thing to note is that by default, you will only see the last 64 commands. This number is defined by the variable $MaximumHistoryCount. To increase the maximum commands: 1. In the original PowerShell console, type the following command to increase the maximum command history count: $MaximumHistoryCount = 100
This will allow you to look at up to 100 previous commands. You can also specify – count 100 for get history to display the 100 commands. By default, you will only get 32 displayed. 2. In the PowerShell console, type the following command to get the last 100 commands: get-history –count 100
There is another way of viewing the previous commands run. However, this will also show the output produced from each of these. If you remember, earlier in the lesson, we created a transcript. This will have recorded all the previous commands that we have run. So let us stop and view the contents of that transcript. 1. In the PowerShell console, type the following command to stop the transcript: Stop-Transcript
This will stop recording of the session and tell you where the output file is. Again, remember here (and moving forward through the additional demonstrations) that transcript commands will fail if being run through the ISE.
2. In the PowerShell console, type the following to read the transcript: notepad
By reading the file, you will see the history of all the commands you have run. This file should be kept for later use, as it can be useful to look at the commands you have run. It is suggested that at least for the next few lessons, start a transcript for each lesson so that you can review those later. In addition to the history Cmdlets, you can also use the up arrow to see the previous commands run. To run the same command again, press Enter. You can also use the up arrow to bring up a previous command and modify it. The drawback here is that if you need to go back several commands, or you need to re-run multiple commands, the order of these commands will change each time a new command is executed.
Exercise 1: Create a Transcript of Commands Objectives In this exercise, you will:
Practice creating transcripts of PowerShell commands
Task 1: Log on to the VM environment 1. Log on to Windows 7 Enterprise client as Contoso\Administrator with the password, P@ssword
Task 2: Open Windows PowerShell Session On the Windows taskbar, click
.
The PowerShell window appears.
Task 3: Record commands in a text file 1. Type the following in the PowerShell console. This will NOT work in the PowerShell ISE as transcripts are not supported under the ISE Host. new-item -path $home\documents -name transcripts -type directory
This will create a new directory for storing transcript files. 2. Type the following to set the transcript variable to a desired location for storing transcript files $global:transcript=”$home\documents\transcripts\$((getdate).tostring("yyyyMMddHHmmss")).txt”
Note: This global variable will be lost when the PowerShell session is terminated. The variable assignment can be added to a Profile if it is required to persist between sessions. Note also that you should always use ISO8601 for dates rather than a specific locale as shown in tostring("yyyyMMddHHmmss")) above.
3. Type the following to start the recording part of this PowerShell session in a text file. start-transcript.
4. Enter some commands, for example: Get-command Get-service Get-process Get-help
5. Type the following to stop recording this PowerShell session.
Exercise 2: Using the Most Common Commands Objectives In this exercise, you will:
Practice using the most common and useful PowerShell commands
Task 1: Log on to the VM environment 1. Log on to Windows 7 Enterprise client as Contoso\Administrator with the password, P@ssword
Task 2: Open Windows PowerShell Session On the Windows taskbar, click
.
The PowerShell window opens.
Task 3: Get-Help, Get-Command and Get-Member 1. Type the following to view the full help available on using the get-help Cmdlet. 2.
get-help get-help -full
Type the following to view help for the get-command Cmdlet.
get-help get-command
3. Type the following to view help for the get-member Cmdlet. get-help get-member
4. Type the following to return the methods and properties that are available for the output of the (get-help get-command) command. (get-help get-command) | get-member
5. Type the following to return only the properties that are available for the output of the (get-help get-command) command. (get-help get-command) | get-member -membertype noteproperty
6. Type the following to return only the methods that are available for the output of the (gethelp get-command) command. (get-help get-command) | get-member -membertype method
7. Type the following to display the command syntax only. (get-help get-command).syntax
8. Type the following to display all the parameters of the command. (get-help get-command).parameters
9. Type the following to view the static members of the datetime type. [datetime] | get-member -static
Exercise 3: Run Multiple Commands Objectives In this exercise, you will:
Explore running multiple PowerShell commands in a single line
Task 1: Log on to the VM environment 1. Log on to Windows 7 Enterprise client as Contoso\Administrator with the password, P@ssword
Task 2: Open Windows PowerShell Session On the Windows taskbar, click
.
The PowerShell window opens.
Task 3: Multiple Commands 1. Type the following series of commands on a single line write-output. The text is wrapped here due to the page width. Write-Output “Asset Information`n” | out-file $home\documents\assetinfo.txt; get-date | out-file $home\documents\assetinfo.txt -append; $Env:COMPUTERNAME | out-file $home\documents\assetinfo.txt -append; get-service | out-file $home\documents\assetinfo.txt –append
2. Type the following command to view the asset information. notepad "$home\documents\assetinfo.txt"
Lesson 2 Demonstration : Commands and objects Introduction This lab introduces PowerShell commands, known as cmdlets. You will learn about cmdlet usage, discovery and syntax for a complete understanding of their importance. You will also understand the concept of objects, which is fundamental to using PowerShell effectively.
Objectives After completing this lab, you will be able to:
Explore command discovery, syntax and usage
Leverage command help topics
Discover & create command aliases
Explain the usage of classes, objects & various object models in PowerShell
Pre-requisites To complete this lab, you need:
A Windows 7 workstation logged onto with administrator credentials
Exercise 1: PowerShell Commands Objectives In this exercise, you will:
Learn command syntax
Learn command usage
Find command help
Discover commands and their grouping
Scenario PowerShell consists of four types of commands:
Cmdlets
Functions
Scripts
External commands
In this exercise, we will focus on using the first type of commands, known as Cmdlets (pronounced ‘command-lets’). Cmdlets are commands ‘built-in’ to PowerShell. They are written in a .NET language (C#, VB.NET, F#, etc.) and compiled into a dynamic link library (.DLL) file. 236 Cmdlets are available by default in PowerShell v2.0 and cover a wide range of uses, from interacting with the file system to listing event log and service information. Although out-of-scope for this lesson, it is worth noting that new Cmdlets authored and compiled by a developer can be loaded into the PowerShell process, alongside the default Cmdlets.
Task 1: Understand the Command Syntax Commands have a verb-noun naming convention, where the verb describes the action to take on the noun. Nouns are always named in a singular way (Process rather than Processes). It is also worth noting that PowerShell is not case sensitive. Command names are followed by a number of hyphen-prefixed parameter names which may be paired with an argument and are known as named parameters. All parameters and their arguments are separated by one or more space characters. Parameter arguments can also be inferred by their position in the command without specifying the parameter name. These are known as positional arguments.
1. Open the PowerShell console or ISE and type the following command: Get-Process
This command will return a list of all processes running on the local machine. 2. To limit the number of processes returned, add a parameter and an argument. The following example uses the Get-Process Cmdlet’s –Name parameter. Get-Process -Name explorer
This will return a single line of information about the “explorer” process running on the local machine. 3. Parameter names can also be shortened by abbreviating them to a unique value. Get-Process -Na explorer
4. Next, try typing the same command using PowerShell’s tab-completion feature. Type the following: Get-
Then, press the Tab key until the full command name appears. Pressing SHIFT+TAB moves backwards through the list. 5. This feature also works with parameter names. Type a space character and a hyphen character. Pressing the Tab key will cycle through all the parameters for a particular command. Again, pressing Shift+Tab moves backwards through the list. Get-Process -
6. Certain parameter names can be omitted entirely with the command still working as expected. Below, the argument explorer is associated with the –Name parameter by its position in the command. Remember that the arguments have to be passed in the default order specified by the Cmdlet. Get-Process explorer
7. Many parameters also accept a list of arguments, allowing more than one value to be bound to a parameter. In PowerShell, lists can be specified by separating each item with a comma. Get-Process –Name explorer,system,wmiprvse
8. Now add a parameter that does not require an argument. Such parameters are called switch parameters, since they change the command's behavior by enabling a feature within it.
For example, the module switch parameter of the Get-Process Cmdlet turns on a feature that lists all the .dll files loaded by the returned process. Get-Process -Name explorer -Module
9. If you omit any required parameters, PowerShell will prompt you to supply the required arguments automatically. In the example below, you are prompted for the -Path and Type parameter arguments to successfully create a new folder on the local C: volume. PS C:\Users\Administrator> New-Item cmdlet New-Item at command pipeline position 1 Supply values for the following parameters: Path[0]: c:\test Path[1]: Type: directory Directory: C:\ Mode ---d----
LastWriteTime ------------11/08/2011 10:00 PM
Length Name ------ ---test
Task 2: Search for Commands (Get-Command) In this task, you will understand how to search for Cmdlets. To do this, use a Cmdlet designed specifically for this purpose. The Get-Command Cmdlet returns a list of commands. 1. Open the PowerShell console or ISE. 2. Type the following command and press Enter: Get-Command
A list of Cmdlets, Functions and Aliases will be displayed, since all command types are listed by default. 3. If you were searching for a command containing a particular string you can enclose it in wildcard (*) characters. Get-Command *item*
4. Get-Command also has –verb and –noun parameters which allow you to limit the search to commands matching the verb and/or noun part of the name. Below we list all the Cmdlets where the word on the left-hand side of the hyphen, the verb, matches the string “get”. Get-Command –verb get
Wildcard characters can also be used in parameter arguments. 5. List all the commands where the noun part of the name starts with the string ‘object’. Get-Command –noun object
6. List all commands where the verb part of the name ends with the letter ‘w’. Get-Command –verb *w
Task 3: Get Command Help (Get-Help) PowerShell has an extensive help system accessible through the Get-Help Cmdlet. The Cmdlet can return the syntax, description, parameters and examples for any command. 1. To use this Cmdlet, type the name of the command you want help for as the first argument. Get-Help New-Item
This use of the command displays basic help information. Get-Help also has a number of switch parameters that control the amount of help information returned. The -full parameter returns all information about a particular command. Get-Help Get-Service -full
The -examples parameter lists different ways in which a command can be used. Get-Help New-Item -examples
The -detailed parameter adds examples and descriptions to the basic help. Get-Help New-Item -detailed
As with all commands, wildcard characters can be used to return help for multiple matches. If only one command matches, PowerShell returns the help for that command. If not, a list of matching help topics is displayed. Get-Help new*
Another useful switch parameter for this Cmdlet is -Online. If you have internet access, this parameter will open the TechNet Windows PowerShell command Help Topics documentation for the specified command. http://technet.microsoft.com/enus/library/dd347701.aspx. Get-Help New-Item -Online
2. Get-Help can also be used to display conceptual help about the PowerShell Language. This is accessed by using the argument about_*, which will list all of the conceptual help topics. Get-Help about_*
You can then choose the topic and use its full name to list the entire help file. Get-Help about_Command_Syntax
Note: A very useful piece of information returned by all the Get-Help switch parameters is the command syntax. This has a special format that is easy to understand, once you know how to interpret it!
Exercise 2: Command Aliases In the previous exercise, the full verb-noun name was used when calling commands. Using aliases, PowerShell provides the ability to create alternate names for any command. Note: Aliases execute the underlying command using a different name.
There are two types of built-in aliases: Transitional and Convenience. Transitional aliases: Transitional aliases were created to assist users migrating from cmd.exe or UNIX/Linux shells to PowerShell. For example, the cmd.exe dir command lists files and folders in the current directory. In UNIX/Linux shells, the same operation is achieved using the ls command. PowerShell implements two transitional aliases for its equivalent directory listing Cmdlet, Get-ChildItem. The following commands both execute Get-ChildItem. dir ls
Convenience aliases: Convenience aliases are, as the name suggests, for convenience. For example, Get-ChildItem has a convenience alias of gci, which saves the time required to type the complete command name. gci
Note: By default, PowerShell 2.0 has 137 aliases. The majority can be re-assigned to point to a different command or deleted entirely, although they will be re-populated when a new console or ISE session is established.
Task 1: Find Different Alias Commands 1. Find all the ‘*-Alias’ commands using either of the methods below: Get-Command –Name *alias Get-Command –Noun alias
You will see five Cmdlets that can be used to manipulate aliases. The most useful of which are Get-Alias, New-Alias and Set-Alias. a. The Get-Alias Cmdlet is used to list all aliases. Get-Alias
b. New-Alias allows you to create new aliases for a Cmdlet, Function or executable file. The -Name parameter argument specifies the name of the new alias and the -Value parameter specifies the command to alias. New-Alias –Name gp –Value Get-Process
Exercise 3: The Object-based Shell Traditionally, the Windows command console and UNIX shells process data in the form of strings. While this is a common way to represent data, it is not easy to extract and manipulate the data. Character sequences need to be found using regular expressions or line/column numbers and converted into the required string format for another command to process. In contrast, PowerShell is an object-based shell built on the .NET framework. Objects are a mechanism to store and manipulate data in a structured way. Data does not have to be extracted from strings and can be accessed using a simple naming convention. Note: PowerShell’s language is based on a POSIX standard shell (IEEE Spec. 1003.2), which itself is based on the UNIX Bourne Shell (Windows PowerShell in Action – Second Edition, Manning Press 2011 by Bruce Payette).
What is an Object? Objects are all around us. A car is an object with a collection of separate parts, such as a steering wheel, accelerator pedal and brakes. To drive the car, we can use the parts to steer, accelerate and slow/stop the vehicle. We can now divide the car (object) into two distinct concepts.
A collection of parts
Uses of the parts to change the car’s behavior
Now, apply this object model to the Windows Operating System. A Windows Service object has a collection of parts called Properties. Properties represent the state of a service, such as the service name and status. The service status can be changed by using object Methods. Object Methods allow you to start or stop a service. Collectively, properties and methods are called object Members. Members
Properties
Methods
Service Name
Start()
Status
Stop()
Note: Method names can be easily distinguished from property names as they are always appended with a pair of smooth brackets ‘()’.
Task 1: List Object Information (Get-Member Cmdlet) The .NET object framework is self-descriptive. All objects hold information that describes their structure. You can interrogate any .NET object and list its properties and methods within PowerShell without needing to refer to the online MSDN Class Library. You can achieve this by passing the object through the pipeline, to the Get-Member Cmdlet. Pipeline operations will be covered in detail in another lesson. 1. Get a list of process objects using the Get-Service Cmdlet and pipe them to the GetMember Cmdlet. This will list the members (properties & methods) of this type of object. Get-Service | Get-Member
2. Alternatively, you can choose not to use the pipeline and employ the Get-Member Cmdlet’s InputObject parameter. This command however lists the members of the collectin of pipeline data as a whole, rather than the individual items in the collection. Get-Member –InputObject (Get-Service)
The top of the output lists the type name of the object(s). In the first case when piping to Ger-Member, you can see it is a System.ServiceProcess.ServiceController type of object. TypeName: System.ServiceProcess.ServiceController
The next piece of information displayed is the collection of members (properties and methods). The output below displays three columns of member information: the name, membertype and definition. Name MemberType ------------Name AliasProperty RequiredServices AliasProperty Disposed Event Close Method Continue Method CreateObjRef Method Dispose Method Equals Method ExecuteCommand Method GetHashCode Method GetLifetimeService Method GetType Method InitializeLifetimeService Method Pause Method Refresh Method Start Method Stop Method ToString Method WaitForStatus Method CanPauseAndContinue Property CanShutdown Property CanStop Property Container Property
3. The PowerShell code below returns the number of members that a System.ServiceProcess.ServiceController object contains. Note: Pipeline operations will be covered in more detail in the next lesson).
You can see that there are 32 members of a System.ServiceProcess.ServiceController object. Get-Service | Get-Member | Measure-Object -Property MemberType Count Average Sum Maximum Minimum Property
: 32 : : : : : MemberType
4. It is possible to shorten the output from this Cmdlet by listing only the properties. Get-Service | Get-Member –MemberType property
5. It is also possible to shorten the output by listing only the methods. Get-Service | Get-Member –MemberType method
6. Now that you have uncovered the object’s members, you can use them to access state information using properties and manipulate the object using methods.
Task 2: Access Object Members To access information stored in object properties or execute object methods, the dot (.) character is used to separate the object name from the member name. This is referred to as dot-notation. 1. Select a single service object by filtering the output of the Get-Service Cmdlet using the Name parameter and assign it to a variable. $ALGService = Get-Service –Name alg
2. Type the variable name to confirm that you have referenced the correct service. By default, three properties of the service object are displayed: Status, Name and DisplayName.
DisplayName ----------Application Layer Gateway Service
3. Type a dot (.) character directly after the variable name and repeatedly press the Tab key. The member names for this object type will be displayed one after the other. 4. Press Enter to display the information stored in one of the properties. $ALGService.DisplayName Application Layer Gateway Service
5. Type the variable name again, followed by a dot, and type Start(). Press Enter. Note: Be sure to append smooth brackets ‘()’ after the method name. $ALGService.Start()
6. Type the variable name to view the service status. Note that the status is still stopped. This is because the state of the service was saved at the instant you assigned it to a variable in step 1. Following the assignment, the state has not been updated. 7. To update the status property, execute the object’s Refresh() method. $ALGService.Refresh()
8. The status property should now display Running. $ALGService Status -----Running
Name ---ALG
DisplayName ----------Application Layer Gateway Service
9. Let’s see another example of accessing object members. Assign a string to a variable and pass it through the pipeline to Get-Member to discover the string object’s members. Alternatively, you can use the alias for Get-Member (gm). $strMyName = “My name is Chris” $strMyName | Get-Member
10. You can also just pipe the string directly to the Get-Member Cmdlet. Both commands in steps 8 and 9 produce the same output. “My name is Chris” | Get-Member
11. The object type name returned is System.String. This type has 2 properties and 32 methods. The length property stores the number of characters in the string. In this case, the string consists of 16 characters. $strMyName.length 16
Alternatively, call the property using the string, rather than the variable. Again, both commands produce identical output. (“My name is Chris”).length 16
Note: Even though the parenthesis are not required above, it makes sense to have them since it applies to other types of commands where this is not possible without parenthesis.
Try calling a few of the object methods. o
The Split() method splits the string on every occurrence of a space character and returns an array. $strMyName.Split() My name is chris
o
The Substring() method returns a part of the string. This method requires input parameters to be provided within the parenthesis to represent the startIndex. $strMyName.Substring(11) Chris
o
The Replace() method replaces a substring of characters with another. This method requires two input parameters:
The string to find
The string to replace it with
$strMyName.Replace("Chris","John") My name is John
Note: The $strMyName variable is never modified by any of the methods and still contains the original string.
Task 3: Use the *-Object Cmdlets PowerShell has a group of Cmdlets that can manipulate any type of object. This Cmdlet is typically used in a pipeline operation. Pipeline operations will be covered in detail in another lesson. 1. List the *-Object Cmdlets. Get-Command –noun Object CommandType Name ----------- ----
Compare-Object [-ReferenceObject… ForEach-Object [-Process] … Select-Object [[-Property] … Where-Object [-FilterScript]
2. Use the Sort-Object Cmdlet to sort a list of file and folders by their lastwritetime property. Get-ChildItem –Path C:\Windows | Sort-Object –Property LastWriteTime
3. Find Process objects with more than 500 open handles using the Where-Object Cmdlet. Get-Process | Where-Object {$_.handles –gt 500}
4. Return the total file size of a directory in KB. Get-ChildItem –Path ‘C:\Program Files’ –Recurse | Measure-Object –Property length -Sum
Task 4: Add Object Members PowerShell allows you to add user-defined members to existing objects. For example, you want to display the number of threads within a process object. The AddMember Cmdlet can be used to add a new property in which to store information. 1. To add a new property, return a process object using the Get-Process Cmdlet and assign it to a variable. $process = Get-Process -Name lsass
2. Confirm that the Process objects’ Threads property contains a list of thread objects. $process.Threads
Since the Threads property is an array object, it has a count property that stores the number of thread objects contained within it. 3. Use the Add-Member Cmdlet to add a new scriptproperty called ThreadCount to the process object. Note that the InputObject parameter is used to supply the object AddMember operates on. The Value property argument is contained in a set of curly brackets '{}'. This is called a scriptblock and can contain any PowerShell code. The $this variable refers to the current object instance stored in the $process variable. Add-Member –InputObject $process -MemberType scriptproperty -Name ThreadCount ` –Value {$this.Threads.Count} -PassThru
Exercise 4: The .NET Object Model The .NET (pronounced ‘dot net’) framework consists of a library of code that enables interaction with many aspects of the Windows Operating system and an environment in which the code runs. The separation of the runtime environment (Common Language Runtime) and the underlying Windows operating system ensures .NET code is unable to directly compromise operating system security and stability.
.NET Assemblies, Namespaces and Types The .NET Class Library is organized into Assemblies, Namespaces and Types. An assembly is a collection of related namespaces and usually, although not always, maps to a single *.dll file stored on the local machine’s hard disk. A namespace contains a collection of related types. Namespace and type names are separated by a dot (.), in the same way object members are separated from an object name. The top of the .NET framework hierarchy is called System. The rest of the hierarchy is organized into namespaces and types under this root namespace. Sometimes it is not obvious which part is the namespace and which is the type.
Namespace
System.String
Type
Namespace
System.DirectoryServices.DirectoryEntry
Type Note: Types are also called classes. You will probably see the two names used interchangeably.
Types and Objects The car analogy (used previously) can be used again to explain the relationship between types and objects. Consider a factory that manufactures a single model of a car. The cars are all based on the same design, although many instances of the model can be produced, each with different characteristics, such as the engine size, color, or internal trim. Types are factories that create instances of a particular model of object. A type defines the number and implementation of members (properties and methods). Many objects can be created from a single type, but are distinct instances of that type. In a nutshell, an object is an instance of a type.
Task 1: Create new Objects Using the New-Object Cmdlet As you have seen, PowerShell will automatically create a new object during assignment of a value to a variable. 1. Assign a string to a variable $strHello = “Hello World”
2. Use the GetType() method, which is included on every .NET object by default, to discover the type of object PowerShell created. PS C:\ > $strHello.GetType() IsPublic IsSerial Name -------- -------- ---True True String
BaseType -------System.Object
3. We can view the fully qualified name of the type by accessing the FullName property of the type object. $strHello.GetType().Fullname System.String
4. You can use the New-Object Cmdlet to create a new instance of a type. In the next example, you will create a new System.String object using this method, although it produces exactly the same result as variable assignment shown above. $strHello2 = New-Object –TypeName System.String(“Hello World”)
5. New-Object allows us to create any object in the .NET framework. For example, creating a directory searcher allows us to query Active Directory Create a System.Directoryservices.Directorysearcher object $objsearcher = new-object system.directoryservices.directorysearcher
6. Execute the findone method to find the first object in Active Directory using a filter of * $objsearcher.findone()
You will now see an Active Directory entry object. 7. Sending an ICMP packet, commonly known as a ping, is a simple process. Create a System.Net.Networkinformation.Ping object $ping = New-Object –TypeName System.Net.Networkinformation.Ping
8. Use the objects Send() method to send a ping to a specific hostname or IP address. $ping.Send(“localhost”)
Object Models The .NET framework is not the only object model PowerShell can use. The Component Object Model (COM) and Windows Management Instrumentation (WMI) technologies are also directly supported.
Task 2: Component Object Model (COM) COM is a Microsoft technology that allows type libraries to be created. These type libraries can be accessed by many different languages. Before the advent of COM, a different version of a type would need to be created for each language accessing it. COM Object type names are registered in the HKEY_CLASSES_ROOT registry hive using the regsvr32.exe utility. 1. Use the New-Object Cmdlet to create a new COM object instance. The COM object type name is specified as an argument to the -ComObject parameter. $objWSH = New-Object –ComObject WScript.Shell
2. To list the members of the new COM object, simply pipe the variable to Get-Member. $objWSH | Get-Member
Note: The type name is in the form of a GUID. Typename: System.__ComObject#{41904400-be18-11d3-a28b-00104bd35090}
3. Use dot notation to access properties and execute methods. Accessing properties and executing methods is achieved in exactly the same way as a .NET object. $objWSH.CurrentDirectory $objWSH.Popup("New Message",$null,"New Dialog Box")
Note: In practice the popup method of the WSH object should not be used. Instead the .Net framework type of system.windows.forms.messagebox should be used.
Task 3: Windows Management Instrumentation (WMI) WMI is Microsoft’s implementation of an industry standard system management object model. WMI allows management of software and hardware objects. It is a languageindependent distributed COM (DCOM) application and can be accessed by a number of scripting and programming interfaces. The WMI object model is organized into namespaces that logically group objects of a similar technology, organized below a root namespace. Each namespace contains many types (classes) that can be instantiated as objects. WMI can simply be accessed in PowerShell through a single Cmdlet, called GetWMIObject. 1. Specify the -list parameter to display all the classes within the CIMv2 namespace. Get-WMIObject –namespace root\CIMv2 –list
2. Type one of the class names as the argument to the -class parameter to list its information. Store the object in a variable. $objBIOS = Get-WMIObject –namespace root\CIMv2 –class Win32_BIOS
3. List the member information (properties and methods) for your chosen class using GetMember. $objBIOS | Get-Member
4. Select a property and access its information. $objBIOS.Manufacturer
Many WMI objects allow changing the object’s state through object methods. The Win32_OperatingSystem class allows us to reboot the OS locally or remotely. Note: On Windows Vista and above Operating Systems, the PowerShell console must be run as an administrator and the shutdown privilege enabled.
5. Store a reference to the Win32_OperatingSystem class in the $objOS variable. $objOS = Get-WMIObject –class Win32_OperatingSystem
6. Request the correct privilege if on using a Windows Vista or above OS. $objOS.psbase.Scope.Options.EnablePrivileges = $true # needed for Vista & above OS
7. Call the Reboot() method on the object. $objOS.Reboot()
Exercise 1: PowerShell Commands Objectives In this exercise, you will perform the following operations to complete the specified task:
Discover PowerShell commands
Investigate command syntax & usage
Estimated time to complete this lab 10 minutes
Scenario As we have seen, PowerShell contains a large number of built-in commands, called cmdlets. In this exercise we will find cmdlets and discover their syntax in order to complete a task.
Log on to the VM environment Log on to Windows 7 Enterprise client as Contoso\Administrator with Password P@ssword
Open Windows PowerShell Session On the windows task bar locate the
Tasks to Perform: The objective of this exercise is to measure the total size of all .txt files in C:\Program Files and all its subfolders. 1. From the PowerShell console, execute the following command. In PowerShell v2.0, the – commandType parameter is required to include only cmdlet objects in the output. By default this command returns cmdlets, functions and aliases. Get-Command –commandType cmdlet
This will return a list of the default PowerShell cmdlets. While this list is comprehensive, it is also rather large. 2. Let’s reduce the size of the list by using one of the Get-Command cmdlets parameters to filter the results. To do this we must first discover how to use Get-Command, by employing the Get-Help cmdlet, to view the associated help file. Get-Help –name Get-Command
As you can see, the output is fairly general. It may be more help to only list the parameters available on this cmdlet. 3. Modify the previous command to include –Parameter, followed by a wildcard (*) character, to list all the parameters for the cmdlet. Get-Help –Name Get-Command –Parameter *
4. The output gives much more detail about each parameter. As our first objective is to find the cmdlets we need to complete the task, use the –Name, -Verb and –Noun parameters to search for cmdlets by full name, verb and noun. Specifying keywords and wildcard characters will allow Get-Command to filter the cmdlet list. The task states that we must ‘measure the total size of files in a folder and its subfolders’. To complete the objective, we must first get a list of file & folder objects. The Get-* cmdlets are often used as the first cmdlet in a PowerShell pipeline, as they return a list of objects of a specific type. Get-Command -commandType cmdlet get* 5. The list is much shorter than the output of step 1. The cmdlet we require is Get-ChildItem, near the top of the list. Familiarize yourself with this cmdlet’s parameters and syntax using Get-Help. Get-Help –Name Get-Childitem –Parameter *
Another great way to discover cmdlet syntax and usage is by using Get-Help’s –Example switch parameter. Get-Help –Name Get-ChildItem –Example
6. Use the help to decide which parameters are needed to list all text files beneath the path C:\Program Files. Note that the path (C:\Program Files) contains a space character, so it must be enclosed within single or double quotes. Microsoft | Services
7. The command does return all .txt files and folders beneath the specified path. The – recurse switch parameter (a parameter that doesn’t require an argument), ensures that all subfolders are searched & the –Filter parameter’s argument constrains the search to files with the extension ‘txt’. 8. The previous steps complete the collection of file and folder objects. Next, we need to calculate their total size. To do this we require a cmdlet that can measure the length property of all file objects returned (folders do not have a length property & therefore don’t directly have an impact on disk space, other than their entries in the Master File Table). Use Get-Command to search for cmdlets with the keyword ‘Measure’. Note that this time we aren’t sure if the noun or verb part of the cmdlet name contains the text, so we use the –name parameter to search the full name. Surrounding the text with wild-card characters ensures all possible matches are returned. Get-Command –CommandType cmdlet –Name *Measure*
9. Fortunately only 2 cmdlets contain the word ‘measure’. To decide which one to use, have a look at their associated help files. Instead of using the Get-Help cmdlet, try using the shortcut to displaying the default help for a cmdlet, the -? Switch parameter. Measure-Object -?
10. The Measure-Object cmdlet is suitable to complete this task as it ‘…calculates the numeric properties of objects…’ Use Get-Help’s –Detailed, -Example and –Parameter parameters to discover more information about the commands syntax & usage. Get-Help Measure-Object –Detailed Get-Help Measure-Object –Example Get-Help Measure-Object –Parameter *
Measure-Object accepts pipeline object input and allows the property of interest to be specified using its –Property parameter. The –sum switch parameter stores a running total of the file sizes. Get-service | Measure-Object
11. The ‘length’ property of a file object stores its size on disk, in bytes. A simple pipeline operation (pipelines are covered in detail in the next module) is all that is needed to pass the filtered list of .txt files to Measure-Object. Get-ChildItem –path ‘C:\Program Files’ –Filter *.txt –Recurse | Measure-Object –Property length –Sum
12. The Measure-Object cmdlet returns a single object containing its results, therefore we are able to access its ‘Sum’ property directly and perform further formatting. Such as displaying the total file size in Megabytes. To do this, enclose the previous pipeline command in smooth parentheses and use a dot ‘.’ to access the object’s ‘Sum’ property.
Finally, use the division operator (/) and ‘MB’ constant to convert the ‘Sum’ property’s byte result to Megabytes. (Get-ChildItem –path ‘C:\Program Files’ –Filter *.txt –Recurse | Measure-Object –Property length –Sum).sum / 1MB
Tasks to Perform: Since everything we will work with in PowerShell is an object, it is crucial to be able to discover the various members (properties and methods) of any object. We will take the common administrative task of working with files and folders as an example of how to discover and use object members. 1. Use the Get-ChildItem cmdlet to list file and folder objects from C:\Windows and pipeline them to the Get-Member cmdlet in order to view the type of objects returned. Get-ChildItem –path C:\Windows | get-Member
2. From the output we can see that two different types of object exist in the file system, System.IO.DirectoryInfo and System.IO.FileInfo objects. Each of these object types contain a large number of members. Execute the command above, but this time, include Get-Member’s –MemberType parameter & specify the argument ‘property’. The output now only lists the object properties. Get-ChildItem –Path C:\Windows | Get-Member –MemberType property
3. The LastWriteTime property can be seen in the listing. This property contains a date object that stores the last time the file or folder was modified. 4. How would you list only object methods? 5. Next, we will create a pipeline command to filter all files and folders modified over 60 days ago. To do this we will need to create an object that represents a date. Use the GetDate cmdlet to create a new date object and save a reference to this object in a variable. $Date = Get-Date
6. Using the Get-Member cmdlet we can view the members of the date object referenced by the $Date variable. $Date | Get-Member
7. One member that can be seen in the output is the AddDays() method. By supplying an input parameter to the method we can produce a modified date. $Date.AddDays(-60)
8. We can now use the members found on the file, folder and date objects to perform a pipeline operation to determine the files and folders modified over 60 days previously. The pipeline operation performs the following operations. i) ii) iii)
Lists all file and folder objects in the C:\Windows folder. Pipeline the objects to the Where-Object cmdlet. Determine whether the current file or folder object’s LastWriteTime property is greater than the current date, minus 60 days.
Tasks to perform: In this exercise we will create a new TcpClient object and use it to check connectivity to a TCP port number on a remote machine. 1. First we must create an instance of the TcpClient class and save a reference to it in a variable. To do this, specify the .NET class name of the object as an argument to the New-Object cmdlet’s TypeName property. The full name of the class is System.Net.Sockets.TcpClient. $tcpClient = New-Object –TypeName System.Net.Sockets.TcpClient
2. Use Get-Member to see what members exist on this type of object. $tcpClient | Get-Member
3. One of the members listed is the Connect() method. An easy way to view the input parameters for a method is to type the method name omitting the parentheses. $tcpClient.Connect
Four different numbers and combinations of input parameters can be specified for this particular method – This method is referred to as having four ‘overloads’. The overload we are going to use (the first in the above list) requires two objects, a string that represents the hostname of the remote machine and an Integer that stores the port name on which we wish to connect. 4. Try executing the Connect() method against SYDDC01 on port 80. $tcpClient.Connect(“SYDDC01”,80)
5. If no error was returned, confirm that the connection is open using the connected property. The value ‘True’ should be returned $tcpClient.Connected
6. Use the Close() method to close the TCP socket connection and dispose of the TCPClient object. $tcpClient.Close()
In the next exercise we will create a COM object. Thousands of COM objects ‘ProgID’ identifiers are listed in the Operating System registry under HKEY_CLASSES_ROOT. We will create an instance of the InternetExplorer.Application COM class, which allows Microsoft’s Internet Explorer browser to be manipulated programmatically. Note: The next task requires internet access, and should therefore be performed on the student host machine.
1. Creating a COM object instance is also achieved using the New-Object cmdlet, although the –ComObject parameter is used, instead of the –TypeName parameter. $ie = New-Object –ComObject InternetExplorer.Application
2. Get-Member can be used to view the object’s members in exactly the same manner as .NET objects. $ie | Get-Member
3. The Navigate2() method opens the URL specified in the method’s input parameter. $ie.Navigate2(“http://www.microsoft.com”)
4. At this point, the Internet Explorer window is not visible. Using Get-Member, locate the member name that allows the window to appear. What data type does it accept? 5. Next, set the Visible property to the value $true. $ie.Visible = $true
6. The Internet Explorer should now be visible. How would you close the Internet Explorer window using PowerShell?
Exercise 1: Understand the Fundamental Operators Objectives In this exercise, you will:
Learn comparison operators
Discover regular expression usage
Learn logical operators
Scenario PowerShell consists of many different operators:
Arithmetic
Assignment
Comparison
Logical
Redirection
Substring
Type
Unary
Special
In this lesson, you will understand comparison and logical operators, which you will commonly encounter while working with the pipeline. Comparison operators are used to:
Compare values such as text and numbers
Provide a mechanism for testing conditions such as during a call to the Where-Object Cmdlet
There are 13 different comparison operators. Some test for simple equality while others work with sets or special matching situations. Logical operators allow you to join multiple operations to check for compound conditions being true or false. There are five logical operators you will work with, two of which serve the same purpose.
Log on to VM Environment Log on to the Windows 7 Enterprise client
Task 1: Test Equality To test if two values are equal to or not equal to each other, you can use the –eq or –ne operators respectively. These operators, like all comparison operators, are case-insensitive by default.
1. Open the PowerShell console or ISE and type the following command: “PowerShell” –eq “powershell”
This command will return a value of True indicating that these two string values are equal to each other. 2. You can also test if two values are not equal by running the following command: “POWERSHELL” –ne “powershell”
This command returns a value of False since PowerShell is case-insensitive and, irrespective of the case, by default two strings of the same character combination and order will be the same. 3. If you want PowerShell to perform a case-sensitive test of equality, you can add a ‘c’ before the operator you are using. “PowerShell” –ceq “powershell”
This will return a value of False since the strings have different casing. This will work with any comparison operator, not just –eq and –ne. 4. PowerShell can be made to explicitly do a case-insensitive comparison, which can help readability in scripts in certain cases. This is done by using an i instead of a c. “PowerShell” –ieq “powershell”
This will return True once again since an insensitive comparison was explicitly used. 5. Testing equality does not stop with -eq and -ne. You may also need to know whether something is less than, greater than, and so on. When working with numbers, these operations function exactly as you would expect; the following commands: 4 3 3 7
–gt –ge –lt –le
4 3 7 4
The commands above will return the values False, True, True, False, respectively, for tests of greater than, greater than or equal to, less than, and less than or equal to operators. 6. You can do the same thing with strings as well. “Reed” –gt “Read” “k” –lt “g” “powershell” –le “POWERSHELL” “user” –cge “USER”
These commands will return the values True, False, True, and False, respectively. When comparing string values, PowerShell uses the Compare method built into the String type. Therefore, in a case-sensitive comparison, “u” is considered less than “U”. 7. It is interesting to note that you can use arrays when testing for equality. When you do this, you will get more than a simple True or False return value. Microsoft | Services
Instead of returning a simple True, the first command returns “foo” indicating that it found that value to be equal to the one being tested against
The second command returns an array containing “fizz” and “bang” indicating that it found those values to be not-equal to “buzz”
The last command returns no data because nothing in the array is equal to “four”
Task 2: Further Tests with Arrays While equality is easily tested against an array and will return the appropriate set of values, sometimes only a True or False value is required that can be used simply in a conditional statement. 1. To check if a specific value is contained within an array, you can use the -contains operator, returning True if the specified value is found, otherwise false. “foo”,”bar”,”baz”,”qux” –contains “bar” “one”,”two”,”three” –contains “four”
In the example shown above:
The first command will return a value of True since “bar” is contained within the array
The second command will return False since “four” is not contained within the array
2. To check if a value is not contained within an array, you can simply change the operator to -notcontains instead. Use the same data as our previous example, but with the new operator. “foo”,”bar”,”baz”,”qux” –notcontains “bar” “one”,”two”,”three” –notcontains “four”
This will then return False for the first command and True for the second.
Task 3: Wildcard and Regular Expression Tests Checking for a specific value being equal to another is not always enough to confirm if you are dealing with the right data. Sometimes you will need to match a string based on only a part of it. For example, looking at a list of usernames and only returning those that begin with the letter “P”. PowerShell allows you to use basic wildcards through the -like and -notlike operators, and allows you access to regular expressions through -match and -notmatch. 1. Wildcard characters allow you to represent more than a single character when matching. “Dog” –like “D*” “Dug” –like “D[ou]g”
The first returns true because the “*” character is a wildcard that matches zero or more characters of any kind
The second returns true because the square brackets denote a group of characters to match a single time, in this case “o” or “u”
The third returns false because although you allow any single character with the “?” wildcard character you are using the notlike operator
The fourth also returns false but this time it uses a range wildcard to match any single letter from “a” to “z”, but here you have two characters in the middle
2. Just like other comparison operators, the like and notlike operators can be forced to be case sensitive by adding a “c” to the operator name “Cat” –clike “C*” “Cat” –clike “c[au]t” “curl” –clike “c[au]*”
These three commands will return true, false, and true, respectively.
Logical Operators In order to combine a number of different comparison operators, you need to use logical operators to make compound statements. The logical operators you can use are -and, -or, -xor, and -not. There is one additional operator that is available that does the same thing as the -not operator, but it is only a single character "!" (exclamation mark). The -and, -or, and -xor operators are binary operators. This means that they operate on two statements, allow you to combine them, and get a single statement output. Each operator has a left and a right side statement which are joined, and either side can also be another logical statement. The following truth table shows the logical functionality of each operator, where p represents the statement on the left side of the operator and q represents the statement on the right side: p
q
-and
-or
-xor
$true
$true
$true
$true
$false
$true
$false
$false
$true
$true
$false
$true
$false
$true
$true
$false
$false
$false
$false
$false
The -not and ! operators are simpler because they are unary operators − they only operate on a single statement. So, instead of having a left and right side, you place the operator in front of the statement you wish to negate.
Using these operators within PowerShell is quite simple. However, the order of operations is a point to take note of, since the incorrect order can cause unexpected results. You can use parenthesis to override the order of operations, forcing PowerShell to evaluate anything within the parenthesis first. (4 –ge 8) –and (5 –lt 10) ! (4 –eq 4) -not $true –xor $false -not ($true –xor $false)
Note: The about_Operator_Precedence help topic is not included with PowerShell 2.0 documentation however, it can be read via TechNet http://technet.microsoft.com/enus/library/ee681734.aspx
Exercise 2: Understand Pipeline usage, syntax, and the pipeline variable Objectives In this exercise, you will:
Understand pipeline basics (usage and syntax)
Understand pipeline variable
Scenario The pipeline allows a user to take a number of simple commands and string them together into a single pipeline. In the previous exercises, you were writing statements for PowerShell to evaluate. The evaluation of these statements produced an output. The fact that these commands produce output without having to explicitly tell PowerShell to do so ties in directly with the concept of the pipeline. PowerShell will take an object on the pipeline and pass it from one command to the next until there are no additional commands to pass through. When an object reaches the end of the pipeline, PowerShell outputs it to the host.
Log on to VM Environment Log on to the Windows 7 Enterprise client.
Task 1: Understand Pipeline Basics 1. Open the PowerShell console or ISE and type the following command. Get-Process | Where { $_.WS –gt 15MB } | Sort WS | FT –property Id, Name, WS
The command above is a single pipeline made up of four commands that take the output of the Get-Process command and pass it along the pipeline. Each command is separated by a pipe “|” which sends the output from one command to the next. 2. One of the revolutionary aspects of PowerShell is that the pipeline passes objects rather than the simple text data you see on the screen. Get-Process
This command will output the list of running processes on the user's machine with eight properties displayed for each process, including its ID and working set. 3. Now, take that data and pipe it into Format-Table to display other properties. Get-Process | Format-Table ID, ProcessName, StartTime, MainWindowTitle -Autosize
Even though Get-Process by itself only displays six properties for each process, there is more data that gets passed along the pipeline. In this case, you are sending process objects to Format-Table, which then displays two properties: StartTime and MainWindowTitle, which were previously unavailable.
4. A more involved pipeline might look something like this: Get-Process | Where { $_.WS -gt 15MB } | Sort WS | FT Id, Name, WS
As you can see, you can use more than a single pipe in a command to make it more useful. Here, a few aliases are used to make the command fit on a single line, but the task performed is passing objects along four different commands in the pipeline. The output of each command is always passed from left to right along the pipeline.
Task 2: Understand the Pipeline Variable You may have noticed in previous examples when using the Where-Object Cmdlet you had a reference to $_. This is a special variable called the pipeline variable. The pipeline variable is used to refer to the current object on the pipeline. An interesting fact about the pipeline is that, when looking at the data returned by a Cmdlet or function, objects are often returned one at a time. This operation is asynchronous in a way because a Cmdlet does not necessarily need to complete processing before the output can be passed on to the next command in the pipeline.
Get-Process
|
Where-Object { $_.WS -gt 50MB }
|
Sort-Object -property WS
|
Format-Table -property Id, Name, WS
Some Cmdlets however, do require all of the possible input before they can produce any output, such as the case with Sort-Object. In the example above, Sort-Object needs to know the working set of every process before it can sort them according to that property. 1. When piping data, usually things will show up very quickly, which can make it seem like data gets sent along the pipeline instantly: 1..5 1..5 | Sort-Object -Descending
Here, you start by creating an array of numbers from one to five using the range operator (..). Since there are no additional commands on the pipeline, PowerShell outputs those numbers to the console. When you pipe that range of numbers to Sort-Object, it changes the order of the numbers as they get passed along the pipeline. 2. Using the ForEach-Object Cmdlet, you can slow down the data being sent along the pipeline. 1..5 | ForEach-Object { Start-Sleep 1; $_ }
The ForEach-Object Cmdlet instructs PowerShell to sleep, by using the Start-Sleep Cmdlet, for one second before then passing each object along the pipeline.
Here you can see the numbers one through five displays with a one-second delay between each one. Each object gets passed along the pipeline and, in this case, it outputs them to the console. 3. However, not every Cmdlet can process the pipeline data asynchronously. 1..5 | ForEach-Object { Start-Sleep 1; $_ } | Sort-Object -Descending
Here you see a 5 second delay before anything actually happens because Sort-Object cannot process the data asynchronously. Sort-Object is a command that needs to receive all of the pipeline data before it can decide what the appropriate sort will be. After the initial delay, however, the numbers all appear almost instantly because Sort-Object sends all of the data along the pipeline once it is finished processing. 4. To slow down the data as it is passed further along the pipeline, you can move the ForEach-Object Cmdlet after the sort. 1..5 | Sort-Object –Descending | ForEach-Object { Start-Sleep 1; $_ }
Now you can see that the data is sorted first, quickly, before it is slowed down in the ForEach-Object loop before being output. 5. If you were to use the output of a Cmdlet rather than a range of numbers, you would see a similar result. Get-Process | Sort-Object –Descending | ForEach-Object { Start-Sleep -m 250; $_ }
The process objects from Get-Process are passed along the pipeline one at a time. In this example, you can see each running process with a 250 millisecond delay between each one. In all the examples so far, you have been treating the pipeline variable as a single unit. However, in reality there are more behind the scenes. 6. Consider the members available to each object output by Get-Process. Get-Process | Get-Member
You can see that there are several properties available. The pipeline variable applies to the entire object. In the case of Get-Member, it has to inspect each object to provide feedback to the user about the available members, since not every object on the pipeline will be of the same type. Get-Process contains the same type of object so all you see are members of the System.Diagnostics.Process type. 7. Now, consider a directory. Get-ChildItem C:\Windows | Get-Member
In this case, you can see that there are both System.IO.FileInfo and System.IO.DirectoryInfo objects being passed along the pipeline. 8. Get-Member is another Cmdlet that processes data asynchronously. Get-ChildItem C:\Windows\s*.*
When you run the command above, the Cmdlet returns directories before files in the list.
9. You can add a delay to this command before sending it along the pipeline to Get-Member. Get-ChildItem C:\Windows\s*.* | ForEach-Object {Start-Sleep 1; $_ } | Get-Member
Now you will see the type information come back slowly. This is because Get-Member will only pass unique type information along the pipeline and, therefore, you have to wait for each of the objects and their associated sleep command to occur. 10. What you have seen is that $_ refers to only a single object along the pipeline. However, each object has individual members and the pipeline variable provides access to all of them for each individual object. Get-ChildItem C:\Windows\s*.* | ForEach-Object { $_.Name; $_.LastWriteTime }
Here you can see that the ForEach-Object Cmdlet allows you to access the name and last write time for each object that is passed along the pipeline to it.
Exercise 3: Filtering, Sorting, and Grouping data Objectives In this exercise, you will:
Control the display of pipeline objects
Filter pipeline objects
Sort and group pipeline objects
Scenario There are a number of different Cmdlets that allow you to modify the order of data that is passed along the pipeline. In this exercise, you will look at some of the most common Cmdlets that are used in this process. The Get-Process Cmdlet, for example, has parameters that allow you to control which process objects are passed back along the pipeline. However, you may need to be more restrictive of that data than the Cmdlet allows. There are also times where you may need to display data that does not show by default or change the order of what is passed along the pipeline.
Log on to VM Environment Log on to the Windows 7 Enterprise client
Task 1: Controlling the Display of Pipeline Data When working with objects on the pipeline, PowerShell typically only outputs the most pertinent data to the console. This is controlled by some advanced functionality within PowerShell in a number of configuration xml files that tell PowerShell how to handle data. If you want to override this default display of data, there are a few options at your disposal. 1. The most basic method of controlling the properties that display for a given object is to use the Select-Object Cmdlet. Get-Process | Select-Object -property ID, Name, WS, MainWindowTitle Get-ChildItem | Select Name, Length, LastWriteTime
Here you can see that the display returns different information than what is returned by Get-Process and Get-ChildItem when run by themselves. Using the default “property” parameter allows you to specify an array of properties to pass further along the pipeline. In the second command you can use the built-in alias: Select. 2. Sometimes you may want to return more detailed information than a basic property value. In the previous Get-ChildItem example, you selected the length property, which is used for file size in bytes. If you want to change it so that it displays in megabytes, you can provide a custom property through a hash table. gci | Select Name, @{Name=”Size(MB)”;Expression={[Math]::Round($_.Length/1MB, 2)}}
The hash table that you provide has two key/value pairs.
The first is called Name and specified the name of the property that will be displayed. This will show as the column heading in table format or the label in list format.
The second value is an expression provided as a code block, which uses the Math class to round the file size to two decimal places after dividing by 1MB.
3. Select-Object allows you to change the properties that are returned as well as the number of objects that are passed along. Get-Process | Select ID, Name, WS -First 5 Get-Process | Select ID, Name, WS -Last 10
In the example above, the Select-Object Cmdlet is instructed to only select the first 5 objects from the pipeline (in the first example) or the last 10 objects (in the second example). 4. There is also a parameter called Index, which will return only the nth item from the pipeline. Get-Process | Select -Index 10
Depending on what applications your system is running, you could see a wide variety of processes returned here. However, it will only be a single process, and if you look at the full list that Get-Process returns by itself, you will see that it is the 11th process on the list. It is the 11th item from the list because the Index is 0-based, meaning our first item is index 0, second item is index 1, and so on. This concept ties in with arrays as well, which are also 0-based in PowerShell. 5. It is important to note that Select-Object modifies the objects being passed along the pipeline. Get-Process | Select ID, Name, WS | Get-Member
When you pass a Select-Object to Get-Member, the data changes and you no longer have a full representation of the object that was passed into Select-Object. In the case above, you will notice that all of the extra properties that were not included in the Property parameter are now missing from Get-Member’s output. Any other properties are now unavailable to any remaining commands on the pipeline. If you were to try sort your output after this by the CPU utilization (which was not included in the Select) you would not see the order change because the CPU property is missing. 6. In addition to Select-Object, there are a few other Cmdlets that are used for controlling the properties that are displayed on the screen: Format-List and Format-Table. These Cmdlets both allow you to specify the properties. Get-Process | Format-List -Property ID, Name Get-Process | FL ID, Name, CPU, WS
The Format-List Cmdlet simply takes the data and converts it into a format where your key and value pair are listed horizontally. The second command uses the built-in alias for Format-List: FL 7. Typically, objects get output to the screen in a tabular format based on the configuration files mentioned earlier. However, sometimes that output will default to a list format. When it does, you can use Format-Table to force it to display as a table. Get-Service | Format-Table -Property Name, Status Get-Service | FT Name, Status -AutoSize
The Format-Table Cmdlet also has an autosize parameter, which controls how much of the screen is taken up by the output. PowerShell attempts to determine the most appropriate display format when using this parameter. The second example uses the builtin alias for Format-Table: FT. 8. Like the Select-Object Cmdlet, Format-Table and Format-List also change the data that is passed along the pipeline. However, these Format commands do it drastically. Get-Process | FL ID, Name, CPU, WS | Get-Member
What you can see from the Get-Member output is that you have a number of different objects that are being passed along the pipeline by the Format-List command. This change in the object makes it impossible to access any of these properties again. 9. You can use a Sort-Object Cmdlet to order data after a Select-Object Cmdlet, but not with Format-List or Format-Table. Get-Process | Select ID, Name, CPU, WS | Sort-Object WS Get-Process | FL ID, Name, CPU, WS | Sort-Object WS
The first command will properly sort the data. This is not a recommended format for writing this command. The Select-Object Cmdlet is still changing the data so if you were to try to sort by virtual memory size (VM) instead of working set (WS) no sorting would actually take place, since the VM property is gone. The second command with Format-List is more drastic and throws an error. The error that is thrown relates to the fact that Format-List changes the data so drastically that it is no longer valid input for a command like Sort-Object.
Task 2: Filter Data on the Pipeline You have already seen how Select-Object can control some of the data that gets passed along the pipeline, and that data can be changed drastically when using the Format Cmdlets. If you want to change which results are passed along instead of the data that passes along with them, you can use the Where-Object Cmdlet. 1. In addition to the objects being passed into Where-Object, it only takes one additional parameter: FilterScript. The parameter name is optional here so all you have to do is provide the script block that is used for the filter. Get-Process | Where-Object { $_.WS -gt 15MB }
Here you are instructing Where-Object to only return objects of which the working set is greater than 50 megabytes. Where-Object goes through each item in the pipeline, changing the pipeline variable each time, and executes the filter script to check if the filter is true or false. If the filter script is true for that item in the pipeline, it is then passed on to the next command. 2. Where-Object also has a few built-in aliases, one of which can sometimes confuse people who are new to PowerShell. Get-Process | Where { $_.Name -eq “notepad” } Get-Process | ? { $_.Threads.Count -gt 25 }
The second example, using a question mark, can look confusing. However, it is a simple alias used for Where-Object and is the number 2 spot atop the list when you execute the Get-Alias Cmdlet with no parameters in a standard PowerShell instance. 3. Going back to the Select-Object Cmdlet, there is one additional parameter it provides, which helps to filter data along the pipeline. Get-Process | Select Name -Unique
Every version of Windows in the recent past will run a number of services that hosted within the same executable running as separate instances. You could have multiple PowerShell, ISE, or notepad instances running, among others. The Unique parameter allows you to filter out duplicate objects and only return those that are distinct.
Task 3: Sorting and Grouping Objects on the Pipeline You have already seen a few examples using Sort-Object, showing that it synchronously processes data along the pipeline. 1. Sort running processes by the size of the working set with the following command: Get-Process | Sort-Object -Property WS
Note: The property parameter name is optional and Sort-Object has a built-in alias called Sort.
2. When sorting objects, take note of where in the pipeline these objects are. Get-Process | Sort WS | Select -First 10 Get-Process | Select -First 10 | Sort WS
These two commands have very different meanings. In the first command you are getting the 10 processes with the smallest working set because you:
Sorted first along the pipeline
Then limited the selection to the first 10
The second command, since you selected the first 10 process objects, will sort only those first ten objects. It will therefore (very likely) not be the same list of 10 processes.
3. Sort-Object also allows you to change the order of the sort by using the Descending parameter, which can be shortened to Desc. Get-Process | Sort WS –Desc | Select -First 10
In the example above, you are getting the 10 largest processes by working set rather than the smallest 10 as in the previous example. 4. When working with text data, you can also tell Sort-Object to sort case-sensitively. "abC", "ABc", "deF", "aBc", "DEF", "def" | Sort-object –CaseSensitive
This command changes the sort, since lower-case letters are considered to be of lower value than upper-case letters, just as when you examined the comparison operators. 5. Sort-Object also allows you to only sort unique objects. "abC", "ABc", "deF", "aBc", "DEF", "def" | Sort-object -Unique
In this case, because you are no longer doing a case sensitive sort, the Cmdlet sees that there are a number of duplicates. Thus, the result set is limited to a sorted “aBc” and “def”. These are chosen from the list because they are the individual unique items found last in the pipeline. 6. If you want to get unique objects, it may be more useful to use the Group-Object Cmdlet. This will allow you to maintain all of the items that are found to be duplicates. "abC", "ABc", "deF", "aBc", "DEF", "def" | Group-Object
The data returned with Group-Object will, by default, group the data into GroupInfo objects that contain each individual item for each group. The name of each group will be the first unique value found for each one: in this case, “abC” and “deF”, unlike SortObject -Unique.
Exercise 4: Pipeline Input and Output Objectives In this exercise, you will:
Input and output simple data to and from the pipeline
Work with CSV files
Understand the ConvertTo-* Cmdlets
Scenario Since the pipeline only goes from left to right, you should be able to provide some kind of input to the pipeline that cannot be generated from an initial cmdlet or function. To do this, PowerShell provides a number of simple commands to input and output data to and from the pipeline.
Log on to VM Environment Log on to the Windows 7 Enterprise client
Task 1: Understand Basic Input and Output on the Pipeline Since you are going to be working with data in the pipeline, you first need to create a file to work with. To do this you can use the Set-Content and Add-Content Cmdlets. 1. Write data to a file using Set-Content. Set-Content -Path c:\pshell\part1\lesson3\services.txt -Value “winrm”
This command writes “winrm” to a file called services.txt. Open the file with notepad to verify the data was written, then close notepad. Set-Content can also be called by its built-in alias sc. 2. Append data to the file using Add-Content. Add-Content -Path c:\pshell\part1\lesson3\services.txt -Value “wuauserv” Add-Content c:\pshell\part1\lesson3\services.txt “netlogon”
Here you are using Add-Content to append data to an existing file. If the file did not exist, a new one would have been created. Re-open the file in notepad to verify that you have five service names listed (each on a separate line), then close notepad. 3. You can also pipe data to Set-Content and Add-Content. “winlogon”, “dnscache” | ac c:\pshell\part1\lesson3\services.txt
This command takes the pipeline data of a text array and sends it in by value to the AddContent Cmdlet, appending each pipeline object as a new line within the services.txt file. Additionally, you are calling Add-Content by its built-in alias.
4. Set-Content and Add-Content were designed to work with string data. So, if you pass non-string data to them, PowerShell will convert the objects to strings before writing to the file. Get-Process | Set-Content c:\pshell\part1\lesson3\processes.txt
If you open this processes.txt file in notepad, you will see that there is a line item for each process running on your machine. Unfortunately, the actual information contained on each line is the string conversion output from a Process object. You can see this by calling the ToString() method of any process object. Get-Process | ForEach-Object { $_.ToString() }
5. Set-Content and Add-Content stop the pipeline of data, unless you explicitly tell them to continue it with the -Passthru parameter. When you use Passthru, you can actually see the data that gets written to the file. Get-Process | Set-Content c:\pshell\part1\lesson3\processes.txt -Passthru
In previous steps, you output data to the text file, but were unable to see what was written there and had to either open the file or look at the value of the ToString() method for each process. The -Passthru parameter allows this data to be passed along the pipeline so you can actually see that data, or perhaps take further action upon the objects that were passed into it. 6. Now that you have created a few files, you can also try to read from them with another Cmdlet, Get-Content. Get-Content c:\pshell\part1\lesson3\services.txt
You can see that the data from the file is output to the screen. Each line from the file is returned as a separate object on the pipeline and each one is a string. 7. Since the Get-Service Cmdlet allows pipeline input for the Name parameter, you can then take this data and pipe it to Get-Service. Get-Content c:\pshell\part1\lesson3\services.txt | Get-Service
This command then returns the designated services specified in the file.
Task 2: Work with CSV Files In other scripting environments, reading in CSV files is a lot of work. Typically, a program that accepts any kind of file input would need its own implementation to work with CSV files. Fortunately, PowerShell includes two Cmdlets, Import-CSV and Export-CSV, which handle this for you. 1. Create a file to work with using the Set-Content and Add-Content Cmdlets. SC AC AC AC AC
AC c:\pshell\part1\lesson3\people.csv “Thomas,Andersen,Revolutionary”
Open the file in notepad to confirm there are six lines of text starting with the header and five individuals. Close the file when finished. 2. Now that you have a CSV file to work with, reading it in with PowerShell is quite simple. Import-CSV c:\pshell\part1\lesson3\people.csv
When you execute this command, it turns the data from the file into objects that get passed along the pipeline. Each object has properties that correlate with the column headers from the CSV file. You can also change the delimiter for each value or set the header information manually if you prefer using the appropriate parameters. 3. You can work with the imported data like any other pipeline data. ipcsv c:\pshell\part1\lesson3\people.csv | Sort Surname | Select GivenName
Here you are calling Import-CSV using its built-in alias. Then, you are piping the data out to Sort-Object and Select-Object. 4. Exporting data to a CSV is even easier and provides considerably more information than when using Set-Content and Add-Content. Get-Process | Export-CSV c:\pshell\part1\lesson3\processinfo.csv
Here you piped some data to the Export-CSV Cmdlet and PowerShell wrote all the properties to the file for each individual object, setting appropriate headers in the file. 5. Just like Import-CSV you can also change the headers, delimiter and some other information. It is important to note that, Export-CSV will overwrite any file that already exists and there is no built-in functionality for appending to a CSV. Get-Process | Select –First 10 | epcsv c:\pshell\part1\lesson3\processinfo.csv
Here you are limiting process selection to the first 10 objects and then sending them to Export-CSV using its built-in alias. When you open the processinfo.csv file now, you will see that it completely overwrote the old data from the previous example. 6. If you wanted display this data on the screen instead of writing it to a file, you can use the ConvertTo-CSV Cmdlet. Get-Process | Select id, name –First 10 | ConvertTo-CSV
This displays that data as text to the screen because it was passed along the pipeline rather than out to a file. You can then take that output and send it to another Cmdlet, such as Send-MailMessage to email it to yourself for later use. 7. The ConvertTo-HTML Cmdlet can be even more useful by taking data and turning it into an HTML table. It works similar to the ConvertTo-CSV Cmdlet, but gives you more functionality and converts to HTML. Get-Process | ConvertTo-HTML > c:\pshell\part1\lesson3\processinfo.html
If you open this file with Internet Explorer, you will see a basic HTML table has been created. If you are familiar with HTML, you can look at the source and you will see it has properly formatted everything in a standard TABLE element. There are additional parameters available to alter the output by specifying a CSS file to use for styling or to add data to the Head, Title, Body, and other areas of the document. Note: There are a few additional ConvertTo-* Cmdlets included with PowerShell, for more information use Get-Help ConvertTo-*
Exercise 1: PowerShell Operators Objectives In this exercise, you will:
Use the PowerShell operators to test for conditions.
Use the Where-Object Cmdlet to filter results.
Estimated Time to Complete this Lab 10 minutes
Scenario Now that you know how WMI can be accessed in Windows, you can use PowerShell 1.0 or 2.0 to get information from it. This exercise concentrates on getting only local information.
Log on to the VM environment Log on to Windows 7 Enterprise client as Contoso\Administrator with Password P@ssword
Open Windows PowerShell Session On the windows task bar locate the
icon. Click on this icon.
The PowerShell window will open.
Task 1: Using Operators on the Pipeline Using the PowerShell pipeline operators you can search for an object with specific values. For the first example, you will look at what services are running on your workstation 1. From PowerShell console, run the following command Get-service | where-object {$_.status –eq “Running”}
You will see the services that are currently running on your workstation. This is because the list of services was passed from the Get-Service Cmdlet to the Where-Object Cmdlet. Using the equals operator, the Where-Object Cmdlet only displays services whose status is equal to running. You can reverse the logic by using the not equals to operator 2. From PowerShell console, run the following command Get-service | where-object {$_.status –ne “Running”}
You will now see the services that are not running. You can also use the operators to look at other objects. Now, look for PowerShell script files in the c:\pshell directory. 3. In the PowerShell console, type the following command to search for files:
You will now see any *.ps1 files in the c:\pshell tree. You can also look for files with other properties. Look for files that are greater than a particular size. 4. Type the following into the PowerShell console to list all the files from the root of c: Get-childitem c:\
You will now see all the files that are in c:\. Next let’s look for any files that are greater than 1KB 5. Type the following command in the PowerShell console to find files greater than 1Byte Get-childitem c:\ | where-object {$_.length –gt 1}
You will now see the list of files greater than 1 byte. 6. Type the following command in the PowerShell console to find files greater than 1KB Get-childitem c:\ | where-object {$_.length –gt 1kb}
You will now see the list of files greater than 1KB. Note that this works as KB is a byte constant in PowerShell. This means that 1KB = 1024 bytes to make it easier to reference byte values in PowerShell. To extend this further, you will now use 1MB also. 7. Type the following in the PowerShell console to find files greater than 1MB Get-childitem c:\ | where-object {$_.length –gt 1mb}
You will now see any files that are greater than 1MB.
Exercise 2: The PowerShell Pipeline Objectives In this exercise, you will:
Use the PowerShell operators to test for conditions.
Use the where-object Cmdlet to filter results.
Estimated Time to Complete this Lab 10 minutes
Log on to the VM environment Log on to Windows 7 Enterprise client as Contoso\Administrator with Password P@ssword
Open Windows PowerShell Session On the windows task bar locate the
icon. Click on this icon.
The PowerShell window will open.
Task 1: Using the Pipeline Variable Using the PowerShell pipeline, you can easily get information from one Cmdlet or object and pass it to another. Using the pipeline and the pipeline variable, this can even be used to perform actions. 1. From the PowerShell console, run the following command to read a list of computers into a variable: $computers = get-content c:\pshell\part1\lesson3\labs\Computers.txt
This will assign the contents of the computers.txt file to the variable. 2. Type the following command in the PowerShell console to display the list of computers. $computers
You will now see the list of computers. Now you will use the pipeline to process this list of computers and ping each computer to test for connectivity. To do this, you will use the foreach-object Cmdlet 3. Type the following to ping each computer from the variable. $computers | foreach-object {ping $_}
You will now see the results of the ping command. Note: Each computer’s name is passed to the foreach-object one at a time using the $_ variable. The ping command uses this name to perform the ping.
This can also be used with other objects, such as files on your computer. From the PowerShell console, run the following command: Get-childitem c:\pshell
You will now see the files and folders in c:\pshell. 4. Type the following command to display the full name of each file or folder in the directory. Get-childitem C:\pshell | foreach-object {$_.fullname}
The full name for each file or folder will be displayed. Taking this a step further, you may want to filter to just directories or folders. You can do this with the property $_.psiscontainer and the Where-Object Cmdlet. The psiscontainer property is a Boolean property that is true if the object is a directory or folder. 5. Type the following command to display the full name for each folder in the directory. Get-childitem C:\pshell | where-object {$_.psiscontainer} | foreach-object {$_.fullname}
You will now see the full name displayed for any folders in c:\pshell. Expanding on this, you may want to know how many files or folders are under each subdirectory and the total size of each of these folders. First, try the command on the c:\pshell folder. 6. From PowerShell console, run the following command to display the count and total size of the files in c:\pshell. To reduce the size of the command, use aliases. Gci c:\pshell –recurse | measure-object length –sum
You will now see displayed the count of files and the sum of the files for the c:\pshell directory. Using the foreach-object Cmdlet and the pipeline do the same for each top level directory in the c:\pshell path. To do this you will combine the commands used in previous steps. Get-childitem C:\pshell | where {$_.psiscontainer} | foreach-object {$_.fullname ; gci $_.fullname –recurse | measure-object length -sum}
You will now see displayed the file count and total size of the files for each sub directory The next example uses services. 7. From the PowerShell console, run the following command to display running services: Get-service | where-object {$_.status –eq “Running”}
This can also be done with the foreach-object Cmdlet although this does require more code. This is also using an if statement. This will be covered in more detail in the scripting lesson. 8. From the PowerShell console , run the following command to display running services: Get-service | foreach-object {if ($_.status –eq “Running”) {write-host “$($_.name) : $($_.status)”}}
Running services will now be displayed. As you are using the write-host Cmdlet you can also add color to the display. 9. From the PowerShell console , run the following command to display running services with color: Get-service | foreach-object {if ($_.status –eq “Running”) {write-host “$($_.name) : $($_.status)” –foregroundcolor green}}
You will now see the running services displayed in green. Expanding on this you can also display services not running as red by modifying the if statement. 10. From the PowerShell console, run the following command to display running services with color: Get-service | foreach-object {if ($_.status –eq “Running”) {write-host “$($_.name) : $($_.status)” –foregroundcolor green} else { write-host “$($_.name) : $($_.status)” –foregroundcolor red}}
You will now see displayed the services and their status in:
Green for running
Red for services that are not running
You might notice that the names of the services are the short names. If you modify the command above to use $_.displayname instead of $_.name you will see the friendly name of the service displayed. 11. From the PowerShell console, run the following command to display running services with color using their displayname: Get-service | foreach-object {if ($_.status –eq “Running”) {write-host “$($_.displayname) : $($_.status)” –foregroundcolor green} else { write-host “$($_.displayname) : $($_.status)” –foregroundcolor red}}
You will notice that the display is not sorted and that the data is displayed as a table starting with status, name and displayname. You can change this by using the sort-object Cmdlet. 12. Type the following to sort the services by their status. Get-service | sort-object status | foreach-object {if ($_.status –eq “Running”) {write-host “$($_.displayname) : $($_.status)” –foregroundcolor green} else { write-host “$($_.displayname) : $($_.status)” –foregroundcolor red}}
You will now see the services displayed sorted by their status with color.
Note: The use of the foreach-object here is to showcase the use of the pipeline and the processing of each item passed through the pipeline. There are much better ways of performing the above activities.
Exercise 3: Filter and Sort with the Pipeline Objectives In this exercise, you will:
Use the PowerShell operators to test for conditions
Use the Where-Object Cmdlet to filter results
Estimated Time to Complete this Lab 10 minutes
Log on to the VM environment Log on to Windows 7 Enterprise client as Contoso\Administrator with Password P@ssword
Open Windows PowerShell Session On the windows task bar locate the
icon. Click on this icon.
The PowerShell window will open.
Task 1: Filtering and Sorting When using PowerShell commands to collect information, it is useful to be able to:
Filter the information based on values
Sort the information returned
The commands shown below allow you to use these features. 1. From the PowerShell console, run the following command to display running processes: Get-process
The list of running processes will now be displayed. Now, filter the display to look for specific processes. 2. From the PowerShell console, run the following command to display running processes starting with s: Get-process | where-object {$_.name –like “s*”}
The list of running processes starting with s will now be displayed. The next property deals with filtering processes based on CPU time used. 3. From the PowerShell console, run the following command to display running processes with more than one second CPU time consumed: Get-process | where-object {$_.cpu –gt 1}
The list of running processes consuming more than one second CPU time will now be displayed. These can also be combined into one command using the –or and –and operators. 4. Type the following command to filter processes Get-process | where-object {$_.name –like “s*” –or $_.cpu –gt 1}
The examples below show sorting with services. 5. From the PowerShell console, run the following command to display running services: Get-service | where-object {$_.status –eq “Running”}
The running services will now be displayed. You will notice that the display is not sorted and that the data is displayed as a table starting with status, name and displayname. You can change this by using the sort-object Cmdlet and the format-table Cmdlet. 6. From the PowerShell console, run the following command to sort the services by their status: Get-service | sort-object status
You will now see that the services are now sorted by their status. However, the output is still displayed as the default table and the stopped services are displayed first. Note: By default PowerShell will perform ascending sorts. You can change this by adding the -descending option to the command
7. From the PowerShell console, run the following command to sort the services by status in descending order: Get-service | sort-object status -descending
Now you will see the running services first and then the stopped services. The following examples deal with changing the output displayed. 8. From the PowerShell console, run the following command to sort services and change the display: Get-service | sort-object status –descending | format-table name, displayname, status
You will now see the services and their status in a table with the service name, displayname and the status. You will notice that there are some truncated names and some is space lost. This is because the format-table Cmdlet uses a default column size without looking at the data returned. You can change this by using the -autosize parameter. 9. In the PowerShell console, type the following command to sort the services and see the result of the -autosize option: Microsoft | Services
Get-service | sort-object status –descending | format-table displayname, status – autosize
You will now see that the display is much better as it does not truncate the names and does not waste any white space. However, you will notice that the services are now sorted by their status and not by their name or displayname. This can be addressed by adding name to the sort-object Cmdlet 10. In the PowerShell console, type the following command to sort services and see the result of the -autosize option: Get-service | sort-object status, name –descending | format-table status –autosize
displayname,
You will now see the services sorted by their status and name. However, note that because you used the -descending parameter the sort is descending. If you remove this parameter, the sort will be ascending. 11. In the PowerShell console, type the following command to sort services and see the result of the -autosize option: Get-service | sort-object status, name | format-table autosize
displayname, status –
You will now see the services displayed and sorted by their name. However, the status is reversed as S comes before R in the alphabet. If you use the sort-object Cmdlet normally, you have to choose if the whole sort will be ascending or descending. However, this is a way of having one property sorted in ascending order and the other in descending order. This is done via an expression hash table. 12. In the PowerShell console, type the following command to sort services using the expression hash table: get-service | sort-object -property @{Expression="Status";Descending=$true}, @{Expression="Name";Descending=$false} | format-table displayname, status – autosize
Now you will see the services displayed and sorted with the names in ascending order and the status in descending order. You may want services to use the displayname instead of the short name. You can do this by modifying the command. 13. Type the following to sort services using the expression hash table. get-service | sort-object -property @{Expression="Status";Descending=$true}, @{Expression="DisplayName";Descending=$false} | format-table displayname, status –autosize
You will now see the services displayed and sorted by displayname and then status.
Finally, you might want to save this information to a file. This can be easily done by using the redirector operator and specifying a filename. 14. Type the following to sort the services using the expression hash table: get-service | sort-object -property @{Expression="Status";Descending=$true}, @{Expression="DisplayName";Descending=$false} | format-table displayname, status –autosize > servicestatus.txt
15. Type the following to open the text file in notepad: Notepad servicestatus.txt
Lesson 4 Demonstration : Providers Introduction This lesson will introduce you to the concept of the PowerShell provider model and their use. It will introduce you to what providers are available, what data the providers contain and how to operate with the providers.
Objectives After completing this lab, you will be able to:
Understand the concept of PowerShell providers
Use PowerShell providers and drives to access various different information sources
Understand which providers are single level and multiple level
Create items in different providers
Prerequisites To complete this lab, you need:
A Windows 7 workstation logged onto with administrator credentials
Exercise 1: Provider Introduction Objectives In this exercise, you will:
Learn what Windows PowerShell providers are
List available PowerShell providers
List available PowerShell drives
Scenario The PowerShell provider model is a system built into PowerShell to allow you to access different data sources like you access data in a file system. This is achieved by a system of providers and PowerShell drives. There are several providers and drives already built into PowerShell to allow you to access various different data types. It is possible to add additional providers to PowerShell
Task 1: Log on to VM Environment Log on to Windows 7 Enterprise client as Contoso\Administrator with the password P@ssword
Task 2: Open Windows PowerShell and List the Available Providers In Windows PowerShell, there are PowerShell providers and PowerShell drives. The provider is a set of .Net codes that has been written to present the data from the source it is working with, as if it were a file system. You can also explain drive here, a drive is the way a provider presents its data, as name implies the idea is to simulate the desk drive convention? While there are a number of built-in providers installed with PowerShell, it is also possible to add additional providers to access different data. The built-in providers are:
Alias provider
Certificate provider
Environment provider
File system provider
Function provider
Registry provider
Variable provider
WS-Management provider
You can get a list of these providers by running the Cmdlet get-psprovider. 1. In the PowerShell console, type the following command to list the available providers. Get-psprovider PS C:\Users\administrator> Get-PSProvider
You will see that now you have displayed the names of the providers available, their capabilities, and the drives associated with them. While it is useful to see the PowerShell providers listed, this may not be how you would think of them in terms of accessing information from them. You are more likely to use them, or think of them as drives.
Task 3: List PowerShell Drives You can list PowerShell drives using the get-psdrive Cmdlet. 1. In the PowerShell console, type the following command to list the available drives: get-psdrive PS C:\Users\administator> Get-PSDrive Name ---Alias C cert D Env Function HKCU HKLM Variable WSMan
Now, you will see the list of PowerShell drives that are available. You will see the name of the drive that you will use to set the location, the provider that is presenting the drive, and file system details such as used and free space for the file system drives.
Task 4: Navigate Through Providers This section describes how to navigate through various providers and drives. This is simple, as they are presented as a file system. By changing to the drive for that provider, you can view the data from it. To do this, the set-location Cmdlet is used with its drive name specified, followed by a colon. For example, set-location env: would change the location to the environment drive.
1. In the PowerShell console, type the following command to set the current location to the alias drive: set-location Alias:\ PS Alias:\>
The prompt will now change to PS Alias:\>. From here, you can list the available alias using the get-childitem Cmdlet, or the dir alias. 2. In the PowerShell console, type the following command to list the available aliases: Get-childitem
The list of the current defined alias will now be displayed. To set the location back to the file system, or to another location, use the set-location Cmdlet. If you want to change the location to a particular folder in a drive, you can use the setlocation Cmdlet. In this case, you will change the location to the software folder in the registry drive HKLM:. To do this, you need to specify the drive and the path as you would with file system drives and folders. 3. In the PowerShell console, type the following command to set the location to HKLM:\software: Set-location HKLM:\software PS HKLM:\software>
The prompt will now change to PS HKLM:\software> From here, if you type get-childitem, you will see the sub-directories from this key. 4. In the PowerShell console, type the following command to list the content of the registry location: Get-childitem
To go back to a directory or move up that branch in the tree, use ... 5. In the PowerShell console, type the following command to set the location up one level in the directory tree: Set-location .. PS HKLM:\>
The prompt will now change to PS HKLM:\>. This indicates that you are now in the root of the drive.
Exercise 2: Provider Related Cmdlets and Operations Objectives In this exercise, you will:
List the various groups of provider cmdlets Work with the provider and drive Cmdlets Work with the path related Cmdlets Work with the item and property cmdlets
Scenario When using any of the PowerShell providers, there are many Cmdlets that are related to working with information accessible via the providers. Many of these Cmdlets work in the same or a similar way for each provider. To identify the Cmdlets related to the providers, break them down into three groups.
First Group: Cmdlets that work with the providers and drives
Second Group: Cmdlets for navigation and path related operations
Third group: Cmdlets for working with the items, properties and contents of the information accessible via providers
Task 1: First Group: Provider and Drive Cmdlets The Cmdlets included in this group are:
Get-psprovider
Get-psdrive
New-psdrive
Remove-psdrive
You are familiar with using get-psprovider and get-psdrive, and therefore use the newpsdrive and remove-psdrive Cmdlets. The new-psdrive Cmdlet is used to create a new instance of a drive in PowerShell and map it to an available provider and path. 1. Click Start > Run, type powershell and press Enter. 2. In the PowerShell console, type the following command to list the PSdrives: Get-psdrive
A list of available PowerShell drives appears. Notice that for the registry provider there is only the Hkey _Current_User and Hkey_Local_Machine registry hives available. You do not have access to the Hkey_Classes_Root, Hkey_Users or Hkey_Current_Config hives.
This can be fixed by creating a new PowerShell drive and setting its path to the required hive. You need to provide the drive name, specify the provider that the information is coming from, and the root path to which you want to map. 3. In the PowerShell console, type the following command to create a new PowerShell drive: new-psdrive –name HKCR –psprovider registry –root HKEY_CLASSES_ROOT
A drive called HKCR is created and it will contain the information from the hkey classes root registry hive. 4. In the PowerShell console, type the following command to list the PSdrives: Get-psdrive
The HKCR drive is listed and available. You can also create a new drive to map directly to an existing path in another drive. 5. In the PowerShell console, type the following command to create a file system provider, PowerShell drive: new-psdrive –name mydocs –psprovider filesystem –root c:\users\administrator\documents
6. In the PowerShell console, type the following command to set the location to the new drive: set-location mydocs:
You will see that the prompt has changed to PS mydocs:\> indicating that you are in the mydocs drive. 7. In the PowerShell console, type the following command to list the contents of the drive: Get-childitem
The list of files and folder available from the mydocs drive appears. Along with creating new drives, you can also remove drives. Note that this should only be used on additional drives you have created and not on inbuilt drives. 8. In the PowerShell console, type the following command to set the location back to C:. Set-location c:
9. In the PowerShell console, type the following command to remove the mydocs drive: Remove-psdrive –name mydocs
This will remove the mydocs drive from the current shell. You can confirm this with getpsdrive. 10. In the PowerShell console, type the following command to list the available PowerShell drives.
You will notice that the current drive is removed.
Task 2: Second Group: Navigation and Path Related Operation Cmdlets You are now familiar with the set-location Cmdlet. Let us now focus on the other Cmdlet that you may not be familiar. The list of navigation and path Cmdlets are:
Get-location
Pop-location
Push-location
Set-location
Join-path
Convert-path
Split-path
Resolve-path
Test-path
Let us start by understanding the test-path Cmdlet. This is very useful as it allows you to test if an object exists or not. This works with all providers and hence, along with testing if files and folders exist, you can test for registry keys, certificates, or even variables. To use it all, you need type test-path followed by the path of the object of interest.
Task 3: Test Path 1. In the PowerShell console, type the following command to test the C:\temp directory: Test-path c:\temp
The result, indicating that C:\ path is valid appears. If you test for a location that does not exist or file that does not exist the result will be false. 2. In the PowerShell console, type the following command to test the path C:\fakefolder: Test-path c:\fakefolder
The result, indicating false appears. Let us test for a file. 3. In the PowerShell console, type the following command to test for the file C:\notafile.txt: Test-path c:\notafile.txt
Again, a false is returned as this file does not exist. Let us try a file that does exist. 4. In the PowerShell console, type the following command to test the file C:\fso\servers.txt: Test-path c:\fso\servers.txt
This returns a true as the files exists. You can also use test path on UNC paths (those that can be used as a verificationexception handing mechanism while writing script that sets or gets data to UNC paths). 5. In the PowerShell console, type the following command to test the path \\syddc01\netlogon: Test-path \\syddc01\netlogon
Note: The current location must be a file system provider location or the UNC will return false regardless if it exists or not. This is also true when using set-location on UNC paths. You must first be in a file system provider location.
Let us now look at something other than the file system. You can test to see if an environment variable exists. 6. In the PowerShell console, type the following command to test the systemroot environment variable: Test-path env:\systemroot
You will see that the result is true. As you can see, test-path works with all providers in the same way.
Task 4: Get Location Get-location can be used to determine the current location. This also returns additional information that can be useful when dealing with psdrives and providers. 1. In the PowerShell console, type the following command to determine the current location: Get-location
The current path appears with additional information. 2. In the PowerShell console, type the following command to see more information about the location: Get-location | format-list *
The drive, provider, providerpath and path appears. You can extract only the path, which can then be assigned to a variable. 3. In the PowerShell console, type the following command to set $mypath to the current path: $mypath = (get-location).path
4. In the PowerShell console, type the following command to view the value of $mypath: $mypath
The variable $mypath contains only the path value.
Task 5: Push Location and Pop Location These Cmdlets work in combination. The push-location Cmdlet adds the current path to the stack, and pop-location changes to the last location added to the stack. The best way to understand this is to use them. 1. In the PowerShell console, type the following command to set the current location to the you home location: Set-location $home
2. In the PowerShell console, type the following command to add the location to the stack: Push-location
3. In the PowerShell console, type the following command to set the location to env: drive: Set-location env:
4. In the PowerShell console, type the following command to add the location to the stack: Push-location
5. In the PowerShell console, type the following command to set the location to the hklm: drive: Set-location hklm:
The current path is set to PS HKLM:\>. 6. In the PowerShell console, type the following command to change to the first location from the stack: Pop-location
The current location changes to the last location from where you ran push-location, PS Env:\>. 7. In the PowerShell console, type the following command to change to the next location from the stack: Pop-location
The prompt changes to the first location from which you ran push-location.
Task 6: Resolve Path Another useful Cmdlet is the resolve-path Cmdlet. This is used to resolve paths of objects using wildcards. 1. In the PowerShell console, type the following command to set the location to c:\. Set-location c:\
2. In the PowerShell console, type the following command to resolve the path *program*:
The path, *program* will be resolved to C:\program files. You can also use the convert-path Cmdlet to convert a PowerShell path to a PowerShell provider path that can be used with the ps-drive Cmdlet 3. In the PowerShell console, type the following command to convert the path HKLM:\software\microsoft: Convert-path –path HKLM:\software\microsoft HKEY_LOCAL_MACHINE\software\microsoft
The path is converted to HKEY_LOCAL_MACHINE\software\microsoft. This can be used as the root path when using the new-psdrive Cmdlet.
Task 7: Split Path Another useful Cmdlet when dealing with providers is the split-path Cmdlet. This can be used to easily grab the filename, or parent path for an object. The Cmdlet accepts input from the pipeline. 1. In the PowerShell console, type the following command to get only the filename: get-item c:\windows\windowsupdate.log | split-path –leaf
Only the name of the file, windowsupdate.log appears. You can also get only the parent path. 2. In the PowerShell console, type the following command to get the parent path of the file: get-item c:\windows\windowsupdate.log | split-path –parent
Task 8: Join Path This Cmdlet is used to join a parent path and a child path. This also works with wildcards. 1. In the PowerShell console, type the following command to join the path together using wildcards: join-path –path program* -childpath *microsoft* -resolve
The path is resolved to a number of directories for Microsoft products.
Task 9: Group Three: Item and Property Related Cmdlets When working with the PowerShell providers, the items contained within these providers is of most interest. To work with items in providers, there is a large set of item, item property, and content Cmdlets that are available for these operations. Interestingly, these commands
work in a similar way for all the providers. This allows a standard syntax to be used irrespective of the individual provider or item in use. The Cmdlets that work with items, item properties and content are:
Clear-item
Copy-item
Get-item
Invoke-item
Move-item
New-item
Remove-item
Rename-item
Set-item
Clear-itemproperty
Copy-itemproperty
Get-itemproperty
Invoke-itemproperty
Move-itemproperty
New-itemproperty
Remove-itemproperty
Rename-itemproperty
Set-itemproperty
Add-content
Clear-content
Get-content
Set-content
The best way to explore using these is to use them in the context of providers. You will try this in the next exercise.
Exercise 3: Single Level Providers Objectives In this exercise, you will:
Work with the alias provider Work with the environment provider Work with the function provider Work with the variable provider
Scenario When working with PowerShell providers they can be split into two major groups:
Single level providers
Multiple level providers
This exercise will focus on single level providers. Single level providers are providers that use the file system model and do not have sub folders. That is, all items of interest are effectively located in the root of the drive. The single level providers available are:
Alias provider
Environment provider
Function provider
Variable provider
Task 1: Alias Provider Let us look at the alias provider first. This provider allows access to current defined aliases. It is assessable via the alias: drive. 1. Open the PowerShell console. 2. In the PowerShell console, type the following command to set the location to the alias: Set-location alias:\
3. In the PowerShell console, type the following command to list the aliases: Get-childitem
The list of currently defined aliases appears. Notice that there are no sub folders. This is because, it is a single level provider and all items are in the root of the drive. 4. In the PowerShell console, type the following command to get the dir alias: Get-item dir
You can also create a new alias using the new-item Cmdlet. 5. In the PowerShell console, type the following command to create a new alias: new-item –name myalias –value get-help
This will create a new alias, myalias. 6. In the PowerShell console, type the following command to execute the alias: Myalias
The get-help Cmdlet executes. You can remove the alias using remote-item. 7. In the PowerShell console, type the following command to remove the alias: Remove-item myalias
8. Type myalias to view the error. Myalias
No error appears as the alias has been removed.
Task 2: Environment Provider Let us now look at environment provider. This is available via the env: drive: 1. In the PowerShell console, type the following command to set the location to env: drive: cd Env:
2. In the PowerShell console, type the following command to list the environment variables: Get-childitem
The list of environment variables available appears. You can also get a particular variable of interest. 3. In the PowerShell console, type the following command to get the systemroot variable: Get-item systemroot
The systemroot variable will now appear. You can also address using the full path to the item from any location. 4. In the PowerShell console, type the following command to set the location to C: drive: Set-location c:
5. In the PowerShell console, type the following command to get the systemroot variable with full path: get-item env:\systemroot
You can also create new environment variables using the new-item Cmdlet. However, note that these are not permanent. Variables created here will only be available to the current PowerShell console session. The variable will be deleted when the current session expires. If you need to create a new permanent variable, then you will have to create the variable in the registry, or via the control panel. There is an alternative way of getting the value of an environment variable. This is by using $env:. 6. In the PowerShell console, type the following command to get the windir value: $env:windir
Only the value of the variable appears. Another task that can be very useful is to test if a particular environment variable exists. This can be achieved using the test-path Cmdlet. 7. In the PowerShell console, type the following command to test the temp variable: test-path env:\temp
The result is true as this variable is defined.
Task 3: Function Provider The function provider is something unique to PowerShell. This allows you to list the current defined functions as an object. It is also possible to create a new function using the provider and to modify the content of a function. First, let us list the currently defined functions. Each function will have a name, using which it can be called, and a definition, which is the code executed for the function. 1. In the PowerShell console, type the following command to set the location to the function drive: set-location function:
2. In the PowerShell console, type the following command to list the contents of the drive: Get-childitem
The list of functions currently defined appears. You will notice the 26 functions, A: to Z:. These are not aliases. The reason they are not aliases is because, they are not only a reference to Cmdlet, but are set-location . An alias is only a different name of a Cmdlet, the only way the A: to Z: commands can work is through a function. Let us filter out the A: to Z: functions so that you can see the other functions. 3. In the PowerShell console, type the following command to filter the A-Z functions: get-childitem | where-object {$_.definition –notlike “set-location*”}
It is also possible to create a new function here, test if a function is defined with test-path, rename a function with rename-item, or delete a function with delete-item. The definition or code to execute a function can also be changed. Note: Ensure not to use this to change the inbuilt functions as this may cause unknown issues with PowerShell.
Task 4: Create, Rename and Redefine Functions 1. In the PowerShell console, type the following command to create a function: new-item –name myfunction –value “write-host ‘This is my function, get your own!’”
2. In the PowerShell console, type the following command to execute the function: myfunction
The text, This is my function get your own! Appears. 3. In the PowerShell console, type the following command to rename the function: rename-item myfunction –newname ourfun
4. In the PowerShell console, type the following command to execute the renamed function: ourfun
The function runs with the new name. 5. In the PowerShell console, type the following command to redefine the function: set-item ourfun –value “write-host ‘all your functions are belong to us!’”
Note that this is not the correct way to create functions. This was only to demonstrate the function provider. The correct way to define functions will be covered in module 6.
Task 5: Variable Provider The variable provider is another provider that is unique to Windows PowerShell. This provider allows you to see currently defined variables and the values of these variables. This information is available through the variable drive. 1. In the PowerShell console, type the following command to set the location to the variable drive: Set-location variable:
2. In the PowerShell console, type the following command to list the contents of the drive: get-childitem
The currently defined variables and their values appear. Note that the names of the variables do not include $. The $ sign is used to tell PowerShell that you are working with a variable. It is not actually part of the variable name.
As with all providers, you can test if a variable exists, create new variables, or rename them. These operations can also be performed using the assignment operator.
Task 6: Delete Variables The ability to delete variables is very useful. 1. In the PowerShell console, type the following command to create a variable: $deleteme = “Temp variable”
2. In the PowerShell console, type the following command to get the value of $deleteme: $deleteme
The contents of the variable appear. 3. In the PowerShell console, type the following command to delete the variable: Remove-item –path variable:\deleteme
The variable is deleted from all locations as you have specified the full path to the object. Deleting a variable can also be done using remove-variable. Both of these will result in the variable being destroyed (not set to null or blank). This is important if the information stored in the variable is critical.
Exercise 4: Multiple Level Providers Objectives In this exercise, you will:
Scenario In addition to single level providers, PowerShell also has multiple level providers. The major difference between single level providers and multiple level providers is that the multiple level providers have containers as well as items contained in them. This presents the information available via the provider as in a file system. A file system also has items, containers and sub containers. The multiple level providers available are:
Filesystem provider
Registry provider
Certificate provider
WSman provider
Task 1: Certificate Provider Let us look at the certificate provider. This provider allows access to certificate stores on the machine. It is assessable via the cert: drive. 1. Open the PowerShell console. 2. In the PowerShell console, type the following command to set the location to the cert: drive: Set-location cert:
3. In the PowerShell console, type the following command to list the contents: Get-childitem
Two containers are now available, the CurrentUser and LocalMachine containers. Let us navigate to the local machine folder. 4. In the PowerShell console, type the following command to set the location to the local machine container: Set-location cert:\localmachine
5. In the PowerShell console, type the following command to list the contents: Get-childitem
The list of certificate stores for the local machine appears. If you change your location to one of these stores, you can see the certificates in it.
6. In the PowerShell console, type the following command to set the location to the ca container: Set-location ca
7. In the PowerShell console, type the following command to list the contents: Get-childitem
The list of certificates appears. Note that thumbprint is the name of the certificate used when using the item Cmdlet. As thumbprints are not very friendly, it is highly recommended that you enable quick edit mode for PowerShell to allow you to cut and paste. Let us now look at one of the certificates in detail. 8. In the PowerShell console, type the following command to get a certificate: get-item tab
This will now get one certificate. There is more information available for the certificate. To access this, pipe this to format-list *. 9. In the PowerShell console, type the following command to display the details of the certificate: get-item tab | format-list *
The details available for the certificate appears. Another useful feature when working with the certificate provider is to search for certificates by their subject name, or part of it. 10. In the PowerShell console, type the following command to set the location to cert:\localmachine: set-location cert:\localmachine
11. In the PowerShell console, type the following command to search for certificates that have Microsoft in the subject: get-childitem –recurse | where {$_.subject –like “*Microsoft*”}
The list of certificates in the localmachine store that contain Microsoft in the subject name appears.
Task 2: Registry Provider The registry provider is one of the very useful features of PowerShell. This provider allows you easy access to the local machine and current user hives. The other hives can also be accessed by creating additional drives as demonstrated previously. The registry provider is available via the HKLM: and HKCU: drives. 1. In the PowerShell console, type the following command to change the current location to the HKLM: drive:
In the PowerShell console, type the following command to list the contents: Get-childitem
The containers accessible from the root of the HKLM drive appear. Note that the error you get is expected. This is due to the security key that is accessible only by the system account. 3. In the PowerShell console, type the following command to change the location of the autorun programs for the system key: Set-location .\software\Microsoft\powershell\1\shellids\Microsoft.PowerShell
The current location is now changed to the run key. From here, see the items you have. 4. In the PowerShell console, type the following command to list the contents: Get-childitem
There is no result. This is due to the slightly different way the registry provider works. The registry keys are represented as folders, but the registry values that you would expect to be presented as items are not. They are properties of the key. That is, instead of using the get-item, or get-childitem Cmdlets, you need to use the get-itemproperty Cmdlet to read a value. 5. In the PowerShell console, type the following command to go one level up the tree: Set-location ..
6. In the PowerShell console, type the following command to get the properties of the run key: Get-itemproperty –path .\Microsoft.Powershell
The registry values appear. You can isolate this down to just the value. 7. In the PowerShell console, type the following command to extract only the value: (get-itemproperty –path .\Microsoft.Powershell –name ` ExecutionPolicy).ExecutionPolicy
Only the value for Execution Policy appears, but this requires you knowing the name of the value you want. There is an easier way to do this using a method call on the registry key. 8. In the PowerShell console, type the following command to assign the registry key to a variable: $regkey = Get-item Microsoft.PowerShell
9. In the PowerShell console, type the following command to get the value using a method call: $regkey.getvalue(‘ExecutionPolicy’)
You can also create registry keys using the new-item Cmdlet. 10. In the PowerShell console, type the following command to change the location to the software key: Set-location hklm:\software
11. In the PowerShell console, type the following command to create a registry key under the software key: New-item mysoftware
This will create the new registry key under the software key. 12. In the PowerShell console, type the following command to display the subkey of the software key: Get-childitem
The software key appears. Now, create a registry value. The path needs to be the registry key under which you will create the value and you need to specify the name and value of the registry property. 13. In the PowerShell console, type the following command to create a registry value: New-itemproperty –path mysoftware –name myregvalue –value “This is my registry value”
This will create the registry value as a string. You can also create dwords or other data types by adding the –type parameter. 14. In the PowerShell console, type the following command to create a registry dword: New-itemproperty –path mysoftware –name mydword –value “0x23” –type dword
15. In the PowerShell console, type the following command to check our registry values created: Get-itemproperty mysoftware
Task 3: WSman Provider The WSman provider allows access to the Windows Remote Management service configuration. This simplifies the configuration of the winRM service, and allows this to be checked. This is available via the WSman drive. As this is a multiple level provider, there are many settings available. 1. In an elevated PowerShell console, type the following command to change to the WSman drive: Set-location wsman:\
2. In the PowerShell console, type the following command to display the contents of this drive: Get-childitem
The root of the drive contains one container, the localhost container. It is inside this container that you find the configuration for various WinRM settings and components. 3. In the PowerShell console, type the following command to list the contents of the container: Get-childitem localhost | format-table -autosize
Some settings, and additional containers that contain further settings appear. 4. In the PowerShell console, type the following command to change to the client container: Set-location localhost\client
5. In the PowerShell console, type the following command to display the contents of the client folder: Get-childitem
You can modify the values of these settings using the set-item Cmdlet. This will be covered later in the PowerShell remoting lesson.
Task 4: File System Provider The final multiple level provider that will be discussed in this module is the file system provider. When working with the file system provider in Powershell, you will notice some difference in the working when compared to what you may be used to. This is due to the object-oriented nature of PowerShell. The file system provider will make any file system drive available by its drive letter. If you have multiple drives on your system, PowerShell will present these. If you only have one drive available, then you will only see one drive. 1. In the PowerShell console, type the following command to list the file system drives available: Get-psdrive | where-object {$_.provider –like “*filesystem*”}
The file system drives available appear. 2. In the PowerShell console, type the following command to set the current location to the root of c drive: Set-location c:\
3. In the PowerShell console, type the following command to display the contents: Get-childitem
The contents of the C drive appear. This will include both files and folders. You can filter the view such that you will only see files, or folders. To do this, use a property called, psiscontainer. 4. In the PowerShell console, type the following command to display only folders: Get-childitem | where-object {$_.psiscontainer}
Only the folders appear. Note that you can use the psisontainer property without an operator as it is a Boolean value. 5. In the PowerShell console, type the following command to display only the files: Get-childitem | where-object {!$_.psiscontainer}
Only the files appear. The ! sign represents a NOT operator and reverses the logic, so look for objects where psiscontainer is false. 6. In the PowerShell console, type the following command to display the properties available for files and folders: Get-childitem | get-member –membertype *property*
The properties for both system.io.directory and system.io.fileinfo types appear. These are .Net framework types that represent the files and folders on the system. Note the properties with names that start with PS and are of type NoteProperty. These are additional properties that are added to the display by PowerShell. This is because you are accessing the items via the provider. These properties have useful information.
The PSChildname property contains the name of the item
The PSDrive property contains the PowerShell drive the item is from
The PSIscontainer property contains the container status of the item
The PSParentPath property contains the PowerShell parent path of the object. This includes the provider reference
The PSPath property contains the full PowerShell path of the object. This includes the provider reference
The PSProvider property contains the PowerShell provider that the object is from
These properties are added to any object accessed through a PowerShell provider. 7. In the PowerShell console, type the following command to create a new directory: New-item –name myfolder –type directory
This will create a new directory. The type parameter is required. As the file system can contain both files and directories, you need to define the object you are creating. 8. In the PowerShell console, type the following command to change the current location to C:\myfolder:
9. In the PowerShell console, type the following command to create a file: New-item –name machinenames.txt –type file
This will create a file. Note that the file length is current 0. This is a completely empty file. It is also possible to create a file with data in it at the same time. 10. In the PowerShell console, type the following command to create a file with contents: New-item –name machinenames.txt –type file –value “Machinenames”
This will create the file and populate it with the data from the value parameter. 11. In the PowerShell console, type the following command to read the data from the file: Get-content machinenames.txt
The contents of the file appear. 12. In the PowerShell console, type the following command to add contents to the file: Add-content machinenames.txt –value “syddc01”
13. In the PowerShell console, type the following command to add more data to the file: Add-content machinenames.txt –value “w7client”
14. In the PowerShell console, type the following command to read the contents of the file again: Get-content machinenames.txt Machinenamessyddc01 w7client
Notice that machinenames and syddc01 are on the same line. This is because, when the file was created, the value specified was written to the file as it was. This did not include a new line character. When the add-content commands were used, they added the new line character. This should be taken care of. 15. In the PowerShell console, type the following commands to set the contents of the file: Set-content machinenames.txt –value “Myservers” add-content machinenames.txt –value “syddc01” add-content machinenames.txt –value “w7client”
16. In the PowerShell console, type the following command to get the file contents: Get-content machinenames.txt PS C:\myfolder> Get-Content .\machinenames.txt Myservers syddc01 w7client
The set-content Cmdlet will overwrite the file. This Cmdlet also adds a new line after setting the contents. The add-content Cmdlet also does the same.
17. In the PowerShell console, type the following command to rename the file: Rename-item machinenames.txt –newname servernames.txt
18. In the PowerShell console, type the following command to list the files: Get-childitem
The machinenames.txt file no longer exists and is now called servernames.txt. 19. In the PowerShell console, type the following command to delete the file: Remove-item servernames.txt
This will delete the file. You can also delete directories. 20. In the PowerShell console, type the following command to create a new subdirectory: New-item –name mysub1 –type directory
21. In the PowerShell console, type the following command to create a file in the subdirectory: New-item –path .\mysub1 –name deleteme.txt –value “delete this file” –type file
22. In the PowerShell console, type the following command to create a second subfolder: New-item –name mysub2 –type directory
23. In the PowerShell console, type the following command to list the files and folders recursively: Get-childitem –recurse PS C:\myfolder> Get-childitem -recurse Directory: C:\myfolder Mode ---d---d----a---a---
Length Name ------ ---mysub1 mysub2 0 myfile.txt 29 servernames.txt
Directory: C:\myfolder\mysub1 Mode ----a---
LastWriteTime ------------11/09/2011 8:21 PM
Length Name ------ ---16 deleteme.txt
You now have an empty subdirectory and one with a file in it. 24. In the PowerShell console, type the following command to delete the mysub2 directory: Remove-item mysub2
The command runs without a return. 25. In the PowerShell console, type the following command to delete the mysub1 directory:
You will be prompted to confirm that you want to delete the directory and all child items, because the directory contained a file. If you want to perform this action without the prompt you can specify the –recuse option. Use this carefully, as you will not be prompted to confirm the action.
Lesson 4 Hands-On : Providers Introduction This is the self-paced section for the providers’ lesson. In this lab, you will use various providers to perform operations.
Objectives After completing this lab, you will be able to:
Work with the environment provider to create and test variables
Work with the certificate provider to search for certificates by their properties
Export the details of a certificate as a text file
Work with the registry provider to create registry keys
Work with the registry provider to create registry values
Edit registry values to filter out unwanted values
Prerequisites To complete this lab, you need:
A Windows 7 workstation logged onto with administrator credentials
Exercise 1: Work with Environment Provider Objectives In this lab, you will:
Set location to the environment provider and create new variables
Export variables to a file and import variables
Task 1: Log On to VM Environment Log on to Windows 7 Enterprise client as Contoso\Administrator with the password P@ssword
Task 2: Open Windows PowerShell On the Windows taskbar, click
.
The PowerShell console opens.
Task 3: Set Location to Environment Provider and Create New Variables 1. In the PowerShell console, type the following command to set the location to the Environment provider drive: Set-location env:\
Now, create multiple variables. This will only be available for the current session. You can make a permanent environment variable by editing the registry. 2. In the PowerShell console, type the following command to create an environment variable: New-item –name AssetTag –value “12345ABCD”
3. In the Powershell console, type the following command to create another environment variable: New-item –name SOE_Version –value “WIN7_X86_CONTOSO_R1.2”
4. In the PowerShell console, type the following command to prompt for input: $Department = read-host “Please enter your department”
5. Type a department name of your choice. The $department variable will contain the input you have entered. 6. In the PowerShell console, type the following command to create an environment variable with the PowerShell variable data: New-item –name department –value $department
The $department variable is expanded, and then the value for the department environment variable is assigned.
7. In the PowerShell console, type the following command to create a variable from other variables: New-item –name CurrentUser –value “$env:userdomain\$env:username”
The variables are again expanded and a \ is added between them. 8. In the PowerShell console, type the following command to list the variables created: Get-childitem
The new variables that you have created are visible.
Task 4: Export Variables to a File 1. In the PowerShell console, type the following command to export the variables to a CSV file: Get-childitem | export-csv –notypeinformation ` c:\Pshell\part1\lesson4\labs\variables.csv
This will export the current variables to a csv file. This file will contain all the properties of the items, including their PS properties as well their name and values. The – notypeinformation option is used to prevent PowerShell from including type information in the file. This information is only useful when you are going to import information from a csv and keep the type mapping. 2. In the PowerShell console, type the following command to view the csv file in Notepad: Notepad c:\pshell\part1\lesson4\labs\variables.csv
You will see that there is a lot of information in the file.
Task 5: Open a New PowerShell Console and Import File This new PowerShell console will not contain the new variables you have previously created. You can check this by listing the current variables. 1. In the new PowerShell console, type the following command to set the location to the Environment drive: Set-location env:\
2. In the new PowerShell console, type the following command to list the variables: Get-childitem
The variables AssetTag, SOE_Version, department and current user no longer exist. Now, import the variable details you exported to the csv file. $myenv = import-csv c:\pshell\part1\lesson4\labs\variables.csv
3. In the new PowerShell console, type the following command to view the imported data: $myenv
The default view is a list and all the properties for each variable appear. You can change this to display a similar view to the original variables. 4. In the new PowerShell console, type the following command to reformat the date: $myenv | format-table name, value
The name and value are now displayed in a table format. 5. In the new PowerShell console, type the following command to test the variables imported: $myenv | foreach {write-host "Variable: $($_.name) exists $(test-path env:\$($_.name))"}
A list of the variables and a true or false result if the variable current exists appear. The command above uses the foreach Cmdlet that passes each item from the variable one at a time to the script block section. The script block section is the {} part. This is a block of code that will be run for each item. The script block uses the write-host Cmdlet and the pipeline variable the $_ to display the name of each variable. It also tests if the variable exists using the test-path Cmdlet. Sub expressions can also be used with the $( ). This allows you to extract the value of the name and value properties. You can create any variables that do not exist. 6. In the new PowerShell console, type the following command to create any variables that do not exist: $myenv | foreach {if (!$(test-path env:\$($_.name))) {new-item –path env:\$($_.name) –value $($_.value)}}
This command uses the if statement and the result of the test-path Cmdlet to find any variables that does not exist. If they do not exist, the new-item Cmdlet is executed to create the variable and the value. 7. In the new PowerShell console, type the following command to list the variables: Get-childitem
The variables AssetTag, SOE_Version, department and currentuser now exist. 8. In the new PowerShell console, type the following command to test the variables imported: $myenv | foreach {write-host "Variable: $($_.name) exists $(test-path env:\$($_.name))"}
All variables listed exist as true. 9. In the console type the following to return to the c: Set-location c:
Exercise 2: Work with the Certificate Provider Task 1: Log On to VM Environment Log on to Windows 7 Enterprise client as Contoso\Administrator with the password P@ssword
Task 2: Open Windows PowerShell 1. On the Windows taskbar, click
.
The PowerShell console opens.
Task 3: Set Location to Certificate Provider 1. In the PowerShell console, type the following command to set the location to the Certificate provider drive: Set-location cert:\
2. In the PowerShell console, type the following command to change to the local machine certificate container: Set-location localmachine
The prompt will now be located in the localmachine certificate store. From here, you can search for certificates given their properties. First, search for certificates that have expired. To do this, you need to create a value in datetime format to compare it to the value of the certificates. 3. In the PowerShell console, type the following command to create a datetime value: $today = get-date
4. In the PowerShell console, type the following command to search for the certificates that have expired: Get-childitem –recurse | where-object {$_.notafter –lt $today}
The certificates that have an expiry, or notafter property value less than today’s date appear. You can also add them to a variable and filter out any containers that may be included. 5. In the PowerShell console, type the following command to add the expired certificates to a variable and filter out any containers: $expiredcerts = gci -recurse | where {$_.notafter -lt $today -and $_.psiscontainer -ne $true}
$expiredcerts will now contain the expired certificates. You can examine one of the certificates using array addressing to look at that certificate.
6. In the PowerShell console, type the following command to examine one certificate from the variable: $expiredcerts[0] | format-list *
The details for the first certificate in the variable appear. You can look at other certificates using different numbers in between the [ ]. You can also look at valid certificates using a different logic. 7. In the PowerShell console, type the following command to search for current valid certificates: $validcerts = gci -recurse | where {$_.notafter -gt $today -and $_.notbefore -lt $today}
The valid certificates are assigned to the validcerts variables. It is also possible to check if the certificate is valid with the method call verify. 8. In the PowerShell console, type the following command to display the certificate subject name: $validcerts[0].subject
9. In the PowerShell console, type the following command to check if the certificate is valid: $validcerts[0].verify()
You will see that the result is true, as this certificate is valid. You can test one of the expired certificates that is not valid. 10. In the PowerShell console, type the following command to display the certificate subject name: $validcerts[0].subject
11. In the PowerShell console, type the following command to check if the certificate is valid: $expiredcerts[0].verify()
You will see that the certificate is not valid. Let us get some more details on the expired certificate 12. In the PowerShell console, type the following command to get the certificate name: $expiredcerts[0].GetNameInfo(“simplename”,$true)
13. In the PowerShell console, type the following command to get the type of the certificate: $expiredcerts[0].getformat()
14. In the PowerShell console, type the following command to certificate issuing authority: $expiredcerts[0].getissuername()
Exercise 3: Working with the Registry provider Task 1: Log On to VM Environment Log on to Windows 7 Enterprise client as Contoso\Administrator with the password P@ssword
Task 2: Open Windows PowerShell On the Windows taskbar, click
.
The PowerShell console opens.
Task 3: Set Location to Registry Provider 1. In the PowerShell console, type the following command to set the location to the environment provider drive: Set-location hklm:\software
2. Now, type the following command to create a registry key: New-item –name contoso
3. In the PowerShell console, type the following command to assign the registry key to a variable for later reference: $mykey = get-item hklm:\software\contoso
4. In the PowerShell console, type the following command to create an array: $departments = “Sales”, “Marketing”, “IT_Support”, “Silly_Walks”, “Legal”, “HR”, ”Administration”
5. Type the following command to create a multi string registry value: New-itemproperty –path hklm:\software\contoso –name Departments –value ` $departments –type multistring
6. Type the following command to check the value of the registry key property: $mykey.getvalue(‘departments’)
The values of the departments registry property appear. It has been decided that the department of Silly Walks is no longer needed at Contoso. As such, you need to remove it from the list of departments and keep all other departments. You can do this with two simple steps using PowerShell. 7. In the PowerShell console, type the following command to create a new list of departments: $newdepartments = $mykey.getvalue(‘departments’) | where-object {$_ -notlike ‘Silly_walks’}
This command will assign everything to the variable $newdepartments except the value you filter with the where-object code, Silly_walks. Microsoft | Services
8. In the PowerShell console, type the following command to check the contents of $newdepartments: $newdepartments
The names, Sales, Marketing, IT_Support, Legal, HR, Administration appear but not Silly_walks. Note that all the work is done by the where-object Cmdlet using the – notlike operator. 9. In the PowerShell console, type the following command to set the value of the property to the new list: Set-itemproperty –path hklm:\software\contoso –name departments –value ` $newdepartments
Now, verify the value of the department property. 10. In the PowerShell console, type the following command to check the registry property: $mykey.getvalue(‘departments’)
11. In the PowerShell console type the following to return to the c: set-location c:
Lesson 5 Demonstration : Variables and Type Fundamentals Introduction In this module, we will learn about the different variables available in Windows PowerShell. Along with the understanding of the usage of the variables, we will also look at the different types of variables available in PowerShell. Each of them is used for a specific purpose. Effective use of variables, arrays, and hash tables is a key for an administrator to prepare scripts for daily administrative tasks.
Objectives After completing this lab, you will be able to learn how to:
Create various types of variables and manipulate with the values
Understand Arrays and Hash Tables and how to use them
Understand how variables, arrays, and hash tables could be helpful for building basic scripts
Prerequisites To complete this lab, you need:
Windows 2008 and Windows 7 workstation logged onto with administrator credentials
Exercise 1: Working with Variables Objectives In this exercise, you will:
Understand the usage of variables
Learn about the techniques to create variables, modify value and use of variables
Scenario The Windows PowerShell variable provider allows you to create, add, and delete variables. First, let us understand what a variable is. A variable, as the name suggests, is something whose value can vary. Variables are primarily used for two reasons: 1. To hold some value or data in memory 2. To hold the output, which is a result of an expression Variables can store information about different types such as string, integer, and Boolean. The various types will be discussed later in this lesson. In the exercise below, the following operations will be demonstrated using variables:
Variable assignment
Variable expansion
Variable related Cmdlets
Task 1: Log on to VM Environment Log on to Windows 7 Enterprise client as Contoso\Administrator with the password P@ssword
Task 2: Variable Assignment In PowerShell, you can create a variable name by adding a $ sign before the name of the variable. 1. To create a variable of name, Result, add $ sign before it and use an equals sign to assign it a value. Thus, the name of the variable will be $Results. PS C:\> $Results = “We won!”
You can use the New-Variable built in Cmdlet as well, to create a new variable. When using the New-Variable Cmdlet, you do not need to add a $ sign before the variable name. 2. To create a variable using the New-Variable Cmdlet, type the following command: PS C:\> New-Variable Results2 –value “We won again!”
3. Write an expression that performs a compare operation and stores the result of the operation inside a variable. The expression will be evaluated to either True or False. The expression would be as follows: PS C:\> $a = 5 PS C:\> $b = 6
Creating a new variable and assigning the value of 5. Creating a new variable and assigning the value of 6.
4. Create a third variable to store the value of the expression. Let the name of that variable be $c. PS C:\> $c = ($b -gt $a) PS C:\>$c
-gt in Windows PowerShell is a comparison operator for "Greater Than". In this case, the expression evaluates to true. The result will be stored in the variable $c. Note the “Type” of the variable, $c. PS C:\> $c.GetType() IsPublic IsSerial Name -------- -------- ---True True Boolean
BaseType -------System.ValueType
It is Boolean since we have a value of True of False. PS C:\> $a.gettype() IsPublic IsSerial Name -------- -------- ---True True Int32
BaseType -------System.ValueType
It is an Integer since we have an integer value.
A "Type" is what defines the kind of information or value that can be stored in a variable. Note: A variable name can also have spaces in between however; remember to enclose the variable name inside a curly brace.
For example, ${New Variable}.
Automatic Variables Although you can choose a name of your choice for a variable, there are certain special variables that are predefined in PowerShell.
The following are some of the automatic variables that are predefined in Windows PowerShell. These variable names are reserved. $Args
Stores values of parameters passed to a function
$Error
Stores information about the error object when an error has occurred during any script execution
$PsHome
Home directory where the PowerShell is installed
$Home
Home directory of the user
$True
Check for Boolean Value of True
$False
Check for Boolean Value of False
Note: For a complete list of automatic variable, refer the Online Help.
Variable Expansion Quotes have a special meaning when used with variables. Consider the following example: PS C:\> $First = “Hello” PS C:\> $Statement1 = “$First World” PS C:\> $Statement1 Hello World
The output stored in the variable $Stament1 will be Hello World. This is because, when you use double quotes, Windows PowerShell will expand the variable name with its value. In the example, you can see that the output is Hello World. This is because, Windows PowerShell substitutes $First with its value, which is Hello. On the other hand, if you assign the values within single quotes, Windows PowerShell takes that as a literal value and does not substitute the value. Consider the following example, PS C:\> $First = ”Hello” PS C:\> $Statement1 = ‘$First World’ PS C:\> $Statement1 $First World
You can see in this example that the value of $First is not inserted into $Statement1 We learnt about variables in this section however, there might be situations where we need to constant value. We can define a constant using Set-Variable Cmdlet.
Variable Related Cmdlets To work with variables using the variable provider, the following Cmdlets are built in Windows PowerShell. Get-Variable
Gets the variables in the current console
New-Variable
Creates a new variable
Set-Variable
Sets the value of a variable
Remove-Variable
Deletes a variable and its value
Clear-Variable
Deletes the value of a variable
Task 3: Expressions Windows PowerShell executes the command depending on the command input. If a native Windows command was typed, PowerShell will execute the command in a way similar to how Windows would execute in a CMD command shell. Similarly, if you write a mathematical or a comparison expression in the PowerShell console, it will process accordingly. 1. Type the following command in the PowerShell console: PS C:\> ipconfig.exe Windows IP Configuration Connection-specific DNS IPv4 Address. . . . . . Subnet Mask . . . . . . Default Gateway . . . .
Suffix . . . . . . . . . . . .
. . . .
: : 192.168.1.1 : 255.255.255.0 : 0.0.0.0
Wireless LAN adapter Wireless Network Connection: Media State . . . . . . . . . . . : Media disconnected Connection-specific DNS Suffix . :contoso.com Ethernet adapter Local Area Connection: Media State . . . . . . . . . . . : Media disconnected Connection-specific DNS Suffix . :contoso.com Tunnel adapter isatap.corp.microsoft.com: Media State . . . . . . . . . . . : Media disconnected Connection-specific DNS Suffix . :
This behavior of PowerShell is also known as Argument mode processing. 2. Using a PowerShell cmdlet, we can see similar behavior with arguments by running the following command in the console: PS C:\> Write-Host 6*5 6*5
Because PowerShell is in argument parsing mode, it interprets “6*5” as an expression and displays it to the console host. 3. Now, type the following command in the PowerShell console:
After processing Write-Host, PowerShell encounters the “(“ which causes it to switch to expression mode parsing. In this expression mode, it actually evaluates the mathematical expression of 6*5 and the output is 30. 4. The dollar sign is another one of the common characters that can cause PowerShell to enter expression mode parsing. $int = 5 + 5 $int
You can see now that instead of treating the line of text as a command, PowerShell sees the dollar sign and knows that this is an expression to be evaluated, one which assigns the value of 5+5 into the variable “int”. On the second line, the evaluation is simply to retrieve the variable, which causes PowerShell to output that variable to the pipeline. 5. You can also force PowerShell into argument mode on a given expression. Enter the following commands: $cmd = “get-command” $cmd
We are simply using expression parsing mode and assigning a string into a variable. Note that the “get-command” cmdlet is not actually executing, this is merely a text assignment. 6. Using the ampersand, also known as the “call operator”, we can now force the previous expression to be evaluated in argument mode instead. &$cmd
This time the output is the same as if you directly executed the “get-command” cmdlet. 7. Script blocks are another example where PowerShell changes between parsing modes. Execute the following code: { get-command –verb get }
This simply defines a script block, but does not execute it. 8. You can execute the code by putting the call operator in front of it: & {get-command -Verb get}
Exercise 2: Basic Variable Types in PowerShell Objectives In this exercise, you will:
Understand the type fundamentals in Windows PowerShell
Learn the use of specific types of variables
Scenario In PowerShell, you can create and delete objects for various purposes. In those objects, you can store data for performing some operations. Before you can store data, you may define the kind of data to be stored in that object. The kind of information that can be stored in an object is defined by its "Type". Let us look at a few examples to understand this in detail. In the exercise that follows, the use of different “Types” will be demonstrated.
Number types
String types
Expandable strings
Literal strings
Here-strings
Other types
Task 1: Log on to VM Environment Log on to the Windows 7 client as Contoso\Administrator. In Windows PowerShell, some common "Types" are defined for Integer, Strings, and Boolean.
Task 2: Number Type To understand numeric type, consider the following example: To launch PowerShell, click
on the taskbar.
1. Create a variable named, a and assign the value 9. PS C:\> $a = 9
2. Here, you create a new variable and store a value of 9 in it. Now, let us see the type of variable. 3. To find the type of variable, use the GetType() method. PS C:\>$a.gettype() IsPublic IsSerial Name -------- -------- ----
4. Note the name, Int32. To hold the value, 9, you created an instance of "Type" of Int32 object. An Int32 object represents a 32-bit integer. 5. Change the value of the variable from an integer to a floating point. PS C:\> $a = 4.5 PS C:\> $a.gettype() IsPublic IsSerial Name -------- -------- ---True True Double
BaseType -------System.ValueType
Note the Name property. It changed from Int32 to Double. An instance of "Type" of Double object represents a floating-point number. 6. Assign a larger value to the same variable. PS C:\> $a =8000000000 PS C:\> $a.gettype() IsPublic IsSerial Name -------- -------- ---True True Int64
BaseType -------System.ValueType
Note that the Name property now shows Int64. Let us take a few more examples. This time rather than assigning a math value let us take a list of all services on the computer. 7. In the PowerShell console, type the following command: PS C:\> $a = Get-Service PS C:\> $a.gettype() IsPublic IsSerial Name -------- -------- ---True True Object[]
BaseType -------System.ValueType
8. Similarly, store True or False in a Boolean object Type. PS C:\> $a = 1 PS C:\> $b = 2 PS C:\> $c = ($a -lt $b) PS C:\> $c True PS C:\> $c.gettype() IsPublic IsSerial Name -------- -------- ---True True Boolean
In the example above, you created two variables initially, assigned values to it and then did a compare operation. To store the result of the compare operation, you created a third variable and you can see that the "Type" is Boolean.
Task 3: String Type PowerShell allows storing strings in variables. A string is a collection of characters. In the previous section, we looked at the different number types. In this section, you will get familiar with string types and their use.
Expandable Strings String expansion is a very important functionality in Windows PowerShell. Consider an example to understand this behavior. In the following example, you will understand the significance of quotes with variables: 1. Create a new variable name and assign the string value Bob in double quotes. 2. Use the same variable with a statement enclosed in double quotes. PS C:\> $name = "Bob" PS C:\> "Hi $name, Welcome to the PowerShell workshop" Hi Bob, Welcome to the PowerShell workshop
You can notice that when the string was in double quotes, you substituted the variable $name with its value. This behavior is called string expansion. 3. Now, try the same using single quotes. When the statement is enclosed with a Single quote, we see that the variable is not substituted with its value. PS C:\> 'Hi $name, Welcome to the PowerShell workshop' Hi $name, Welcome to the PowerShell workshop
Literal Strings 4. To assign a string value to the variable, type the following command: PS C:\>
$a = "Welcome to the world of PowerShell!"
PS C:\> $a Welcome to the world of PowerShell! PS C:\> $a.GetType() IsPubli IsSerial Name -------- -------- ---True True String
5. To store a string value in a variable, use either a single quote or a double quote. PS C:\> $a = "Welcome to the world of PowerShell!" PS C:\> $a Welcome to the world of PowerShell!
PS C:\> $a = 'Welcome to the world of PowerShell!' PS C:\> $a Welcome to the world of PowerShell!
In this case, both yield the same results for a simple assignment.
Here Strings A Here string is used to place a sequence of strings the way they are, without any additional formatting. Consider an example. 6. Create another variable and assign the string value exactly as shown below. PS C:\> $NewString = "Hello and how are you?" PS C:\> $NewString Hello and how are you?
You can see the output without any additional formatting. Consider another example to display the following statement as an output: "Good Morning!, how are you?", would you like to have a cup of tea or coffee? 7. Create a new variable named ComplicatedString, and assign the string value as shown below and observe the behavior. PS C:\> $ComplicatedString = ""Good Morning!, how are you?", would you like to have a cup of tea or coffee?" Unexpected token 'Good' in expression or statement. At line:1 char:28 + $ComplicatedString = ""Good <<<< Morning!, how are you?", would you like to have a cup of tea or coffee?" + CategoryInfo : ParserError: (Good:String) [], ParentContainsErrorRecordException + FullyQualifiedErrorId : UnexpectedToken PS C:\> $ComplicatedString = ""Good Morning!, how are you?", would you like to have a cup of tea or coffee?"" Unexpected token 'Good' in expression or statement. At line:1 char:28 + $ComplicatedString = ""Good <<<< Morning!, how are you?", would you like to have a cup of tea or coffee?"" + CategoryInfo : ParserError: (Good:String) [], ParentContainsErrorRecordException
+ FullyQualifiedErrorId : UnexpectedToken PS C:\> $ComplicatedString = "Good`Morning!, how are you?", would you like to have a cup of tea or coffee?" Missing expression after ','. At line:1 char:52 + $ComplicatedString = "Good`Morning!, how are you?", <<<< would you like to have a cup of tea or coffee?" + CategoryInfo : ParserError: (,:String) [], ParentContainsErrorRecordException + FullyQualifiedErrorId : MissingExpressionAfterToken
You can make this work by adding a few correct quotes and braces, but it is time consuming. In such a case, Here string is useful. 8. In PowerShell, type the following command: PS C:\> $ComplicatedString = @” >> Good Morning!How are you?, would you like to have a cup of tea or a coffee? >> "@ >> PS C:\> $ComplicatedString Good Morning!How are you?, would you like to have a cup of tea or a coffee? PS C:\>
The string included between the start and the end of the Here string is displayed as it is. Windows PowerShell does not parse any quotes or braces inside a Here string. Hence, the string is stored without any errors.
Other Types You looked at some of the basic primitive number and string types. However, Windows PowerShell has more types available in it. The following table from TechNet shows the various types. Data Type Alias
Data type Aliases and type qualification. The above table contains what are called data type aliases. These are used as a shortcut instead of typing the whole .NET framework types when in PowerShell. There are many more data type aliases available. However, the table above does cover most of the common alias that you will encounter. It is also possible to create your own data type aliases but this will not be covered here. A common use of the datatype aliases is to use them to qualify either data as a certain type or to type constrain a variable. Normally in powershell you are not too concerned with the types of a variable or data. This is due to the type adaption system that powershell uses which converts the type when needed. However, there are some circumstances that might require the types to be qualified. To do this with PowerShell, you use the data type aliases.
Data qualification Using the data type aliases on the right hand side of the assignment operator allows for the data to be qualified, or cast as a specific type. 1. Type the following in the PowerShell console to create a variable $a = 77
2. Type the following to check the type $a.gettype()
You will see that you have an int32 3. Type the following create a variable $a = “77”
4. Type the following to check the type $a.gettype()
You will see that you have a string. 5. Type the following to qualify the data as a int32 $a = [int] “77”
6. Type the following to check the type $a.gettype()
You will see that you have an int32. This is due to qualifying, or casting the data as a number. However, the variable can still be set to a string or any other type as the variable has not been type constrained. 7. Type the following to set $a to a string $a = “See I can still be a string”
8. Type the following to check the type $a.gettype()
You will see that you have a string.
Type constraining As well as being able to qualify data as a specific type, it is possible to also constrain a variable to be a specific type. This is done by using the data type alias on the left hand side of the assignment operator. This means that the variable will only be able to contain data of that specific type. If you try to assign a different type to that variable it will fail.
1. Type the following in the PowerShell console to create a variable $a = 77
2. Type the following to check the type $a.gettype()
You will see that you have an int32 3. Type the following create a type constrained variable [int]$a = “77”
4. Type the following to check the type $a.gettype()
You will see that you have an int3 even though a string of “77” was assigned . 5. Type the following to assigned a string to the variable $a = “this will not work”
You will now see that you get an error from PowerShell. This is because the string “this will not work” cannot be converted to an int32. This is because we can only store numbers in the variable due to the type constraint. 6. Type the following to assign another number to the variable $a=42
This will work as 42 is an int32. Is it possible to change the constraint on the variable to another type. 7. Type the following to constrain $a to a string [string]$a = “See I can now be a string”
8. Type the following to check the type $a.gettype()
You will see that you have a string. If you try to now assign a number this will now fail. 9. Type the following to assign an int32 to $a $a = 42
You will now see that this succeeds because converting an integer to a string is allowed. 10. You can also effectively remove the constraint from a variable by making it of type object. Type the following to qualify the variable as type object [object]$a = 42
11. Type the following to check the type $a.gettype()
You will see that you have an int32. 12. Type the following to assigned a string to the variable $a = “this works now”
13. Type the following to check the type $a.gettype()
Exercise 3: Working with Arrays Objectives In this exercise, you will:
Understand the use of an Array in Windows PowerShell.
Learn how to create, modify values in an Array and add Elements in an Array.
Scenario In the previous exercise, you learnt about the use of variables and the type fundamentals in PowerShell. Let us continue to explore the functionality and use of arrays in this module. An array object contains a collection of elements of the same type. For example, an array of integers or string. While evaluating any expression, the output can be either a single object or a collection of objects. To store the result of all services on a computer, you create an array. The following is an illustration of a simple one-dimensional array.
Each block is referred to as an element, which stores values. Arrays can be one-dimensional or multi-dimensional. The following is an illustration of a two-dimensional array.
Task 1: Log on to VM Environment Log on to the Windows 7 client as Contoso\Administrator.
Task 2: Create Arrays 1. To create an array object, directly assign the element values delimited with a comma to the array variable. PS C:\> $NewArray = “a”,”b”,”c” PS C:\> $NewArray.Gettype() IsPublic IsSerial Name -------- -------- ---True True Object[]
BaseType -------System.Array
2. We can also create an empty array using the @ operator. PS C:\>$NewArray = @()
Let us look at creating an array of numbers. 3. In the PowerShell console, type the following command to create an array. Notice the values of elements. PS C:\> $Numbers = @(1,2,3,4,5) PS C:\> $Numbers 1 2 3 4 5 PS C:\> $Numbers.gettype() IsPublic -------True
IsSerial ---------True
Name ------------Object[]
BaseType -----------System.Array
4. Use the Get-Service Cmdlet to get a list of all services running on a computer and store the output in $service as an array. PS C:\> $service = get-service PS C:\> $service Status -----Stopped Stopped Stopped Running Stopped Stopped Running Running
Name ---AeLookupSvc ALG AppIDSvc Appinfo AppMgmt aspnet_state AudioEndpointBu... AudioSrv
DisplayName ----------Application Experience Application Layer Gateway Service Application Identity Application Information Application Management ASP.NET State Service Windows Audio Endpoint Builder Windows AudioPS C:\> $Numbers.gettype()
IsPublic IsSerial Name -------- -------- ---True True Object[]
BaseType -------System.Array
PS C:\>
Task 3: Add Elements to Arrays In the example that follows, you will see how you can add elements in an array. Create a variable named $numbers, which will store numbers from 1 to 10. 1. In the PowerShell console, type the following command: #Create an array and assign values to elements. PS C:\> $numbers = 1,2,3,4,5,6,7,8,9,10 PS C:\> $numbers.count 10
The count property of array tells us how many elements are present in an Array. 2. To add an element and assign a value, type the following command: PS C:\> $numbers += 11 PS C:\> $numbers 1 2 3 4 5 6 7 8 9 10 11 PS C:\> $numbers += 12 PS C:\> $numbers.Count 12 PS C:\>PS C:\>
The count of the array has increased since you added two elements.
Task 4: Array Addressing In an array, the first element is referred as index 0. 1
2
3
4
5
6
7
8
9
10
The array holds values for 10 elements. To find the value in the first element, which is 1, refer the index number 0. In the following example, a variable named $numbers stores the numbers 1 to 10. Take a count of how many elements you have in the array. Modify the value of the first element in the array. #Create an array and assign values to elements. PS C:\> $numbers = @(1,2,3,4,5,6,7,8,9,10) PS C:\> $numbers.count 10
# Changing the value of 1st element from 1 to 11. PS C:\> $numbers[0]= 11 PS C:\> $numbers 11 2 3 4 5 6
Exercise 4: Working with Hash Tables Objectives In this exercise, you will:
Understand the techniques of creating and accessing different values in Hash table
Learn how Hash tables can be used while building scripts
Scenario Hash table is a kind of array where we can store the values in a key-value pair. Hash tables are used when we need to store information in the form of a dictionary array and then access the value of an element using a corresponding label name. The following is an example of an array representing the ID of employees within an organization: Dave
183
Roy
478
Alice
671
In this module, the following operations for hash tables will be discussed.
Creating hash tables
Adding to hash tables
Hash table addressing
Task 1: Log on to VM Environment Log on to the Windows 7 client as Contoso\Administrator.
Task 2: Create Hash Tables Creating a hash table is similar to creating an array except one difference. In an array, elements are inside parenthesis (), and in hash tables, elements are inside braces {}. $Numbers = @{"A"=1; "B"=2; "C"=3} $Numbers.GetType()
Let us look at a hash table, which contains employee name and ID. 1. In the PowerShell console, type the following command to create a hash table. $a = @{"Dave"=123; "Roy"=478; "Alice"=671} $a Name ---Dave
Task 3: Add Entries to Hash Tables In the below example, we are creating a Hash table which will store the information about the computer type. Note: The order of your keys/value pairs may show up sorted differently than the exercises below, this is normal behavior because hash tables are not ordered.
1. In the PowerShell console, type the following command to create a hash table: $ComputerType = @{"Type1"="Desktop";"Type2"="Server";"Type3"="Laptop"} $ComputerType Name ---Type1 Type2 Type3
Value ----Desktop Server Laptop
Add a New Entry to Hash Table 2. In the PowerShell console, type the following command to add a new entry to a hash table: $ComputerType[“Type4”] =”TabletPC” $ComputerType Name ---Type1 Type2 Type3 Type4
Value ----Desktop Server Laptop TabletPC
3. In the PowerShell console, type the following command to add a new entry to a hash table: $computertype.Type5=”Slate” Name ---Type1 Type2 Type3 Type4 Type5
Value ----Desktop Server Laptop TabletPC Slate
4. In the PowerShell console, type the following command to change the value of an existing key: $ComputerType[“Type4”] =”Netbook” $ComputerType
Task 4: Hash Table Addressing Addressing hash tables is different from addressing an array. Although, both have elements, when you address a specific value of a key in a hash table, you address using the Key Name. 1. Consider the following hash table: $a = @{"Dave"=123; "Roy"=478; "Alice"=671} $a Name ---Dave Roy Alice
Value ----183 478 671
2. From the example, to find the ID of Dave, address it as follows: $a.Dave 183 $a.Roy 478 $a.Alice 671
According to the definition, this table contains a Key-Value pair. Every key will have an associated value to it and you can address the value by using a dot reference to its key.
Exercise 5: Working with Console Input-Output Objectives In this exercise, you will:
Understand Windows PowerShell console Input-Output
Understand various methods of interacting with PowerShell console for Input-Output operations
Scenario Like every other scripting and programming environment, Windows PowerShell offers variety of methods from where an input can be passed for a command to be executed as well as to display the results. The Windows PowerShell console host is where the command you type is by default, used to take the user input and to display the output. First, let us look at the input mechanisms in Windows PowerShell. The following is a sample script that prompts a user to enter a valid path. After the path is entered, scan the directory to get only the files inside that directory.
Console Input ============ Script code: ============ $Path = Read-Host "Please enter a valid path" $obj = @(dir $path) $objcount = $obj.count for ($i = 0; $i -lt $objcount; $i++) { if ($($obj[$i].Length)) { $obj[$i].Name } }
In this code, a Cmdlet, Read-Host that prompts a user for an input is used. Based on the input, the script will be processed further. While using the Cmdlet is one way of passing an Input to PowerShell, the PowerShell console Host also takes a user input and processes the commands.
Console Output You might have noticed that whenever you type a command in the PowerShell console, you see the output in the command window.
This is because of the Out-Default Cmdlet that is executed after every Cmdlet. Therefore, in the PowerShell console, whenever you execute a command, Get-Service, PowerShell is actually executing the command Get-Service | Out-Default. Out-Default will send the output to Out-Host and then the output is displayed on the host window. Additional options to specify output to a specific object: Out-File
Will send an output to a file
Out-Printer
Will send an output to a printer
Out-Host
Default output window
Out-Grid
Display the output in a Grid view
Write-Host
Writes customized output to a host
Write-Output
Sends the specified objects to the next command in the pipeline. If the command is the last command in the pipeline, the objects are displayed in the console.
Tee-Object
Microsoft | Services
Saves command output in a file or variable, and displays it in the console
Exercise 6: Working with Files Objectives In this exercise, you will:
Understand management of files and folders using Windows PowerShell
Explore various built-in Cmdlets used for File Management
Scenario Windows PowerShell adds functionalities to manage files and folders on a local as well as a remote computer. Administrators can perform a variety of operations for files and folder management such as create, delete, rename, copy, and move.
Task 1: Log on to VM Environment Log on to the Windows 7 client as Contoso\Administrator. 1. Run a simple command to verify the existence if a file. Use the Test-Path Cmdlet. test-path C:\Windows\system32 True
You can see that the result is True as you know that the folder does exist. 2. Type the following command to verify the existence of another folder: test-path C:\Windows\system32\anotherwindows False
As expected, the result is false as there is no folder with the name anotherwindows. 3. Type the following command to see how you can implement the simple test as an important check in script: $Fileinfo = Test-Path C:\Windows\System32\drivers\ntfs.sys if ($Fileinfo -eq "True") {Write-Host "File Exists"} File Exists
When this is executed, observe the output. You can also add another condition to write File Does not exist, if it does not. PowerShell also allows copying or moving files from one location to another. In the following example, you will copy a file from C:\ to D:\ using the following command. Copy-Item C:\pshell\part1\lesson5\setup.log C:\pshell\part1\lesson5\newsetup.log
4. Run the following Cmdlet to move the file from one location to another. Move-Item C:\pshell\part1\lesson5\setup.log c:\temp -force
You can also delete, or rename files using the Delete-Item, or Rename-Item Cmdlets.
Alternatively, you can use these methods on a file or directory object to copy, move, or delete. $file = Get-Item C:\pshell\part1\lesson5\setup.log $file | gm –membertype method TypeName: System.IO.FileInfo Name ---AppendText CopyTo Create CreateObjRef CreateText Decrypt Delete Encrypt Equals GetAccessControl GetHashCode GetLifetimeService GetObjectData GetType InitializeLifetimeService MoveTo Open OpenRead OpenText OpenWrite Refresh Replace SetAccessControl ToString
The CopyTo method copies the file to the specified location.
Task 2: Read from Files 1. Use the get-Content Cmdlet to read the content from a file as follows: Get-Content C:\pshell\part1\lesson5\setup.log [InstallShield Silent] Version=v7.00 File=Log File [ResponseResult] ResultCode=0 [Application] Name=Integrated Camera Driver Installer Package Ver.1.1.0.42 Version=1.1.0.42 Company=RICOH Lang=0009 VersionInfo
2. You can also clear the contents of file using the Clear-Content Cmdlet as follows:
Task 3: Write to Files In the following examples, you will look at the Cmdlets you can use to write something to a file. You will use the Set-Content and Out-File Cmdlets. 1. In the PowerShell console, type the below command to write the word Hello to a file in drive D and the filename is test1.txt. Set-Content C:\pshell\part1\lesson5\test1.txt "Hello"
2. Run the Get-Content Cmdlet, to verify the content of the text file. Get-Content C:\pshell\part1\lesson5\test1.txt Hello
3. You may want to write entire output of a Cmdlet to a file. For example, the status of all the services running on a computer, list of all the running process etc. 4. This can be achieved using the Out-File Cmdlet as follows: Get-Service | Where-Object {$_.status -eq "Running"} | Out-File ` -FilePath "C:\pshell\part1\lesson5\Services.txt" Get-Content C:\pshell\part1\lesson5\Services.txt Status -----Running Running Running Running Running Running Running Running Running Running
DisplayName ----------Application Information Windows Audio Endpoint Builder Windows Audio BitLocker Drive Encryption Service Base Filtering Engine Background Intelligent Transfer Ser... Bluetooth Support Service Bluetooth Service SMS Agent Host Certificate Propagation
Task 4: Work with Other File Formats PowerShell allows saving data in different formats such as HTML, CSV, and XML. You can use the Cmdlets on many occasions to read the content from a .txt file and get the output in an HTML format to present it as a report. 1. Let us look at an example to create a report of all the running services on computer. Get-Service | Where-Object {$_.status -eq "Running"} | ConvertTo-Html Name, ` Status | Set-Content C:\pshell\part1\lesson5\Services.html invoke-item C:\pshell\part1\lesson5\Services.html
The following is the output when the file is converted to HTML. Name
The first Cmdlet gets a list of all the services of the system. Then we pipe that output and take a look at the status property of each object to match if it is "Running". Then, we use the ConvertTo-HTML Cmdlet to covert the output. The end part, Set-Content Cmdlet writes the content to the file. PowerShell also adds the flexibility to export the content to a CSV file. We can use the Export-CSV Cmdlet to export the output to a CSV file 2. Consider another example. Get-Service | Where-Object {$_.status -eq "Running"} | Export-CSV ` C:\pshell\part1\lesson5\Services.csv notepad c:\pshell\part1\lesson5\services.csv
The code above exports the output to a CSV file and loads it. 3. One last example deals with saving content in a much more rich format: XML. Get-Service | Where-Object {$_.status -eq "Running"} | Export-clixml ` C:\pshell\part1\lesson5\Services.xml Invoke-item C:\pshell\part1\lesson5\Services.xml
Exercise 7: PowerShell Error Object Objectives In this exercise, you will:
Understand the use of PowerShell error object
Explore different variables available to store the error information
Understand how PowerShell error object can be used for effective debugging
Scenario It is common for an administrator, writing a script to encounter an error during the execution. PowerShell provides a rich set of inbuilt objects and mechanisms to understand the error details and then take the necessary corrective actions.
Task 1: Log on to VM Environment Log on to the Windows 7 client as Contoso\Administrator. 1. Launch the PowerShell console and type the following command: Get-Process invisibleapp.exe Get-Process : Cannot find a process with the name "invisibleapp.exe". Verify the process name and call the Cmdlet again At line:1 char:12 + Get-Process <<<< invisibleapp.exe + CategoryInfo : ObjectNotFound: (invisibleapp.exe:String) [GetProcess], ProcessCommandException + FullyQualifiedErrorId : NoProcessFoundForGivenName,Microsoft.PowerShell.Commands.GetProcessCommand
The error on the console host can be viewed. In Windows PowerShell, there is an Error object of type, System.Management.Automation.ErrorRecord. The automatic variable $Error contains information about the most recent errors. $error Get-Process : Cannot find a process with the name "invisibleapp.exe". Verify the process name and call the Cmdlet again At line:1 char:12 + Get-Process <<<< invisibleapp.exe + CategoryInfo : ObjectNotFound: (invisibleapp.exe:String) [GetProcess], ProcessCommandException + FullyQualifiedErrorId : NoProcessFoundForGivenName,Microsoft.PowerShell.Commands.GetProcessCommand
Like other array objects, you can take a count of the errors currently stored in the error object. $error.count 1
Since this is implemented as an array, use the traditional method to refer to index 0 for the value of the first element. Below you can see some examples of what errors may look like, but your environment will likely be very different. $error[0] Get-Process: Cannot find a process with the name "invisibleapp.exe". Verify the process name and call the Cmdlet again At line:1 char:12 + Get-Process <<<< invisibleapp.exe + CategoryInfo : ObjectNotFound: (invisibleapp.exe:String) [GetProcess], ProcessCommandException + FullyQualifiedErrorId : NoProcessFoundForGivenName,Microsoft.PowerShell.Commands.GetProcessCommand $error[1] The term 'lastexistcode' is not recognized as the name of a Cmdlet, function, script file, or operable program. Check t he spelling of the name, or if a path was included, verify that the path is correct and try again. At line:1 char:14 + lastexistcode <<<< + CategoryInfo : ObjectNotFound: (lastexistcode:String) [], CommandNotFoundException + FullyQualifiedErrorId : CommandNotFoundException $error[2] Get-Item : A positional parameter cannot be found that accepts argument 'Exit'. At line:1 char:9 + Get-Item <<<< c:\doentexist.txt Exit 123 + CategoryInfo : InvalidArgument: (:) [Get-Item], ParameterBindingException + FullyQualifiedErrorId : PositionalParameterNotFound,Microsoft.PowerShell.Commands.GetItemCommand $error[3] Get-Item : Cannot find path 'C:\doentexist.txt' because it does not exist. At line:1 char:9 + Get-Item <<<< c:\doentexist.txt + CategoryInfo : ObjectNotFound: (C:\doentexist.txt:String) [GetItem], ItemNotFoundException + FullyQualifiedErrorId : PathNotFound,Microsoft.PowerShell.Commands.GetItemCommand
By default, you can store up to 256 errors in the $Error object. This is implemented using the $MaximumErrorCount variable. However, the value for the variable in the example can be changed. It is also possible to clear the error variable. You can do this by using the clear method on the error variable. This is a good idea to use when scripting with PowerShell. This enables you to focus only on the errors that your scripts has generated, not errors that might have been produced outside of the current script.
Type the following to clear the variable $error.clear()
Error Variable Parameter Windows PowerShell provides an option of recording the error information for a specific Cmdlet using the $ErrorVariable parameter. get-process -id 112 -ErrorVariable Errprocess Errprocess Get-Process : Cannot find a process with the process identifier 112. At line:1 char:12 + get-process <<<< -id 112 -ErrorVariable Errprocess + CategoryInfo : ObjectNotFound: (112:Int32) [Get-Process], ProcessCommandException + FullyQualifiedErrorId : NoProcessFoundForGivenId,Microsoft.PowerShell.Commands.GetProcessCommand
Task 2: Determine Last Exit Code The last exit code of the script or the Windows based program can be determined using the $LastExitCode automatic variable. To find the result of the executed script or command, use the $? Variable. To understand this further, consider two more variables. 1. Open the PowerShell Command and ping a reachable IP address. In this case, ping the loopback IP. ping 127.0.0.1 Pinging 127.0.0.1 with 32 bytes of data: Reply from 127.0.0.1: bytes=32 time=3ms TTL=64 Reply from 127.0.0.1: bytes=32 time<1ms TTL=64 Reply from 127.0.0.1: bytes=32 time<1ms TTL=64 Reply from 127.0.0.1: bytes=32 time<1ms TTL=64 Ping statistics for 127.0.0.1: Packets: Sent = 4, Received = 4, Lost = 0 (0% loss), Approximate round trip times in milli-seconds: Minimum = 0ms, Maximum = 3ms, Average = 0ms $LastExitCode 0
Here, the result of execution of the code was successful and hence, the last exit code is 0. There can be a user defined exit code. 2. Type the following command to ping a non-existent IP address and observe the error. ping 127.0.0.900 Ping request could not find host 127.0.0.900. Please check the name and try again. $LastExitCode 1
Task 3: Check Execution Status To know the execution status of the last operation, use the "$?" variable. get-process qwertyuiop get-process : Cannot find a process with the name "qwertyuiop". Verify the process name and call the cmdlet again. At line:1 char:1 + get-process qwertyuiop + ~~~~~~~~~~~~~~~~~~~~~~ + CategoryInfo : ObjectNotFound: (qwertyuiop:String) [Get-Process], ProcessCommandException + FullyQualifiedErrorId : NoProcessFoundForGivenName,Microsoft.PowerShell.Commands.GetProcessCommand $? False
Windows PowerShell allows specifying how it may respond to non-terminating errors. The preference is defined in the $ErrorActionPreference variable. $ErrorActionPreference Continue
Currently, the preference is set to Continue and will therefore display the error and continue with the script execution. The other possible values for this variable are: SilentlyContinue When the preference is set to SilentlyContinue, the flow of execution of script continues even when an error is encountered and it does not display the error on the host. 1. In the powershell console type the following $erroractionpreference = "SilentlyContinue”
2. Type the following command which will fail, but will not display any output. Get-item fakefile
Inquire Prompts for a user action when an error is encountered. Stop Halts the script execution.
Cmdlet –erroraction parameter In addition to the error active preference variable, there is an error action parameter available on cmdlets. This overrides the global error action preference for that specific command. This is useful if you have a single command that may generate an error and you wish to handle that specific command separately.
3. In the powershell console type the following $erroractionpreference = "Continue”
4. Type the following command which will fail Get-item fakefile
This above command will generate an error and display this. 5. Type the following to overwrite the error action for the specific command Get-item fakefile –erroraction “silentlycontinue”
You will note that the above does not display an error as per the previous command did.
Exercise 1: Working with Variables Objectives In this exercise, you will:
Create variables for use with Numeric and string operations
Look at the different properties of the variable
Task 1: Log on the VM Environment Log on to Windows 7 Enterprise client as Contoso\Administrator with the password P@ssword
Task 2: Open Windows PowerShell Session On the Windows taskbar, click
. The PowerShell console opens.
Task 3: Work with Variables 1. type following command: PS C:\> $x = 10
2. On the next line, type the following command: PS C:\> $y = 45
You created two variables and assigned a value to it. 3. Now perform an addition operation. PS C:\> $z = $x + $y
4. The output of this operation will be stored in a third variable, $z. 5. In the PowerShell console, type the following commands to view the output stored in $z and to find the type. PS C:\> $z 55 PS C:\> $z.GetType()
6. Identify the type of the object. 7. Create another variable $a and assign a string value to it. PS C:\> $a = "Good Morning,”
8. Create another variable $b and assign another string value. PS C:\> $b = "How are you?”
9. Create a third variable $c and add variables $a and $b. PS C:\> $c = $a + $b
10. In the PowerShell console, type the following command to view the output stored in $c: PS C:\> $c Good Morning, How are you?
11. Verify the results. This addition operation is also called String Concatenation. You will now use the variable to store a collection of objects. 12. In the PowerShell console, type the following command to get a list of all running processes on a system: PS C:\> $Process = Get-Process
13. On the next line, type $Process to view the output. PS C:\> $Process
Close all instances of notepad except one. If notepad is not running, start it.
14. On the next line, type the following command to find an instance of a running process and store the output in $ProcessNotepad variable: PS C:\> $ProcessNotepad = Get-Process Notepad
15. Type $ProcessNotepad in the command to view the output. PS C:\> $ProcessNotepad
16. Type the following commands to view the properties of the object stored in $ProcessNotepad: PS PS PS PS
Exercise 2: Working with Arrays Objectives In this exercise, you will:
Learn how to create arrays and manipulate the values of elements in an array.
Task 1: Log on to VM environment Log on to Windows 7 Enterprise client as Contoso\Administrator with the password P@ssword
Task 2: Open Windows PowerShell Session On the Windows taskbar, click
. The PowerShell console opens.
Task 3: Create an Array and modify the elements 1. In the PowerShell console, type the following command to create an array with three elements: PS C:\> $Currency = @("Dollar","Rupee", "Pound")
2. In the PowerShell console, type the following command to access the first element in the array, and view the output: PS C:\> $Currency[0]
3. In the PowerShell console, type the following command to access the last element in the array, and view the output: PS C:\> $Currency[-1]
4. In the PowerShell console, type the following command to add a new element to an existing array: PS C:\> $Currency += "Yen"
5. Type $Currency to verify the addition of element in array. 6. In the PowerShell console, type the following command to change the value of an existing element: PS C:\> $Currency[2] = "Peso"
7. Type $Currency to verify the change operation in the array. $Currency
8. In the PowerShell console, type the following command to store the first 10 application event logs: PS C:\> $logs = get-eventlog application | Select-Object -First 10
9. In the PowerShell console, type the following command to view the properties and methods for the first object of an array: PS C:\> $logs[0] | Get-Member
10. In the PowerShell console, type the following command to identify the machine name on which the event was generated: PS C:\> $logs[0].MachineName
11. In the PowerShell console, type the following command to find the description: PS C:\> $logs[0].Message
Task 4: Combine Two Arrays 1. In the PowerShell console, type the following command to create two arrays: PS C:\> $Array1 = @(1,2,3,4,5) PS C:\> $Array2 = @("Six", "Seven", "Eight", "Nine", "Ten")
Make sure that quotes are added for string values or else you may encounter certain errors. 2. In the PowerShell console, type the following command. PS C:\> $ArrayCombined = $Array1 + $Array2
3. Display the results of $ArrayCombined $ArrayCombined
Task 5: Create an Array of a Specific Type 1. In the PowerShell console, type the following command to create an array of integer type: PS C:\> [int[]]$Numbers = @(1,2,3,4,5)
2. Assign a string value to it and notice the behavior. PS C:\> $Numbers += "Word"
Exercise 3: Work with Hash Tables Objectives In this exercise, you will:
Learn how to create a hash table, access and modify the values
Task 1: Log on to VM Environment Log on to Windows 7 Enterprise client as Contoso\Administrator with the password P@ssword
Task 2: Open Windows PowerShell Session On the Windows taskbar, click
. The PowerShell console opens.
Task 3: Create a Hash Table and work with values. 1. In the PowerShell console, type the following command to create a new hash table: PS C:\>$NewHashTable = @{"Company"="Microsoft Corporation";"Street"="One Microsoft Way";"City"="Redmond";"State"="WA"}
2. Type $NewHashTable to view the Key-Value pair. 3. In the PowerShell console, type the following command to find the value for Company: PS C:\> $NewHashTable.Company
4. In the PowerShell console, type the following command to add a new key-value to this table: PS C:\> $NewHashTable["Telephone"] = "98052-7329"
You added a new key. However, the value added is incorrect. The value is not the telephone number, but the PIN. 5. In the PowerShell console, type the following command to modify and assign the correct value: PS C:\> $NewHashTable["Telephone"] = "425-882-8080"
6. Type $NewHashTable to verify the correction. 7. In the PowerShell console, type the following command to view the output of the hash table in a table format: PS C:\> $NewHashTable | FT *
8. In the PowerShell console, type the following command to view the output in a list format: PS C:\> $NewHashTable | FL *
You can create a hash table to store a specific type of values (integer, string) by prefixing its type before the name. Use the same method for creating arrays of specific type. 9. In the PowerShell console, type the following command to sort the output by value: PS C:\> $NewHashTable.GetEnumerator() | Sort Value
10. In the PowerShell console, type the following command to sort the output by name: PS C:\> $NewHashTable.GetEnumerator() | Sort Name
Exercise 4: Work with Hash Tables and Calculated Object Properties Objectives In this exercise, you will:
Learn how to use calculated object properties with hash tables
Task 1: Log on to VM Environment Log on to Windows 7 Enterprise client as Contoso\Administrator with the password P@ssword
Task 2: Open Windows PowerShell Session On the Windows taskbar, click
. The PowerShell console opens.
Task 3: Working with Hash Tables and Calculated Object properties. 1. Launch two or three instances of Notepad with an interval of 30 seconds for each instance. 2. In the PowerShell console, type the following command to create a hash table and format the output using the Format-Table Cmdlet: PS C:\> PS C:\> get-process notepad | Format-table Handles ------65 65 65
NPM(K) -----7 7 7
PM(K) ----2572 2568 2568
WS(K) VM(M) ----- ----7324 79 7068 79 7192 79
CPU(s) -----0.09 0.06 0.09
Id -1704 6896 7988
ProcessName ----------notepad notepad notepad
You can see the key and an associated value to it. The properties displayed about are present by default for a PowerShell object. You can restrict the output to one or two properties. 3. In the PowerShell console, type the following command to view ProcessName and CPU for instances of Notepad: PS C:\> get-process notepad | Format-table Name,CPU -AutoSize Name ---notepad notepad notepad notepad
CPU --0.3744024 0.0936006 0.0780005 0.0936006
4. If you want to find for how long each instance of Notepad is running, you can use a calculated object property to find out the values. 5. In the PowerShell console, type the following command:
In the first part of the script, you can notice that to create a calculated property a hash table is created using @{}. Later, the expression is specified to provide the value for TotalRunningTime property. Create a hash table and a calculated object property using the Select-Object Cmdlet. 6. In the PowerShell console, type the following command: PS C:\> get-process
The list of all running processes on the computer appears. 7. On the next line, type the following command: PS C:\> get-process | select-object -property ProcessName
The property, ProcessName for all processes on the computer appears. 8. In the PowerShell console, type the following command to use a calculated property: PS C:\> get-process | select-object -property ProcessName,@{Name="Start Day"; Expression = {$_.StartTime.DayOfWeek}}
You can find on which day the processes were started. This completes this exercise and lab.
Lesson 6 Demonstration : Scripting Introduction The focus for this lesson is scripting in PowerShell. PowerShell is both a command-line shell and a scripting language. It was designed specifically for the IT Administrator and contains a very rich arrangement of language constructs such as variable assignments, arrays, iterations, and flow control. This lesson describes these concepts and introduces the use of functions and profiles.
Objectives The objectives for this lesson are:
To define what constitutes a script and basic script elements such as:
Comments (#)
White space
Line terminators (newline, semicolon)
Script arguments
To explain how to execute a script and the security features that are applicable to running scripts, including:
The execution policy and group policy objects
Script signing
To explain PowerShell language iteration statements such as:
Do While and Do Until
For and ForEach
While
To explain PowerShell language flow control statements, such as:
Break and continue
Return and Exit
To explain other statements that are commonly used in scripts, including:
Labeled statements
If
Switch
To describe functions and their basic features, including:
Exercise 1: Scripting in PowerShell Objectives In this lesson, you will:
Create a basic PowerShell script
Describe different ways to run scripts
Set the execution policy and understand the different configurations
Describe script arguments
Scenario A script is a collection of commands that are stored in a file with a .ps1 filename extension. Scripts are not explicitly named within the file; instead, they take their name from the file name. Restricted (default)
Permits individual commands but will not run scripts.
All Signed
Scripts can run. Requires that all scripts be signed by a trusted publisher, including scripts that you write on the local computer Prompts you before running scripts from publishers that you have not yet classified as trusted or untrusted Risks running unsigned scripts from sources other than the Internet and signed, but malicious, scripts Note: Type get-help about_signing at a PowerShell command prompt to display insyntaxion related to signing scripts.
Remote-Signed
Scripts can run. Requires a digital signature from a trusted publisher on scripts that are downloaded from the internet (including email and instant messaging programs)
Unrestricted
Unsigned scripts can run. Warns the user before running scripts from the internet
Bypass
Nothing is blocked and there are no warnings or prompts. This execution policy is designed for configurations in which a Windows PowerShell script is built into a larger application or for configurations in which Windows PowerShell is the foundation for a program that has its own security model
Undefined
There is no execution policy set in the current scope If the execution policy in all scopes is Undefined, the effective execution policy is Restricted, which is the default execution policy
A script contains a sequence of Unicode characters that is translated by PowerShell into a series of tokens that can be interpreted as syntax in PowerShell. Scripts are useful to store a series of commands that are likely to be used again in the future.
Task 1: Log on to the VM environment Log on to Windows 7 Enterprise client as Contoso\Administrator with the password, P@ssword
Task 2: Open Elevated Windows PowerShell Session 1. On the Windows taskbar, right-click . 2. Select Run As Administrator. 3. Click Yes if a User Account Control prompt appears. The PowerShell window opens.
Task 3: Set Execution Policy 1. In the PowerShell console, type the following command to display the current execution policies in effect on this machine: get-executionpolicy -list
PowerShell execution policies define the conditions under which PowerShell runs scripts. The following policies can be configured: 2. In the PowerShell console, type the following command: set-executionpolicy unrestricted
3. Type Y to confirm the change and press Enter. Y
This sets the execution policy for LocalMachine to unrestricted. Execution policies can be set for:
LocalMachine
CurrentUser
Process (the current session)
A group policy object can also be used to set execution policy for computers and users. Note: Execution policies for the local computer and current user are stored in the registry and therefore there is no need to set execution policies in a PowerShell profile.
Task 4: Create a Basic PowerShell Script Let us look at creating a basic PowerShell script using notepad and then add comments. 1. On the command line, type notepad.exe and press Enter to open Notepad. Notepad.exe
2. Start your new script file by annotating the script using comments. PowerShell treats comments as white space. White space is only used to separate tokens in PowerShell; other than that, it is ignored for all purposes.
There are three types of comments that can be used: Single-Line-Comment This type of comment begins with the hash character (i.e. #) and ends with one of the line or statement termination characters i.e. new-line (enter key/Carriage return Unicode U+000D) or semicolon (;). Delimited-Comment This type of comment begins with the character pair <# and ends with #> and is useful to indicate either part of a line or multiple lines as annotation. Requires-Comment This is a special type of comment that can be used to specify the minimum version of PowerShell that is required to execute a script. The syntax is: #requires -Version N[.n] Where, N = major version and n = minor version. N is a required value while n is an optional value. A script can contain multiple requires-comments. A requires-comment must be the first item on a line and cannot reside within a function or cmdlet. 3. Type #requires -version 3 on the first line of the file to test the requires-comment functionality. #requires -version 3
4. Click File > Save As, and type “c:\Pshell\part1\Lesson6\Lesson_6_exercise_1.ps1” in the File name text box. Leave the file open as we will be making changes shortly. 5. Type C:\Pshell\part1\Lesson6\Lesson_6_exercise_1.ps1 at the command prompt to run the script. The following error message appears because as you are not using PowerShell version 3.0. C:\Pshell\part1\Lesson6\lesson_6_exercise_1.ps1
The script 'Lesson_6_exercise_1.ps1' cannot be run because it contained a "#requires" statement at line 1 for Windows PowerShell version 3.0. The version required by the script does not match the currently running version of Windows PowerShell version 2.0. At line:1 char:15 + .\ Lesson_6_exercise_1.ps1 <<<< + CategoryInfo : ResourceUnavailable: (lesson_6_exercise_1:String) [], ScriptRequiresException + FullyQualifiedErrorId : ScriptRequiresUnmatchedPSVersion
6. Change the comment in the script file from #requires -version 3 to #requires -version 2. #requires -version 2
8. Retry the command by typing C:\Pshell\part1\Lesson6\lesson_6_exercise_1.ps1 at the command prompt. C:\Pshell\part1\Lesson6\lesson_6_exercise_1.ps1
Note that the script now runs without error. 9. Type a delimited-comment starting with <# followed by some text on multiple lines and close the delimited-comment using #>. The script file should now resemble the following: #requires -Version 2 <# Author: Date: #> 10. On the File menu, click Save to save the file. 11. Type C:\Pshell\part1\Lesson6\lesson_6_exercise_1.ps1 in the command prompt to run the script and verify that it runs successfully. C:\Pshell\part1\Lesson6\lesson_6_exercise_1.ps1
Task 5: Run PowerShell Scripts 1. Scripts can be run by typing the full path and file name as you did in the previous procedure. That is, C:\Pshell\part1\Lesson6\lesson_6_exercise_1.ps1. 2. Refer to the table below for valid and invalid ways to run a script from within the PowerShell command shell. Works Fails Full path and script file name e.g.
Double click a .ps1 file.
c:\Pshell\part1\Lesson6\ lesson_6_exercise_1. ps1 Note: The command will fail if the path or script file name contains any spaces. Enclosing the command in either single (i.e. ‘’) or double quotes (i.e. “”) will also fail. This is because the quotes turn the command into a string. The way to run a script file that has spaces in its path or filename is to use single or double quotes and prepend an ampersand (i.e. the PowerShell Call Operator) e.g. & “c:\my documents\myscript.ps1” Typing the script file name with a prepended dot backslash (i.e., .\) e.g. PS c:\users\administrator\documents> .\myscript.p s1
Typing the script file name when the present working directory is the directory where the script resides e.g. PS c:\users\administrator\documents> myscript.ps1 Note: There is an exception to this rule: PowerShell will run the myscript.ps1 if the c:\users\administrator\documents folder is
listed in the Windows PATH environment variable OR if a myscript.ps1 file is found in ANY path that is listed in the Windows PATH environment variable. The following command can be used to display the content of the Windows PATH environment variable: $path = $env:path; $path.split(";")
3. Tips for successfully executing PowerShell script files from within the PowerShell command shell: A. Ensure that the execution policy allows the running of scripts. B. Use the .\ notation to run a script that resides in the present working directory. C. Store scripts in a folder that is listed in the Windows PATH environment variable and run from any folder using the script name only. The following command can be used to add a path to the Windows PATH environment variable: $env:path = $env:path + ";c:\myscripts"
Note: This addition to the Windows PATH environment variable will be lost when the PowerShell session is closed. The command can be added to a PowerShell Profile (this topic is covered later in this course) if required to persist between sessions. D. Specify the full path and filename for the script file. E. If the path and/or the script filename contain any spaces, enclose the command with single or double quotes and prepend with an ampersand. 4. PowerShell scripts can also be run external to the PowerShell command shell. A common practical use for this is creating scheduled tasks that run PowerShell scripts. 5. Click Start > Run and type the following command: powershell.exe -noexit -file c:\Pshell\part1\Lesson6\lesson_6_exercise_1.ps1 ` -executionpolicy bypass
Note: The ExecutionPolicy Bypass setting allows scripts to run regardless of whether the current execution policy allows the running of scripts or not.
Task 6: Scripts and Accepting Arguments Scripts can accept arguments using the $args automatic variable. $args is a one-dimensional array that contains all arguments that are specified along with the script name when running a script. Consider the following command as an example: PS c:\users\administrator\documents> .\myscript.ps1 argument1 argument2 argument
Arguments are separated by spaces on the command line. Argument1, argument2 and argument will be available for use in the script by indexing into the $args automatic variable for example, $args[0] relates to argument1, $args[1] relates to argument2. Consider an example of this. 1. In the command prompt, type the following to open the script previously created in Notepad: notepad C:\Pshell\part1\Lesson6\lesson_6_exercise_1.ps1
2. Add the following lines to the Notepad file: write-host “the first argument equals:” $args[0] write-host “the second argument equals:” $args[1]
The file should look as follows: #requires -Version 2 <# Author: Date: #> write-host “the first argument equals:” $args[0] write-host “the second argument equals:” $args[1]
3. On the File menu, click Save to save the file. 4. In the command prompt, type the following command, specifying arguments: C:\Pshell\part1\Lesson6\lesson_6_exercise_1 myarg1 myarg2
Exercise 2: Iteration Statements Objectives In this section, you will:
Work with the Do While and Do Until statements
Work with the For and ForEach statements
Work with the While statement
Scenario PowerShell iteration statements provide the basic logic needed to make programmatic decisions within a script. PowerShell scripts use several familiar programming statements for iteration (i.e., looping and branching). The syntax for these statements is in the form of a script block. A script block in PowerShell is always opened and closed with braces and contains the code to be executed if a previous condition, defined within smooth parentheses, evaluates to true. Iteration statements are used to loop through and execute code multiple times. Iteration is a method to reduce the amount of code that is required to achieve a desired outcome.
Task 1: Log on to the VM environment Log on to Windows 7 Enterprise client as Contoso\Administrator the password, P@ssword
Task 2: Open Windows PowerShell Session On the Windows taskbar, click
.
The PowerShell window opens.
Task 3: Do While and Do Until Iteration Statements The do while iteration is similar to the foreach or for iterations. However, it continues to run until a condition is no longer met. The code for the loop is executed first and then the statement is evaluated. If the condition is false, then the loop ends; otherwise the code is executed again. Note that when using a do while iteration, you will always get one execution, even if the condition is false to start with. The syntax of the do while statement is as follows: do{} while ( operator ) The do until iteration is similar to the do while iteration; however, the logic for the condition is reversed, which means that the iteration continues until a condition is true.
A classic use of this iteration is in reading a file. The iteration will continue to pass through the file, until it reaches the end. The syntax of the do until statement is as follows: do{} until ( operator ) Let us look at an example of these two iteration statements. 1. In the command prompt, type the following to open the script previously created in Notepad: notepad c:\Pshell\part1\Lesson6\lesson_6_exercise_1.ps1
2. Remove all commands from the file, keeping only the commented text. 3. Modify the file to look like this: #requires -version 2 <# Author: Date: #> write-host "starting do while example..." $i = 1 do { write-host “iteration number $i” } while (++$i -le 5) write-host "starting do until example..." $i = 1 do { write-host “iteration number $i” } until (++$i -gt 5)
4. Click File > Save As, and type “C:\Pshell\part1\Lesson6\Exercise_6_2a.ps1” in the file name box. 5. In the command prompt, type the following to run the script: C:\Pshell\part1\Lesson6\Exercise_6_2a.ps1
In the do while example, PowerShell will loop through and execute the code as long as the value of $i is less than or equal to 5. In the do until example, PowerShell will loop through the code until the value of $i is greater than or equal to 5.
Task 4: For and ForEach iteration statements The foreach iteration statement is a very powerful loop used to enumerate a collection.
This is useful when you want to run the same code for a group of objects, but you do not need to know how many objects there are in the loop. You just need to execute the same code for each member of the collection. The syntax of the foreach statement is as follows: foreach ( in ){} The for iteration statement is different from the foreach because, it can be used to loop a certain number of passes through the code. This is useful if only a certain number of passes is required. Another benefit of this statement is that you have an automatic counter for the current pass of the loop. The syntax of the for statement is as follows: for ( ; Boolean loop condition; counter handling){} Let us look at an example of these two iteration statements. 1. In the command prompt, type the following to open the script previously created in Notepad: notepad C:\Pshell\part1\Lesson6\lesson_6_exercise_1.ps1
2. Remove all commands from the file, keeping only the commented text. 3. Modify the file to look like this: #requires -version 2 <# Author: Date: #> write-host "starting foreach example..." $i = 1,2,3,4,5 foreach ($t in $i) { write-host “iteration number $t” } write-host "starting for example..." for ($i = 5; $i -ge 1; --$i) { write-host “iteration number $i” }
4. Click File > Save As, and type “C:\Pshell\part1\Lesson6\lesson_6_exercise_2b.ps1” in the file name box. 5. In the command prompt, type the following command to run the script: C:\Pshell\part1\Lesson6\lesson_6_exercise_2b.ps1
In the foreach example, PowerShell will execute the code (i.e., write-host “iteration number $t” in the example) once for each item in the variable $i. In the for example, PowerShell will execute the code (i.e. write-host “iteration number $i” in the example) as long as the variable $i is greater than or equal to 1.
Task 5: While iteration statement The while iteration is basically the same as the do while iteration; however, the key difference is that the condition is tested before any code is executed. This prevents the possibility of the code or iteration running once even when the condition is not true. The syntax of the while iteration is as follows: while ( operator ){} Let us look at an example of this iteration statement. 1. In the command prompt, type the following to open the script previously created in Notepad C:\Pshell\part1\Lesson6\lesson_6_exercise_1.ps1
2. Remove all commands from the file, keeping only the commented text. 3. Modify the file to look like this: write-host "starting while example..." $i = 1 while ($i -le 5) { write-host “iteration number $i” ++$i }
4. Click File > Save As, and type “C:\Pshell\part1\Lesson6\Exercise_6_2c.ps1” in the file name box. 5. In the command prompt, type the following to run the script: C:\Pshell\part1\Lesson6\Exercise_6_2c.ps1
In the while example, PowerShell will execute the code (i.e., write-host “iteration number $i”;++$i in the example) as long as the variable $i is less than or equal to 5.
Exercise 3: Flow control Statements Objectives In this lesson, we will:
Explain the Break and Continue statements
Explain the Return and Exit statements
Scenario As the name suggests flow control statements are used to control the flow of code through a function, loop or script.
Task1: Log on to the VM environment Log on to Windows 7 Enterprise client as Contoso\Administrator with the password: P@ssword
Task 2: Open Windows PowerShell Session On the Windows taskbar, click
.
The PowerShell window opens.
Task 3: Break and Continue flow control statements The break and continue statements allow you to manage how looping constructs process. The break statement allows you to immediately exit a loop. The break keyword allows the code to exit from nested functions. Consider an example of these flow control statements. 1. In the command prompt, type notepad C:\Pshell\part1\Lesson6\Lesson_6_exercise_1.ps1 to open the script previously created in Notepad. notepad C:\Pshell\part1\Lesson6\Lesson_6_exercise_1.ps1
2. Remove all commands from the file, keeping only the commented text. 3. Modify the file to look like this: #requires -version 2 <# Author: Date: #> write-host "starting break example..." $counter=0 while ($true) { if ($counter++ -ge 3) { break
4. Click File > Save As, and type “C:\Pshell\part1\Lesson6\lesson_6_exercise_3a.ps1” in the file name box. 5. In the command prompt, type the following to run the script C:\Pshell\part1\Lesson6\lesson_6_exercise_3a.ps1
In the break example, the code would normally cause an infinite loop because the while statement has been set to $true. However, the break keyword is called once the counter variable is greater or equal to 3 and therefore, the loop stops. In the continue example, the code shows a foreach loop that loops over the numbers from 1 to 10. The range operator sends a stream of numbers to the if statement, where the modulus operator determines whether the current number is exactly divisible by 2 (i.e., an even number). The continue operator allows the loop to re-iterate if the result is $false (i.e., not an even number).
Task 4: Return and Exit Flow Control Statements The return statement is used in scripts or functions to write to the pipeline and return control back to the caller of the script or function. It is used to exit the current scope, which can be a function, script, or script block. The exit statement is used to exit the current script and return control to the host or a calling script. Consider an example of these statements. 1. In the command prompt, type notepad C:\Pshell\part1\Lesson6\Lesson_6_exercise_1.ps1to open the script previously created in Notepad. notepad C:\Pshell\part1\Lesson6\Lesson_6_exercise_1.ps1
2. Remove all commands from the file, keeping only the commented text. 3. Modify the file to look like this: #requires -version 2 <# Author: Date: #>
4. Click File > Save As, and type “C:\Pshell\part1\Lesson6\lesson_6_exercise_3b.ps1” in the file name box. 5. In the command prompt, type the following to run the script: C:\Pshell\part1\Lesson6\lesson_6_exercise_3b.ps1
In the return statement example, PowerShell will execute the code (i.e. write-host “iteration number $i”;++$i) as long as the variable $i is less than or equal to 5. However, once the variable $i reaches 3 the loop is interrupted by the if statement condition evaluating to true. The return statement terminates the loop and returns the value of $i at that point. In the exit example, PowerShell will execute the code (i.e. write-host “iteration number $i”;++$i) as long as the variable $i is less than or equal to 5. However, once the variable $i reaches 3, the loop is interrupted by the if statement condition evaluating to true. The exit statement then terminates the script and control is handed back to the host without executing the last line in the script. You can access $LastExitCode to view the value will be equal to 3.
Exercise 4: Other Statements Objectives In this lesson, we will:
Explain labeled statements
Explain the if statement
Explain the switch statement
Scenario This section covers other statements that are commonly used in PowerShell scripting.
Log on to the VM environment Log on to Windows 7 Enterprise client Contoso\Administrator with the password: P@ssword
Open Windows PowerShell Session On the Windows taskbar, click
.
The PowerShell window opens.
Labeled statements Statement labels allow you to explicitly refer to a statement by a name. Consider an example of statement labels. 1. In the command prompt, type notepad C:\Pshell\part1\Lesson6\Lesson_6_exercise_1.ps1to open the script previously created in Notepad. notepad C:\Pshell\part1\Lesson6\Lesson_6_exercise_1.ps1
2. Remove all commands from the file, keeping only the commented text. 3. Change the file to look like this: #requires -version 2 <# Author: Date: #> :outer while ($true) { :inner while ($true) { Get-Date -displayhint time break outer # break from the ‘inner’ & ‘outer’ while statements } Get-Date –displayhint date # this potential infinite loop is never called }
4. Click File > Save As, and type “C:\Pshell\part1\Lesson6\lesson_6_exercise_4a.ps1” in the file name box. 5. Type the following to run the script: C:\Pshell\part1\Lesson6\lesson_6_exercise_4a.ps1
In the labeled statement example, breaking out of an inner and an outer while loop by using the label construct to name the first while loop is demonstrated. The nested while loop breaks the outer loop from ever being executed (stopping the final Get-Date cmdlet, which would have been called infinitely).
If Statement The if statement in PowerShell is used to test for a particular condition in a Boolean statement. The syntax of an if statement is as follows: if ( operator ){} elseif ( operator ){} else{} Note that the elseif and else parts are optional in an if statement. Consider an example of an if statement. 1. In the command prompt, type notepad C:\Pshell\part1\Lesson6\Lesson_6_exercise_1.ps1to open the script previously created in Notepad. notepad C:\Pshell\part1\Lesson6\Lesson_6_exercise_1.ps1
2. Remove all commands from the file, keeping only the commented text. 3. Change the file to look like this: #requires -version 2 <# Author: Date: #> $fooditem = “Pumpkin” if ($fooditem -eq “Apple”) { "Fruit" } elseif ($fooditem -eq “Pumpkin” -or $fooditem -eq “Tomato”) { "Who knows?" } elseif ($fooditem -eq “Carrot”) { "Vegetable" } else { "Unknown" }
4. Click File > Save As, and type “C:\Pshell\part1\Lesson6\lesson_6_exercise_4b.ps1” in the file name box. 5. In the command prompt, type the following to run the script “C:\Pshell\part1\Lesson6\lesson_6_exercise_4b.ps1”
Switch Statement The switch statement in PowerShell is similar to the Select Case statement in VBScript. The switch statement is very useful when you want to test a value and run code based on a match. The same action can be performed using a compounded if, elseif statement, but it is more complex. In the case of a switch statement, you simply put the variable that you want to test in the statement and then list the matches and the code to execute for each match. Note that the default match is optional and will match anything that is not matched by any of the other patterns. The syntax of the switch statement is as follows: Switch () { { } { } { } Default { } } Consider an example of the switch statement. 1. In the command prompt, type notepad C:\Pshell\part1\Lesson6\Lesson_6_exercise_1.ps1to open the script previously created in Notepad. notepad C:\Pshell\part1\Lesson6\Lesson_6_exercise_1.ps1
2. Remove all commands from the file, keeping only the commented text. 3. Change the file to look like this: #requires -version 2 <# Author: Date: #> switch ("Monday") { Monday {"Oh no its monday. You have to work today."} Tuesday {"Oh no its Tuesday. You have to work today."} Wednesday {"Its hump day, halfway there."} Thursday {"Its TGIF eve. You have to work today"} Friday{"Thank goodness its Friday. Almost the weekend"} default {"It must be the weekend. No work today, you have to be happy. Its required"} }
4. Click File > Save As, and type “C:\Pshell\part1\Lesson6\lesson_6_exercise_4c.ps1” in the file name box. 5. In the command prompt, type the following to run the script C:\Pshell\part1\Lesson6\lesson_6_exercise_4c.ps1
In the switch example, the value “Monday” is tested for a match. A match is found and the code in the statement block is executed resulting in the text “Oh no it’s Monday. You have to work today.” being displayed on the console. Note that the code in the statement block for the default match would be executed if a match is not found.
Exercise 5: Functions Objectives In this lesson, we will:
Create a basic function
Create a function with a function-parameter-declaration
Create a function with a param-block
Explain the switch type constraint
Explain named blocks and function pipelines
Scenario Almost all programming languages employ the concept of functions, which allow code to be encapsulated and referenced by name. This reduces the complexity of the code and makes it more sustainable. One important thing to note is that PowerShell functions must be declared before they can be used in a script. In contrast to the functions used in a VBScript, PowerShell functions are generally put at the top of the script. To create a function, use the keyword function, followed by a name of your choice and open a new script block with a set of curly parenthesis {…}. In its most basic form, a function is a named block of code to execute. All code within the script block will be executed each time the function is called. To call a function, simply state the name of the function as shown in the following example:
Task 1: Log on to the VM environment Log on to Windows 7 Enterprise client as Contoso\Administrator with the password, P@ssword
Task 2: Open Windows PowerShell Session On the Windows taskbar, click
.
The PowerShell window opens.
Task 3: Create a basic function 1. In the command prompt, type notepad C:\Pshell\part1\Lesson6\Lesson_6_exercise_1.ps1to open the script previously created in Notepad. notepad C:\Pshell\part1\Lesson6\Lesson_6_exercise_1.ps1
2. Remove all commands from the file, keeping only the commented text. 3. Change the file to look like this:
#requires -version 2 <# Author: Date: #> function Sort-Process { get-process | foreach-object { if ($_.cpu -lt 1) { write-host $_.name, $_.cpu -foregroundcolor green } elseif ($_.cpu -gt 5) { write-host $_.name, $_.cpu -foregroundcolor red } } } sort-process
4. Click File, click Save As, and then type “c:\Pshell\part1\Lesson6\Lesson_6_exercise_5a.ps1” complete with the double quotes in the file name box.. 5. Run the script by typing “c:\Pshell\part1\Lesson6\Lesson_6_exercise_5a.ps1” at the command prompt. c:\Pshell\part1\Lesson6\Lesson_6_exercise_5a.ps1
The function above is a basic function and is simply a block of code to execute, similar to a VBScript sub-routine.
Task 4: Create a Function with function-parameter-declaration To expand on the functionality of functions, you can build a function that requires an input value. To pass a value to a function, you need to define an input variable within smooth parenthesis after the function name. To call the function, type the function name followed by a space and the function input value. To return a value, you can use the keyword return followed by the output variable name. Using the return keyword forces the function to exit immediately. Alternately, you can state the name of the output variable. 1. In the command prompt, type notepad C:\Pshell\part1\Lesson6\Lesson_6_exercise_1.ps1to open the script previously created in Notepad. notepad C:\Pshell\part1\Lesson6\Lesson_6_exercise_1.ps1
2. Remove all commands from the file, keeping only the commented text. 3. Change the file to look like this: #requires -version 2 <#
4. Click File > Save As, and type “C:\Pshell\part1\Lesson6\Lesson_6_exercise_5b.ps1” in the file name box. 5. In the command prompt, type the following to run the script: C:\Pshell\part1\Lesson6\Lesson_6_exercise_5b.ps1
The function above returns the WMI status code for a pingstatus command that is executed against the localhost. The function is called using the function name (i.e. wmiping) and the input value (i.e., localhost). In the above function $computername represents a ‘function-parameter-declaration’. Note: When a function executes, parameters are initialized to their corresponding argument value, for example, the above function is called by its name in the script. That is, wmiping and the $computername parameter is initialized to its corresponding argument value i.e. ‘localhost’. If no corresponding argument value is assigned PowerShell will use a default value, if available. A default value can be specified using the assignment operator. Example, wmiping($computername=localhost). If there is neither a corresponding argument value nor a default value PowerShell will use a $null value.
Parameters can also be type constrained for example, wmiping([string]$computername). PowerShell will convert the parameter argument to that type, if necessary.
Task 5: Create a Function with ‘param-block’ It is also possible to use a ‘param-block’. The benefit to using a ‘param-block’ is that attributes can then be specified for the expected parameters. 1. In the command prompt, type notepad C:\Pshell\part1\Lesson6\Lesson_6_exercise_1.ps1to open the script previously created in Notepad. notepad C:\Pshell\part1\Lesson6\Lesson_6_exercise_1.ps1
2. Remove all commands from the file, keeping only the commented text.
3. Change the file to look like this: function wmiping { param([Parameter(Mandatory=$true, ValueFromPipeline=$true)][string[]]$ComputerName) $query = "select * from win32_pingstatus where address = '" + $computername + "'" $wmi = get-wmiobject -query $query write-host "pinging $computername ... " if ($($wmi.statuscode) -eq $null) { $rtnvalue = $($wmi.PrimaryAddressResolutionStatus) } else {$rtnvalue = $($wmi.statuscode)} return $rtnvalue } wmiping
4. Click File > Save As, and type “C:\Pshell\part1\Lesson6\Lesson_6_exercise_5c.ps1” in the file name box. 5. In the command prompt, type the following to run the script: “C:\Pshell\part1\Lesson6\Lesson_6_exercise_5c.ps1”
This function also returns the WMI status code for a pingstatus command that is executed against the localhost. The function is again called using the function name (i.e., wmiping) and the input value (i.e., localhost). The $computername parameter in the function is similar to the previous example of a function but this time we have defined attributes for the parameter. That is, ‘Mandatory’, which is used to enforce specifying a value for the parameter and ‘ValueFromPipeline’, which means that the parameter value can be obtained from the pipeline.
Task 6: [switch] Type Constraint Parameter Functions also support a switch parameter. Switch parameters are Boolean, $true if present and $false if omitted. When a switch parameter is passed, the corresponding parameter is constrained by the [switch] type. You can check if a switch has been passed using an If statement as follows: if ($switchVarName) {“do something!”} else {“do nothing”}. 1. In the command prompt, type notepad C:\Pshell\part1\Lesson6\Lesson_6_exercise_1.ps1to open the script previously created in Notepad. notepad C:\Pshell\part1\Lesson6\Lesson_6_exercise_1.ps1
2. Remove all commands from the file, keeping only the commented text. 3. Change the file to look like this: #requires -version 2 <# Author:
Date: #> function multiplier ([switch]$multiply,$val1,$val2) { if ($multiply) { $val1*$val2 } else { write-host “The ‘multiply’ switch has not been activated.” } } multiplier -multiply 2 4
4. Click File > Save As, and type “C:\Pshell\part1\Lesson6\Lesson_6_exercise_5d.ps1” in the file name box. 5. In the command prompt, type the following to run the script: “C:\Pshell\part1\Lesson6\Lesson_6_exercise_5d.ps1”
Note that the switch can be specified anywhere in the list of parameters. For example, ‘multiplier -multiply 2 4’ is the same as ‘multiplier 2 -multiply 4’ is also the same as ‘multiplier 2 4 –multiply’.
Task 7: Named Blocks and Pipelines The statements within the script block of a function (i.e. within the curly braces {}) can be contained in one large block or they can be divided into named blocks. A begin block is executed once before the first pipeline object is sent. The process block is executed once for each object sent on the pipeline. The end block is processed once after the last object on the pipeline has been sent. 1. In the command prompt, type notepad C:\Pshell\part1\Lesson6\Lesson_6_exercise_1.ps1 to open the script previously created in Notepad. notepad C:\Pshell\part1\Lesson6\Lesson_6_exercise_1.ps1
2. Remove all commands from the file, keeping only the commented text 3. Modify the file to look like this: #requires -version 2 <# Author: Date: #> function myservicecounter { begin { $counter=0 } process { if($_.status -eq "running")
4. Click File > Save As, and type “C:\Pshell\part1\Lesson6\Lesson_6_exercise_5e.ps1” in the file name box. 5. In the command prompt, type the following to run the script: “C:\Pshell\part1\Lesson6\Lesson_6_exercise_5e.ps1”
Note: In this example get-service is piped to the myservicecounter function. Getservice consists of a collection of items that are made available to the function via an enumerator that is automatically defined on entry to the function. This enumerator is called $input.
Exercise 6: Profiles Objectives In this lesson, we will:
Understand the different types of profiles
Understand how to view profile locations
Create a profile for the Current User
Scenario The PowerShell host application ‘resets’ every time it exits. This means that all aliases, functions, variables and so forth that we create are lost upon exit. A PowerShell Profile can be created to make customizations persist between PowerShell host sessions. The ability to create a Profile is a very useful feature of PowerShell. A profile is simply a start-up script that runs every time PowerShell starts. Each line in the script is run and applied to each instance of PowerShell, every time PowerShell is run. (This concept is very similar to the autoexec.bat file for those who remember the old DOS days). The profile can hold simple lines that create new functions and aliases, or hold very complex and powerful pieces of code. $Profile is a special variable that can be used to retrieve the location of the current user on the current host’s profile. $Profile always exists, however, by default the actual profile does not exist and must be created manually. Typing $Profile displays where your personal profile should be stored. To create the profile simply make a note of the directory structure and file name, and create a text file with that name in the appropriate place. There are four types of standard profiles, listed in order of precedence here:
Current User, Current Host – this is the profile referenced by $profile. This profile applies only to the current user, and is run every time PowerShell.exe is run.
Current User, All Hosts – this profile applies to the current user and all PowerShell instances, regardless of the executable host that PowerShell is hosted within.
All Users, Current Host – this profile applies to all users, and is run every time PowerShell.exe is run.
All Users, All Hosts – this profile applies to all users and all PowerShell instances, regardless of the executable host that PowerShell is hosted within.
There are also two profiles that are specific to the Integrated Scripting Environment (ISE):
ISE – Current User, Current Host – this is similar to the Current User, Current Host profile. It is run instead of the normal $profile file.
ISE – All Users, Current Host – this is similar to the All Users, Current Host profile.
Task 1: Log On to VM Environment Log on to Windows 7 Enterprise client as Contoso\Administrator with the password, P@ssword
Task 2: Open Elevated Windows PowerShell Session 1. On the Windows taskbar, right-click . 2. Select Run As Administrator. 3. Click Yes if a User Account Control prompt appears. The PowerShell window opens.
Task 3: View Profile Locations 1. Type $profile | get-member -type noteproperty to view all current values of the $profile variable. $profile | get-member -type noteproperty
2. Type $Profile to return the Current User Current Host profile location. $Profile
3. Type $Profile.CurrentUserAllHosts to return the Current User All Hosts profile location. $Profile.CurrentUserAllHosts
4. Type $Profile.AllUsersCurrentHost to return the All Users Current Host profile location. $Profile.AllUsersCurrentHost
5. Type $Profile.AllUsersAllHosts to return the All Users All Hosts profile location. $Profile.AllUsersAllHosts
Task 4: Create a profile for the Current User 1. Type new-item -path $profile -type file –force to create a profile. new-item -path $profile -type file –force
2. Type notepad $profile to open the newly created profile. notepad $profile
3. Type the following in the profile file to customize the PowerShell prompt for the current user in the current host: function prompt{$env:computername + " " + (get-location) + "> "}
4. On the File menu, click Save to save the file. 5. Click File > Exit to close the file. 6. Open PowerShell. Notice that the prompt has changed.
Exercise 7: Dot sourcing and Script Libraries Objectives In this lesson, you will:
Understand the dot sourcing concept
Learn how to create a script library
Scenario It is a relatively common practice to create libraries of PowerShell code (such as script blocks, functions, aliases, variables, etc.) that can be utilized on demand. These are typically packaged into one or more library scripts that can then be dot sourced. Dot source notation is essentially a method to make items from your script library apply to the current scope, as opposed to only applying to a nested scope. For example a dot sourced script that sets a variable will make that variable available to the current scope whereas the variable would only be available to the nested script scope without dot sourcing. The syntax to dot source a script is as follows: . \myscript.ps1 Note there is a space between the dot and the backslash.
Task 1: Log On to VM Environment Log on to Windows 7 Enterprise client as Contoso\Administrator with the password, P@ssword
Task 2: Open Elevated Windows PowerShell Session 1. On the Windows taskbar, right-click . 2. Select Run As Administrator. 3. Click Yes if a User Account Control prompt appears. The PowerShell window will open.
Task 3: Dot Source a Script file 1. In the command prompt, type notepad.exe and press Enter to open notepad. notepad
2. Type $a=5 in the file to assign a variable. $a=5
3. Click File > Save As, and type “C:\Pshell\part1\lesson6\mydotsourcedscript.ps1” in the file name box. 4. Click File > Save. 5. Click Save to save the file. 6. Click File > Exit to close the file. 7. Type notepad $profile to open the previously created profile.
8. Dot-source C:\pshell\part1\lesson6\mydotsourcedscript.ps1 in the profile file. . C:\pshell\part1\lesson6\mydotsourcedscript.ps1
9. On the File menu, click Save to save the file. 10. Click File > Exit to close the file. Note that there is a space between the dot and the rest of the command. This will ‘dot source’ the mydotsourcedscript script file and effectively make the variable ‘a’ available in the current scope. 11. Close and re-open PowerShell. 12. Type $a and press Enter. $a
Note that the assigned value is returned and that the $a variable is therefore available in the current scope. 13. Type dir variable to see a complete list of the variables that is available in the current scope. Dir variable:
Task 4: Remove the Dot Sourced Script file 1. Type notepad $profile to open the profile. notepad $profile
2. Remove C:\pshell\part1\lesson6\mydotsourcedscript.ps1 from the profile file. 3. On the File menu; click Save to save the file. 4. Click File > Exit to close the file.
Exercise 1: Create PowerShell Scripts Task 1: Log on to the VM environment Log on to Windows 7 Enterprise client as Contoso\Administrator with the password, P@ssword
Task 2: Open Windows PowerShell Session Open Windows PowerShell session: On the Windows taskbar, click . The PowerShell window opens.
Task 3: Create a basic script 1. In the command prompt, type notepad.exe to open notepad and press Enter. Notepad.exe
2. Type the following into the file: #requires -Version 2 <# Author: Your name Date: Today’s date #> get-process | sort-object cpu –descending | select-object –first 5
3. Click File > Save As, and type “C:\pshell\part1\lesson6\labs\top5cpu.ps1” in the file name box. 4. In the PowerShell window, type the following to run the script: C:\pshell\part1\lesson6\labs\top5cpu.ps1
Notice that the top 5 CPU utilizing processes are returned.
Exercise 2: Create Functions in Scripts Task 1: Log on the VM Environment Log on to Windows 7 Enterprise client as Contoso\Administrator with the password P@ssword
Task 2: Open Windows PowerShell Session On the Windows taskbar, click
. The PowerShell console opens.
Task 3: Create a function in a script 1. In the command prompt, type notepad.exe and press Enter to open notepad. Notepad.exe
2. Type the following into the file #requires -Version 2 <# Author: Your name Date: Today’s date #> function topxxcpu { param($number) get-process | sort-object cpu –descending | select-object –first $number }
3. Click File > Save As, and type “C:\pshell\part1\lesson6\lab6\topxxcpu.ps1” in the file name box. 4. In the command prompt, type the following to dot source the script: . C:\pshell\part1\lesson6\labs\topxxcpu.ps1
5. In the command prompt, type the following topxxcpu 5
Notice that the top five CPU utilizing processes are returned. 6. In the command prompt, type the following topxxcpu 15.
Notice that the top 15 CPU utilizing processes are returned.
Exercise 3: Create PowerShell Profiles Task 1: Log on to the VM environment Log on to Windows 7 Enterprise client as Contoso\Administrator with the password, P@ssword
Task 2: Open Elevated Windows PowerShell Session 1. On the Windows taskbar, right-click . 2. Select Run As Administrator. 3. Click Yes if a User Account Control prompt appears. The PowerShell window opens.
Task 3: Create a Profile 1. Create a profile for all Users on all Hosts 2. Type new-item -path $profile.AllUsersAllHosts -type file –force to create a profile. new-item -path $profile.AllUsersAllHosts -type file –force
3. Type notepad $profile.AllUsersAllHosts to open the newly created profile. notepad $profile.AllUsersAllHosts
4. Type the following in the profile file to customize the PowerShell session for all users using any PowerShell host on this computer. write-host "Hello $env:username!`n" -foregroundcolor green $docs=”$home\documents” write-host “The `$DOCS variable provides access to your documents `n$docs`n” -foregroundcolor green
located at:
5. On the File menu, click Save to save the file. 6. Click File > Exit to close the file. 7. Open PowerShell. Notice the welcome message.
Exercise 4: Explore Iteration Statements In PowerShell Task 1: Log on to the VM environment Log on to Windows 7 Enterprise client as Contoso\Administrator with the password, P@ssword
Task 2: Open Elevated Windows PowerShell Session 1. On the Windows taskbar, right-click . 2. Select Run As Administrator. 3. Click Yes if a User Account Control prompt appears. The PowerShell window opens.
Task 3: Create Multiple Folders 1. In the command prompt, type notepad.exe and press Enter to open notepad. Notepad.exe
3. Create a variable named $intFolders, and ensure that it holds the value of 10. The code to do this is shown here. $intFolders = 10
4. Create a variable named $intPad. Do not put anything in the variable yet: $intPad
5. Create a variable named $i, and put the number 1 in it: $i = 1
6. Use the New-Variable cmdlet to create a variable named strPrefix. Use the value argument of the cmdlet to assign the value of "testFolder" to the variable. Use the option argument to change $strPrefix to a constant: New-Variable -Name strPrefix -Value "testFolder" -Option constant
7. Open a do … until statement. Include the opening curly bracket for the script block: do {
8. Begin an if … else statement. The condition to be evaluated is if the variable $i is less than 10: if ($i -lt 10)
9. Open the script block for the if statement. Assign the value of 0 to the variable $intPad: {$intPad=0
10. Use the New-Item cmdlet to create a new folder. The new folder will be created in the c:\mytest directory. The name of the new folder will be comprised of the $strPrefix constant “testFolder”, the number 0 from the $intPad variable, and the number contained in the $i variable. The code that does this is seen here. new-item -path c:\mytest -name $strPrefix$intPad$i -type directory}
11. Add the else clause: else
12. The else script block is the same as the if script block, except that it does not include the 0 in the name that comes from the $intPad variable. Copy the new-item line of code from the if statement, and delete the $intPad variable from the name argument. The revised line of code is shown here. {new-item -path c:\mytest -name $strPrefix$i -type directory}
13. Increment the value of the $i variable by 1 by using the ++ operator: $i++
14. Close the script block for the do clause and add the until statement. The condition that until will evaluate is if the $i variable is equal to the value contained in the $intFolders variable +1. The reason for adding 1 to $intFolders is so that the script will actually create the same number of folders as is contained in the $intFolders variable. Because this script uses a do …until loop and the value of $i is incremented prior to entering the until evaluation, then the value of $i is always 1 more than the number of folders that are created. This code is shown here. }until ($i -eq $intFolders+1)
15. Save your script as shown below: C:\pshell\part1\lesson6\labs\CreateMultipleFolders.ps1
16. Run your script and confirm the results. You should see 10 folders created in the c:\mytest directory.
Task 4: Delete Multiple Folders 1. Open the C:\pshell\part1\lesson6\labs\CreateMultipleFolders.ps1 script in Notepad or another script editor. This script was created in the previous task. Notepad C:\pshell\part1\lesson6\labs\CreateMultipleFolders.ps1
2. In the if … else statement, the New-Item cmdlet is used twice to create folders in the c:\mytest directory. We want to delete these folders. To do this, we need to change the New-Item cmdlet to the Remove-Item cmdlet. The two edited script blocks are shown here. {$intPad=0; remove-item -path c:\mytest -name $strPrefix$intPad$i} else {remove-item -path c:\mytest -name $strPrefix$i}
3. The Remove-Item cmdlet does not have a name argument. So we need to remove this argument but retain the code that creates the folder name. We can replace -name with a backslash: {$intPad=0; remove-item -path c:\mytest\$strPrefix$intPad$i} else {remove-item -path c:\mytest\$strPrefix$i}
4. The Remove-Item cmdlet does not take a type argument. Because this argument is not needed, it can also be removed from both Remove-Item statements. The revised script blocks are shown here. {$intPad=0; Remove-item -path c:\mytest\$strPrefix$intPad$i} else {Remove-item -path c:\mytest\$strPrefix$i}
5. Save your script as shown below: C:\pshell\part1\lesson6\labs\DeleteMultipleFolders.ps1
6. Run your script and confirm the results. You should see that the 10 previously created folders have been deleted.
Lesson 7 Demonstration : Active Directory Administration (ADSI) The following section provides information and exercises for Active Directory Administration using ADSI.
Introduction Active Directory (AD) is Microsoft’s implementation of an X.500 compliant directory service, which enables centralized access, security, and administration of network resources using the Lightweight Directory Access Protocol (LDAP) standard. The AD administrative tasks are commonly performed using two main GUI applications:
Active Directory Users & Computers
Active Directory Sites & Services
These applications are adequate for small addition, modification, and deletion tasks. The applications become unmanageable when performing bulk operations in large forest environments containing thousands or millions of objects.
Active Directory Service Interfaces (ADSI) ADSI enables access to the directory service from different network providers, using a variety of scripting and programming languages. ADSI reduces the complexities of using LDAP directly to enable common administrative tasks such as:
Adding new users or computers
Locating resources in the distributed AD environment
Objectives After completing this lab, you will be able to:
Understand how objects are organized in AD
Create, modify, and delete AD objects using PowerShell and ADSI
Prerequisites Windows 2008 Server and Windows 7 Client Virtual Machines
Exercise 1: Active Directory Fundamentals The following section provides information and tasks for Active Directory fundamentals.
Objectives In this exercise, you will:
Learn how objects stored in AD are organized
Access objects using the ADSI type accelerator
Prerequisites Windows PowerShell v2 must be installed on a Windows 7 client machine. A Domain Controller running Windows 2008 must be available on the network.
Active Directory Overview Active Directory is a directory service, which provides a centralized location to store information in a distributed environment. The directory service stores information about networked devices, services, and the people who use them. AD also implements services that make this information available to users, computers, and applications. It is both:
A database storage system (directory store)
A set of services that provide a means to add, modify, delete, and locate data securely in the directory store.
Directory Partitions The AD database file (ntds.dit) is logically divided into a number of partitions, also known as naming contexts. Partitioning data allows it to be replicated independently to domain controllers in a single domain or the entire forest. There are three default AD partitions. Partition Name
Replication Scope
Description
Domain
All DCs in a Domain
Stores users, computers, groups, and other objects specific to a single domain
Configuration
All DCs in the Forest
Stores sites, services, and partition information for the entire forest
Schema
All DCs in the Forest
Stores the class and attribute definitions and rules for all objects in the entire forest
Directory Hierarchy Although the underlying AD storage mechanism is table based, the directory server organizes the data into a logical hierarchy of parent and child objects.
Each item in the directory is identified by a name and a two-letter prefix, known as Relative Distinguished Name (RDN). For example, all user, group, and computer objects are prefixed by ‘CN’. “CN=FinanceUser01”
To build a tree structure, a unique path to each object is created by concatenating an object’s RDN with its parent container, until the top of the specific directory partition is reached. This path is known as a Distinguished Name (DN) and uniquely identifies an object. DN paths are used to connect to objects in order to create and manipulate them. “CN=FinanceUser01,OU=Finance Users,OU=Corporate Users,DC=contoso,DC=com”
ADSI Providers ADSI includes a number of service providers that allow access to different types of directories. The following table lists service provider details. Service provider
Moniker
Description
LDAP
LDAP://
Namespace implementation compatible with LDAP
WinNT
WinNT://
Namespace implementation compatible with Windows 2000 or Windows NT
NDS
NDS://
Namespace implementation compatible with Novell NetWare Directory Service (NDS)
NWCOMPAT
NWCOMPAT://
Namespace implementation compatible with Novell NetWare 3.x
The LDAP provider fully supports AD, but cannot be used to access Windows NT or the local Security Accounts Manager (SAM) database. The WinNT provider can be used to access Windows NT4 domain controller directory servers, the local SAM database on client and member server machines as well as AD implementations, but will only support features available on Windows NT domains. The NDS and NWCOMPAT providers allow access to the Novell NDS implementations. For example, in order to use the LDAP provider to connect to active directory objects, prefix the LDAP moniker (the provider name plus the two forward slashes and colon character) to the DN of the particular object. Note: Unlike PowerShell, all the four provider strings listed above are case sensitive.
Task 1: Bind to the Directory 1. Connect to the root of the domain partition in the contoso.com domain.
Note: In LDAP terms, connecting to a DN is referred to as 'binding'. “LDAP://DC=contoso,DC=com”
The above string will only appear on the screen when you type it in the PowerShell console or include in a script. 2. To access AD, enter the [ADSI] PowerShell-type accelerator, followed by the binding string. PS C:\> $domain = [ADSI]“LDAP://DC=contoso,DC=com” PS C:\> $domain distinguishedName : {DC=contoso,DC=com} Path :
3. If the computer is a domain member, you need not provide an LDAP moniker and DN, replace it with an empty string. By default, when the computer is a domain member, the binding string will be the root current domain partition. PS C:\> $domain = [ADSI]”” PS C:\> $domain distinguishedName : {DC=contoso,DC=com} Path :
4. The [ADSI] type accelerator is just an alias to the System.DirectoryService.DirectoryEntry .NET class, and is added to save the time to type the fully qualified class name. Use the full name in place of the shortened alias. PS C:\> [ADSI].fullname PS C:\> System.DirectoryServices.DirectoryEntry PS C:\> $domain = [System.DirectoryServices.DirectoryEntry]”” PS C:\> $domain distinguishedName : {DC=contoso,DC=com} Path :
Task 2: Bind using Alternative Credentials 1. By default, connections to AD use the current user’s credentials. If you need to log on with alternative credentials, you can create a new ADSI object, using the New-Object Cmdlet, and specify the Moniker/DN string, username, and password. PS C:\> $domain = New-Object ADSI(“LDAP://DC=contoso,DC=com”,”CONTOSO\Administrator”,”Password123”)
2. It is not a good practice to embed passwords in scripts, you may want to use the GetCredential Cmdlet to securely store the credentials in memory, and then pass them to the ADSI provider. The LDAP provider only accepts plaintext passwords. A workaround
is required to convert the SecureString-encoded password into plaintext, before it is passed on to the provider. Note: Over-the-wire credentials are never sent in plaintext. PS C:\> $cred = Get-Credential PS C:\> $plainTextPwd = [Runtime.InteropServices.Marshall]::PtrToStringAuto( [Runtime.InteropServices.Marshall]::SecureStringToBSTR($cred.password)) PS C:\> $domain = New-Object ADSI(“LDAP://DC=contoso,DC=com”,$cred.username,$plainTextPwd) PS C:\> $domain distinguishedName : {DC=contoso,DC=com} Path :
Task 3: Bind to Specific Domain Controllers The previous examples performed a server-less bind using the DC locator process, to find the nearest Domain Controller in the current site automatically. 1. A specific DNS name, NETBIOS name, or IP address can be used when the requirement is to bind to a specific Domain Controller. [ADSI]”LDAP://syddc01/DC=contoso,DC=com”
2. To bind to the nearest Global Catalog (GC) server in the forest, use the GC:// moniker. [ADSI]”GC://DC=contoso,DC=com”
3. Or bind to a named SYDDC01 server. [ADSI]”GC://SYDDC01/DC=contoso,DC=com”
Exercise 2: Searching Active Directory The following section provides information and tasks for search in Active Directory.
Objectives In this exercise, you will:
Search AD for different types of objects
Search for specific objects
Modify search options
Prerequisites Windows PowerShell v2 must be installed on a Windows 7 client machine. A Domain Controller running Windows 2008 must be available on the network.
Task 1: Directory Searcher: Type Accelerator In the previous exercise, you bound to a specific directory object using its DN attribute. This exercise will help you find a single or a number of objects without knowing their DN. AD search functionality is provided by another PowerShell type accelerator called [ADSISEARCHER]. This is an alias to the much longer System.DirectoryServices.DirectorySearcher .NET class name. To use the type accelerator you must provide a DirectoryEntry object, representing the start of the search. This is called the SearchRoot. 1. In the following example, you will create a DirectoryEntry object using the [ADSI] type accelerator, save this reference in a variable, and pass it to the [ADSISEARCHER] type accelerator. $searchRoot = [ADSI]”LDAP://DC=contoso,DC=com” $dirSearch = [ADSISEARCHER]$searchRoot
Alternatively, you can combine these two operations in a single line. $dirSearch = [ADSISEARCHER][ADSI]”LDAP://DC=contoso,DC=com”
2. Next, use the FindAll() method to execute the search. This operation will return all objects in the domain partition. $dirSearch.FindAll() Path ---LDAP://DC=contoso,DC=com LDAP://CN=Users,DC=contoso,DC=com systemFla... LDAP://CN=Computers,DC=contoso,DC=com systemFla… LDAP://OU=Domain Controllers,DC=contoso,DC=com systemfla…
Task 2: Filter Property Directory search filtering is controlled by the Filter property of a DirectorySearcher object, which requires a special LDAP query syntax string. Essentially, you are filtering all objects where the attribute name specified contains a certain string. For example, the query: (givenName=Chris) Translates to: Search all objects where the givenName attribute contains the string Chris. The following table displays the LDAP query syntax operators with examples.
Note: The ‘=’ operator expressions are grouped by parentheses. The ‘&’ and ‘|’ operators are placed in front of the expressions wrapped in parentheses.
The default search filter is (objectClass=*). Since the wildcard operator is used, this search filter will return all objects under the SearchRoot and all objects are derived from one or more classes. 1. Typing the $dirSearch variable name displays the DirectorySsearcher object properties. In this module, you will focus on the properties highlighted in bold. $dirSearch CacheResults ClientTimeout PropertyNamesOnly
System.DirectoryServices.SortOption False False Never None None
2. To return all user objects, set the Filter property to (objectCategory=user). $dirSearch.Filter = “(objectCategory=user)”
3. Again, start the search by calling the DirectorySearcher object’s FindAll() method. You will see a list of all user objects, in all child containers in the domain. $dirSearch.findAll()
4. A more complex query could include a number of expressions combined with a logical operator and wildcard character. The following example uses the logical AND operator (&) to return all computer objects whose operatingSystem attribute starts with the string “Windows Server”. $dirSearch.filter = “(&(objectCategory=computer)(operatingSystem=Windows Server*))” $dirSearch.findAll() Path
Task 3: SearchScope Property The SearchScope property controls the search behavior. The default setting is ‘Subtree’. As demonstrated in previous examples, this property performs a recursive search from the SearchRoot through all nested child containers. 1. The recursive search behavior can be changed by modifying the SearchScope to "OneLevel". This setting confines the search to the SearchRoot container, in this case, the root of the domain partition. Therefore, only Organizational Unit and Container objects are returned. $dirSearch.SearchScope = “OneLevel” $dirSearch.FindAll() Path ---LDAP://OU=AdminUsers,DC=contoso,DC=com LDAP://CN=Builtin,DC=contoso,DC=com LDAP://OU=Clients,DC=contoso,DC=com LDAP://CN=Computers,DC=contoso,DC=com systemflags... LDAP://OU=Domain Controllers,DC=contoso,DC=com systemflags... LDAP://OU=Exchange Servers,DC=contoso,DC=com LDAP://CN=ForeignSecurityPrincipals,DC=cont... systemflags... LDAP://OU=Groups,DC=contoso,DC=com LDAP://CN=Infrastructure,DC=contoso,DC=com systemflags... LDAP://CN=LostAndFound,DC=contoso,DC=com systemflags... LDAP://CN=Managed Service Accounts,DC=conto... ...
Task 4: MaxPageSize In a large AD environment with hundreds of thousands or even millions of objects in the forest, a DirectorySearch operation could return a huge number of results. AD imposes a limit on the maximum number of results returned from a search. This limitation allows you to conserve DC resources. The MaxPageSize setting at the top of the domain partition controls this limit and is set to a default of 1,000 objects for each query.
1. To overcome this problem, the DirectorySearcher object has a PageSize property, which starts a mechanism called paging. Paging returns multiple result sets, or pages, when a query result exceeds the MaxPageSize limit. Setting this property to any number greater than zero will turn on the paging mechanism, which is transparent to PowerShell. $dirSearch.PageSize = 1000
Task 5: Other Search Options The DirectorySearcher object has many more options available to modify the search behavior, although the Filter, SearchScope and PageSize options already covered will have the greatest impact on search results. The following table lists the other search options. Name
Description
Asynchronous
Gets or sets a value that indicates if the search is performed asynchronously.
AttributeScopeQuery
Gets or sets the LDAP display name of the DN attribute to search. Only one attribute can be used for this type of search.
CacheResults
Gets or sets a value indicating if the result is cached on the client computer.
ClientTimeout
Gets or sets the maximum amount of time that the client waits for the server to return results. If the server does not respond within this time, the search is aborted and no results are returned.
DerefAlias
Gets or sets a value indicating how the aliases of objects that are found during a search should be resolved.
DirectorySynchronization
Gets or sets an object that represents the directory synchronization control to use with the search.
ExtendedDN
Gets or sets a value that indicates the format of the DNs.
Filter
Gets or sets a value indicating the LDAP format filter string.
PageSize
Gets or sets a value indicating the page size in a paged search.
PropertiesToLoad
Gets a value indicating the list of properties to retrieve during the search.
PropertyNamesOnly
Gets or sets a value indicating if the search retrieves only the names of attributes to which values have been assigned.
Gets or sets a value indicating how referrals are chased.
SearchRoot
Gets or sets a value indicating the node in the AD Domain Services hierarchy where the search starts.
SearchScope
Gets or sets a value indicating the scope of search that is observed by the server.
SecurityMasks
Gets or sets a value indicating which security access information for the specified attributes should be returned by the search.
ServerPageTimeLimit
Gets or sets a value indicating the maximum amount of time the server should search for an individual page of results. This is not the same as the time limit for the entire search.
ServerTimeLimit
The ServerTimeLimit property gets or sets a value indicating the maximum amount of time the server spends searching. If the time limit is reached, only entries that are found up to that point are returned.
SizeLimit
Gets or sets a value indicating the maximum number of objects that the server returns in a search.
Sort
Gets or sets a value indicating the property on which the results are sorted.
Tombstone
Gets or sets a value indicating if the search should also return deleted objects that match the search filter.
VirtualListView
Gets or sets a value indicating the virtual list view options for the search.
Exercise 3: The Directory Object Lifecycle The following section provides information and tasks for Directory Object Lifecycle.
Objectives In this exercise, you will:
Understand how to create new user, computer, and group objects in AD
Learn how to modify object attributes
Add users to groups
Manipulate the UserAccountControl attribute
Create and modify multiple objects in the directory
Prerequisites Windows PowerShell v2 must be installed on a Windows 7 client machine. A Domain Controller running Windows 2008 must be available on the network.
Task 1: Create Active Directory Objects So far, you learnt how to connect and search for objects in AD, In addition, you can create new objects. To create a new object, you need the following information:
DN of the container
Class name of the object
A unique RDN (within the parent container) of the new object
Task 2: Class Name and RDN Prefix An easy way to find object class names is to open adsiedit.msc, by clicking Start > Run > adsiedit.msc. Browse the Default naming context for the object type you want to create. View the Class column and note the specified class name. Examples of commonly used class names and RDN prefixes are listed in the table below.
Task 3: Create an Organizational Unit Object Creating objects in AD involves binding to a container and using a method to create objects. The Create() method is available only on container objects, such as the Domain Root, Organizational Units, and Containers. Note: The Create() method is hidden when viewing the object members using the GetMember Cmdlet.
1. To use this method to create a new Organizational Unit object at the root of the domain, first bind to the Domain Root DN, and save a reference to it in a variable. $objRoot = [ADSI]”LDAP://DC=contoso,DC=com”
2. Use the Create() method to create a new Organizational Unit object. To do this, supply two input arguments, the class name ‘organizationalunit’ and RDN with the correct prefix for this object type (OU=). Save the resulting user object in the $objOU variable. $objOU = $objRoot.Create(“organizationalunit”,”OU=Finance”)
3. The new OU object is now created on the local machine. You must now save the object to the directory. To save the object, use the SetInfo() method on the $objOU variable.
4. To confirm the object was created successfully, bind to object. [ADSI]”LDAP://OU=Finance,DC=contoso,DC=com” distinguishedName : {OU=Finance,DC=contoso,DC=com} Path : LDAP://ou=Finance,dc=contoso,dc=com
Task 4: Create User objects The same steps as in creating an Organizational Unit object are used for creating user objects. In this example, you will create a new user within the Finance OU object created in the previous steps. 1. Bind to the Finance OU object. $objOU = [ADSI]”LDAP://OU=Finance,DC=contoso,DC=com”
2. Use the OU’s Create() method to create the new user object. Note: You must change the class to ‘user’ and the RDN prefix to ’CN=’. $objUser = $objOU.Create(“user”,“CN=FinanceUser01”)
3. At this point, it is a good practice to set the samAccountName property of the new object. Otherwise, the system will automatically create a random unique value similar to $A91000-B3973K23LNTD. Such values are not very user-friendly log on names. To set object attributes, use the Put() method on the new user object. Pass the name of the attribute you want to set along with its new value. In this example, set the user object’s samAccountName attribute value to “FinanceUser01”. $objUser.Put(“samaccountname”,”FinanceUser01”)
4. Commit the new object to AD using the SetInfo() method. $objUser.SetInfo()
Task 5: Enable User Objects Once the user objects are created, they are disabled by default, and must be enabled before they can be used. To enable the account, use the following steps. 1. Bind to the newly created user object. $objUser = [ADSI]”LDAP://CN=FinanceUser01,OU=Finance,DC=contoso,DC=com”
2. Set the password using the user object’s SetPassword() method. $objUser.SetPassword(”P@ssword1”)
3. Enable the account by setting AccountDisabled property to FALSE. $objUser.AccountDisabled = $false
4. Save the changes back to the directory. $objUser.Setinfo()
Task 6: Manipulate the UserAccountControl Property User accounts have different options that can be set to control security settings. In ADUC, most options can be set in the Account tab of the user object dialog.
Figure 5:
These settings are stored as binary mask in a property called UserAccountControl on a user object. Each bit position represents a different possible user account option that can be checked or unchecked. Multiple settings can be combined using PowerShell’s binary logical operators and are shown in the following table.
For example, to disable a user account you must perform a binary exclusive OR logical operation (XOR) on the current value of the UserAccountControl property. 5. First, save the current value of the UserAccountControl property into a variable. $uac = $objUser.userAccountControl.value
6. In the above table, find the bit position that controls the option you need to set. In this case, it is 0x0002. For clarity I have saved the number into a more descriptive variable name first. Note: It is possible to use either the hexadecimal or decimal values. $ACCOUNTDISABLE = 0x0002
7. Next, perform the XOR operation on the $uac variable using PowerShell’s –bxor operator. This enables (sets to 1) the second bit position in the UserAccountControl bitmask. $objUser.UserAccountControl = $uac –bxor $ACCOUNTDISABLE
8. Commit the change to the directory. $objUser.SetInfo()
It is a good practice to test if the bit position is already set before changing it, as the XOR operator blindly flips the bit on to off and vice versa. To do this, use the binary AND logical operator to check if the option is set.
If the result is 0, the bit position is turned off ($false).
Any positive integer indicates the bit is turned on ($true).
9. Save the value, representing the Password never expires option into a variable. $DONT_EXPIRE_PASSWORD = 0x10000
10. Bind to the user account. $objUser = [ADSI]”LDAP://CN=FinanceUser01,OU=Finance,DC=contoso,DC=com”
11. Save the UserAccountControl value into a variable. $uac = $objUser.UserAccountControl.value
12. Use an IF statement and a –band operator to determine whether the bit is already turned on. If it is not, turn the bit position on (flip the bit) using the –bxor operator. if ($uac –band $DONT_EXPIRE_PASSWORD) { “Password never expires is already set” } else { “Password never expires is NOT set” “Setting the password to never expire…” $objUser.UserAccountControl = $uac –bxor $DONT_EXPIRE_PASSWORD $objUser.SetInfo() }
13. To set multiple options at once, add them together and use the binary OR operator as follows. $SMARTCARD_REQUIRED = 0x40000
Task 7: Modify Multivalued Attributes Many AD object attributes hold a single value, while others can hold a list of values. These multivalued attributes must be changed with a method other than Put(). The PutEx() method accepts an input parameter in addition to the attribute name and value data. This parameter controls how the value is added to the multivalued attribute. Property Name
Description
Value
Clear
Instructs the directory service to remove all the property value(s) from the object
1
Update
Instructs the directory service to replace the current value(s) with the specified value(s)
2
Append
Instructs the directory service to append the specified value(s) to the existing values(s)
3
Delete
Instructs the directory service to delete the specified value(s) from the object
4
Following is an example of changing multivalued attribute using PutEx() method. 1. Bind to a user object. $objUser = [ADSI]”LDAP://CN=FinanceUser01,OU=Finance Users,DC=contoso,DC=com”
2. Create an array of phone numbers. $arrPhone = “029870123456”,” 029870123457”,”029870123458”
3. Update the ‘otherHomePhone’ multivalued attribute using the PutEx() method. $objUser.PutEx(2,”otherHomePhone”,$arrPhone)
4. Commit the changes to the directory. $objUser.SetInfo()
Task 8: Create Group Objects Group object creation follows the same pattern as user objects, although you have to specify the group type before you commit the transaction to the directory. 1. Bind to the container in which you want to create the new group. $objRoot = [ADSI]”LDAP://ou=Finance,DC=contoso,DC=com”
2. Again, use the Create() method to add the new group. $objGroup = $objRoot.Create(“group”,“CN=FinanceGlobal”)
3. Set the SamAccountName attribute of the new group. $objGroup.InvokeSet(“samaccountname”,”FinanceGlobal”)
4. Set the GroupType property of the new group object to one of its possible values, shown in the following table. Group Type
Hexadecimal Value
Decimal Value
Built-in Local
0x00000001
1
Global
0x00000002
2
Domain Local
0x00000004
4
Universal
0x00000008
8
Security Enabled
0x80000000
-2147483648
5. It is a good practice to assign these values to variables beforehand. Note: It is possible to use either the hexadecimal or the decimal values. $BUILTIN_LOCAL_GROUP = 0x00000001 $GLOBAL_GROUP = 0x00000002 $DOMAIN_LOCAL_GROUP = 0x00000004 $UNIVERSAL_GROUP = 0x00000008 $SECURITY_ENABLED_GROUP = 0x80000000
By performing a binary OR operation (-bor) on the $SECURITY_ENABLED_GROUP variable, and any one of the other four variables you can create any of the security group types. Note: If you set only the GroupType to one of the first four values, a distribution group, rather than a security group will be created.
6. Calculate the Global group binary value, and save it in the $intGlobalGroup variable. $intGlobalGroup = $GLOBAL_GROUP –bor $SECURITY_ENABLED_GROUP
7. Set the groupType attribute to the $intGlobalGroup variable using the Put() method. $objGroup.Put(“grouptype”, $intGlobalGroup)
8. Finally, do not forget to commit the changes to AD. $objGroup.SetInfo()
Task 9: Add Users to Groups Adding users to groups is a common administrative task and can be accomplished very easily in PowerShell. 1. Bind to a group object. $objGroup = [ADSI]”LDAP://CN=FinanceGlobal,OU=Finance Users,DC=contoso,DC=com”
2. Bind to a user object. $objUser = [ADSI]”LDAP://CN=FinanceUser01,OU=Finance Users,DC=contoso,DC=com”
3. Use the group’s Add() method, specifying the user’s path property as the argument. $objGroup.Add($objUser.Path)
4. Save the group membership change back to AD. $objGroup.SetInfo()
Task 10: Create Computer Objects Computer objects share most of their attributes with user objects. Therefore, apart from the class name their creation is identical. 1. Bind to the Finance OU object. $objOU = [ADSI]”LDAP://OU=Finance,DC=contoso,DC=com”
2. Use the Create() method of the OU object to create the new computer object, and save the resulting object in the $objComputer variable. Note: Change the RDN name to ‘NewPC001’ and the object class to ‘computer’. $objComputer = $objOU.Create(“computer”,“CN=NewPC001”)
3. Save the new object back to AD. $objComputer.SetInfo()
4. Computer objects are also disabled by default. To enable them, set the AccountDisabled property to false. $objComputer.AccountDisabled = $false
5. Commit the change to the directory. $objComputer.SetInfo()
Lesson 7 Hands-On : Active Directory Administration (ADSI) The following section provides information and exercises for administering Active Directory objects.
Objectives This lab explores how to create, modify, and search AD objects using Windows Powershell and ADSI.
Prerequisites The lab requires a domain joined Windows 7 client and a Windows 2008 Domain Controller.
Exercise 1: Create Multiple Users The following section provides information and tasks to create multiple users.
Scenario Most AD environments require the creation of many objects in a batch operation. You can use many of the examples covered previously in this lesson to build a user creation script.
Objectives The script will perform the following operations:
Take input from a .csv file to provide individual user details
Create three Organizational Units (OU), global groups, and department manager accounts
Create each batch of users listed in the userlist.csv file
Set a number of single and multivalued attributes
Add each user to a particular global group
Enable the user account and require password to be changed at first log on
Task 1: Develop a script to create AD Objects 1. Open a script editor of your choice and create a new PowerShell script file named c:\pshell\part1\lesson7\labs\lab7-ex1.ps1. 2. Add the following lines to the text file: A. Import the .csv file using the Import-CSV Cmdlet. $users = Import-Csv -Path “C:\pshell\part1\lesson7\labs\userlist.csv”
B. Bind to the Domain Root DN. $objDomainRoot = [ADSI]"LDAP://DC=contoso,DC=com"
3. Create variables to hold the UserAccountControl bitmask values. $NORMAL_ACCOUNT = 0x0200 $ACCOUNTDISABLE = 0x0002
4. Add a foreach loop to iterate through the users imported from the userlist.csv file. foreach ($user in $users) {
5. Create OUs to hold each batch of users. Check whether the OU exists before creating it using the [ADSI] type accelerator’s Exists() static method. if (-not [adsi]::Exists("LDAP://OU=$($user.Department), DC=contoso,DC=com")) { $objOU = $objDomainRoot.Create("organizationalunit","OU=$($user.Department)") $objOU.SetInfo() }
6. Create the department global groups. Check whether the group exists before creating it using the [ADSI] type accelerator’s Exists() static method. if (-not [ADSI]::Exists("LDAP://CN=$($user.Group),OU=$($user.Department),DC=contoso,DC=com" )) { $objOU = [ADSI]"LDAP://OU=$($user.Department),DC=contoso,DC=com" $objGroup = $objOU.Create("group","CN=$($user.Group)") $objGroup.SetInfo() }
7. Create department manager user accounts. Check whether they exists before creating them using the [ADSI] type accelerator’s Exists() static method. if (-not [ADSI]::Exists("LDAP://CN=$($user.Manager),OU=$($user.Department),DC=contoso,DC=co m")) { $objOU = [ADSI]"LDAP://OU=$($user.Department),DC=contoso,DC=com" $objUserManager = $objOU.Create("user","CN=$($user.Manager)") $objUserManager.SetInfo()
9. Take the first letter of current user’s firstname property and concatenate it with the surname property. $samaccountname = $user.firstName.substring(0,1) + $user.Surname # create the user object in the correct OU for the department $objOU = [ADSI]"LDAP://OU=$($user.Department),DC=contoso,DC=com" $objUser = $objOU.create("user","CN=$samaccountname") $objUser.SetInfo()
10. Set the account’s single valued attributes using the Put() method. $objUser.Put("givenName",$user.firstName) $objUser.Put("sn",$user.Surname) $objUser.Put("samaccountname",$samaccountname) $objUser.Put("displayName",$samaccountname) $objUser.Put("UserPrincipalName","[email protected]") $objUser.Put("company","Contoso") $objUser.Put("department",$user.Department) $objUser.Put("homePhone","029870112233") $objUser.Put("postOfficeBox","100") $objUser.Put("streetAddress","1 Epping Road") $objUser.Put("l","Sydney") $objUser.Put("st","NSW") $objUser.Put("postalCode","2122") $objUser.Put("c","AU") $objUser.Put("co","Australia")
11. Set the otherHomePhone multivalued attribute using the PutEx() method. $arrPhone = "029870123456","029870123457","029870123458" $objUser.PutEx(2,"otherHomePhone",$arrPhone) $objUser.SetInfo()
12. Set the user’s manager attribute to the DN of the manager account. $objUserManager = [ADSI]"LDAP://CN=$($user.Manager),OU=$($user.Department),DC=contoso,DC=com" $objUser.Manager += $objUserManager.distinguishedname
13. Add the user to the department global group. $objGroup = [ADSI]"LDAP://CN=$($user.Group),OU=$($user.Department),DC=contoso,DC=com" $objGroup.Add($objUser.path) $objGroup.SetInfo()
14. Enable the user account. $uac = $objUser.UserAccountControl.value $objUser.UserAccountControl = $uac -bxor ($NORMAL_ACCOUNT + $ACCOUNTDISABLE) $objUser.SetInfo() "Created User: $($objUser.distinguishedname)" }
15. Run the script, and confirm that it worked correctly by checking ADUC, verify that the users had been created in the LabUser OU.
Lesson 8 Demonstration : Active Directory Administration (cmdlets) Introduction In Windows Server 2000, Windows Server 2003, and Windows Server 2008, administrators used a variety of command-line tools and Microsoft Management Console (MMC) snap-ins to connect to their Active Directory domains to monitor and manage them. The Active Directory module for Windows Powershell now provides a centralized experience for administering your directory service installation. With the introduction of the new Active Directory cmdlets Active Directory Domain Services (ADDS) administrators can avoid the native .net class based complex codes. The Active Directory module provides a host of cmdlets that comparatively reduce the length of the scripts. These are equally capable of performing complex operations on the Active Directory objects.
Objectives After completing this lab, you will be able to:
Understand Active Directory administration with Windows Powershell, using the Active Directory module and cmdlets
Pre-requisites Windows 2008 Server and Windows 7 workstation logged onto with Domain Administrator credentials
Exercise 1: Using the Active Directory Module Objectives In this exercise, you will:
Understand the usage of the Active Directory cmdlets
Learn about the prerequisites for the Active Directory module
Open windows PowerShell and load the Active Directory module
Scenario The Active Directory module for Windows PowerShell is a Windows PowerShell module, named ActiveDirectory, that consolidates a group of cmdlets. These cmdlets can be used to manage the Active Directory domains in a single, self-contained package.
Prerequisites Windows PowerShell and the .NET Framework 3.5.1 must be installed on a Windows Server 2008 R2 or Windows 7 computer to use the Active Directory module. You can install the Active Directory module by using any of the following methods:
By default, on a Windows Server 2008 R2 server when you install the ADDS
By default, when you make a Windows Server 2008 R2 server a Domain Controller
As part of the Remote Server Administration Tools (RSAT) feature on a Windows Server 2008 R2 server
As part of the RSAT feature on a Windows 7 computer
If you want to use the Active Directory module to manage an Active Directory domain, the Active Directory Web Services (ADWS) service must be installed on at least one Domain Controller in this domain.
ADWS is installed and runs by default on a Windows Server 2008 R2 Domain Controller.
For Domain Controllers running on Windows Server 2008, Windows Server 2003 R2 SP2 and Windows Server 2003 SP2 install the Active Directory Management Gateway Service that provides a Web service interface to Active Directory domains
The Active Directory module is available in the following editions of Windows Server 2008 R2 and Windows 7:
Windows Server 2008 R2 Standard
Windows Server 2008 R2 Enterprise
Windows Server 2008 R2 Datacenter
Windows 7
Now you will load the Active Directory module for Windows PowerShell in different ways.
Task 1: Log on to the VM environment Log on to the Windows 7 client as Contoso\Administrator
Task 2: Import/Load the Active Directory module There are different ways to open and load the Active Directory module for Windows PowerShell. Before you load the module on a Windows 7 Client, ensure that the Active Directory Module for Windows PowerShell is installed using the Remote Server Administration Tools (RSAT) 1. Open Control Panel and Click on Programs and Features. 2. Click on Turn Windows Features On or Off. 3. Expand Remote Server Administration Tools> Role Administration Tools> AD DS and AD LDS Tools. 4. Ensure that Active Directory Module for Windows PowerShell is checked. Similarly, on Windows Server 2008 R2, you can install the Active Directory module for PowerShell by using the Add Features Wizard. You can follow one of the steps mentioned below to load the Active Directory module for Windows PowerShell. 5. On the Start menu, click on Administrative Tools and then click on Active Directory Module for Windows PowerShell. The AD Web Service (ADWS) running on a Domain Controller is discovered and the Active Directory module is loaded. If the service does not exist or is stopped, the Active Directory module will fail to load. On the windows Task Bar, locate and click the icon. This will open the Windows PowerShell menu. 6. At the PS prompt type the following command. get-module -ListAvailable
The output lists of all the modules can be imported into the session. 7. Now type the following command. Import-Module Activedirectory
8. You can list all cmdlets available from this module, as follows: Get-Command -Module "ActiveDirectory"
Exercise 2: Using the Active Directory Provider Scenario In the previous modules, you have learned that Windows PowerShell Providers are .NET Framework based programs that make the data in a specialized data store available, to allow you to work as if they were mounted drives. Administrators can use the Active Directory module provider to navigate and access data stored in the Active Directory domains. The Active Directory module provider exposes the Active Directory database through a hierarchical navigation system, which is very similar to the file system. For example, while you are using the Active Directory module, you can use the following commands to navigate through your directory: Cd, dir, remove
Task Description 1. You can use the Active Directory module provider to map Active Directory domains to specific provider drives. When the Active Directory module is first loaded, a default Active Directory drive (AD:) is mounted with the root path set to RootDSE of the local forest. To connect to the AD: drive, run the following command: PS c:\>cd AD:\
2. To enumerate the partitions in the forest, use dir (gci/get-childitem) PS AD:\> Get-ChildItem Name ---contoso Configuration Schema
The Active Directory provider can be used to easily connect to any of the partitions to query or make changes. 3. To connect to a domain, type the following command: PS AD:\> Cd “dc=contoso,dc=com” PS AD:\DC=contoso,DC=com>
4. Using dir, you can enumerate the objects in the domain, as follows: PS AD:\DC=contoso,DC=com> dir
5. You can also connect to a child OU or container using its Distinguished Name (DN) or Relative Distinguished Name (RDN). The following command will set the location to the drive AD:\OU=Test,DC=contoso,DC=com
6. The Active Directory PSProvider can be used to create a PSDrive, which connects to the Active Directory with specific or logged on credentials. The following command creates a new provider drive to an Active Directory domain using the New-PSDrive cmdlet: New-PSDrive -PSProvider ActiveDirectory -Name Contoso ` -Root "AD:\dc=contoso,dc=com"
The other optional parameters commonly used with the cmdlet New-PSDrive are Server and Credential. 7. In order to use the domain, server, credentials or set the search base to a specific path of the drive, set the location (cd) to the created PSDrive. PS c:\>set-location PS Contoso:\>
Contoso:\
Certain generic cmdlets shown in the following table can be used with the Active Directory provider. Get-PSProvider
New-PSDrive
Get-PSDrive
Remove-PSDrive
Get-ChildItem
Get-Item
New-Item
Remove-Item
Move-Item
Rename-Item
Get-ItemProperty
Set-ItemProperty
Clear-ItemProperty
Get-ACL
Set-ACL
Objects can be searched, added, deleted or modified using Active Directory cmdlets, which will be covered in the later sections of the module.
Exercise 3: Cmdlets and Identity Scenario The Active Directory module cmdlets can be used to perform various administrative, configuration, and diagnostic tasks in your AD DS environments. The Active Directory module can also be used to manage the existing Active Directory user and computer accounts, groups, organizational units (OUs), domains and forests, domain controllers, and password policies, or to create new ones. To list all the cmdlets that are available in the Active Directory module run the following command Get-Command –module ActiveDirectory
The Active Directory cmdlets can be used to retrieve information, add, create, delete, move, rename, reset, restore, search objects, set properties, enable or disable objects and features and unlock accounts. A group of tasks can be completed using the cmdlets to manage the following:
Account Management
Group Management
Managed Service Accounts
Organizational Units
Password Policies
Optional Features
Search\Modify Objects
Forest and Domain Management
Domain Controller
Operations Master Management
Task 1: Connecting to the local domain 1. The command to get the local ADDomain object by using your current credentials is: PS AD:\> Get-ADDomain
Task 2: Connecting to the Global Catalog 2. To connect to a specific domain controller or port, you can use the -Server parameter. For instance, the following will retrieve all users found in the Global Catalog on SYDDC01: PS AD:\> Get-ADUser –Filter * -server syddc01.constoso.com:3268
Task 3: Miscellaneous Operations 3. Get all the members of the 'Schema Admins' group including the members of any nested groups. get-adgroupmember "Schema Admins" -recursive
4. Create a new user named 'Tkim' and set the EmployeeID and mail attributes. New-ADUser tkim –OtherAttributes @{employeeid="12345";mail="[email protected]"}
Task 4: Identity Parameter Almost all of the Active Directory cmdlets have an identity parameter for targeting a single Active Directory object. This parameter can also be used as the first positional argument for quick use. For each object type, the identity parameter searches a set of attributes to find a single match. If for some reason more than one object is found, an error will be returned. The following table covers some of the attributes searched when you specify the identity parameter: Cmdlet Noun ADComputer
Distinguished Name GUID (objectGUID) Security Identifier (objectSid) Security Accounts Manager Account Name (sAMAccountName) Distinguished Name GUID (objectGUID) Security Identifier (objectSid) DNS domain name NetBIOS domain name GUID (objectGUID) IPV4Address Global IPV6Address DNS Host Name (dNSHostName) Name of the server object Distinguished Name of the NTDS Settings object Distinguished Name of the server object that represents the domain controller GUID of NTDS settings object under the configuration partition GUID of server object under the configuration partition Distinguished Name of the computer object that represents the domain controller Fully qualified domain name (FQDN) DNS host name NetBIOS name Distinguished Name
GUID (objectGUID) Security Identifier (objectSid) SAM User Name (sAMUserName) Distinguished Name GUID (objectGUID) Security Identifier (objectSid) SAM User Name (sAMUserName) Distinguished Name GUID (objectGUID) Distinguished Name GUID (objectGUID)
1. The following examples show how the identity parameter is used to retrieve a specific user by using different attributes: #match on SamAccountName PS Contoso:\> Get-ADUser -Identity "tkim"
Exercise 4: Searching Active Directory using Cmdlets Scenario The Active Directory cmdlets with the Verb ‘Get’ are used to search or enumerate objects from Active Directory.
Task Description 1. Type the following commands to list the cmdlets used to search AD object(s) of various classes. PS Contoso:\> gcm get-ad* | ft name Name ---Get-ADAccountAuthorizationGroup Get-ADAccountResultantPasswordReplicationPolicy Get-ADComputer Get-ADComputerServiceAccount Get-ADDefaultDomainPasswordPolicy Get-ADDomain Get-ADDomainController Get-ADDomainControllerPasswordReplicationPolicy Get-ADDomainControllerPasswordReplicationPolicyUsage Get-ADFineGrainedPasswordPolicy Get-ADFineGrainedPasswordPolicySubject Get-ADForest Get-ADGroup Get-ADGroupMember Get-ADObject Get-ADOptionalFeature Get-ADOrganizationalUnit Get-ADPrincipalGroupMembership Get-ADRootDSE Get-ADServiceAccount Get-ADUser Get-ADUserResultantPasswordPolicy
2. In the previous exercise, you have discussed about retrieving object information using the Identity parameter. For example: Get-ADUser -Identity tkim
In order to search the Active Directory based on a pattern or criteria, using an appropriate filter syntax becomes important. You can use the Filter or LDAPFilter parameter to specify a query string that retrieves Active Directory objects. In addition, certain parameters such as ResultPageSize, SearchBase or SearchScope can be used to search the Active Directory efficiently. 3. The following command gets all the Security groups that have a Group Scope of DomainLocal in the OU named Test1. get-adgroup -Filter 'GroupCategory -eq "Security" -and GroupScope -eq "DomainLocal"' –SearchBase ‘OU=Test1,dc=contoso,dc=com’
4. In order to search objects in the ‘Deleted Objects’ container, use the IncludeDeletedObjects parameter as shown below. Get-ADObject -Filter 'samaccountname -like "Vendor*"' -IncludeDeletedObjects
Exercise 5: Creating Active Directory Objects using Cmdlets Objectives In this exercise, you will explore some of the Active Directory cmdlets used to create objects.
Task Description 1. In your PowerShell console, type the following commands to get the cmdlets used to create new AD objects of various classes. PS Contoso:\> gcm new-ad* -commandtype cmdlet | ft name Name ---New-ADComputer New-ADFineGrainedPasswordPolicy New-ADGroup New-ADObject New-ADOrganizationalUnit New-ADServiceAccount New-ADUser
2. To create new users, you can use the New-ADUser cmdlet, as shown in the following example: PS Contoso:\> $pass = ConvertTo-SecureString "P@ssword1" -AsPlainText –Force PS Contoso:\>New-ADUser -SamAccountName "Dpark" -Name "Dan Park" ` -GivenName "Dan" -Surname "Park" ` -Department "IT" -AccountPassword $pass ` -UserPrincipalName "[email protected]"
The ConvertTo-SecureString cmdlet shown above creates a secure string which is needed to specify the User Account password. 3. Consider another scenario where you will create a list of users from a CSV file. The column headers in the CSV file may or may not match the Active Directory attribute names used by New-ADUser cmdlet. For instance, if the column headers are “GivenName”, “Surname,” “Title,” “Department,” “EmployeeId”, “Mail” and so on, or assuming that after receiving the CSV file you modified the column headers to match the attribute names, the following command will create bulk users. PS Contoso:\>Import-CSV c:\pshell\part1\lesson8\userlist.csv | New-ADUser
4. If the column headers do not match the attribute names, the cmdlet Select-Object can be used to calculate the properties as shown in the following example. PS Contoso:\>Import-CSV c:\pshell\part1\lesson8\userlist.csv | Select ` @{Name="GivenName";Expression={$_."First Name"}}, ` @{Name="Surname";Expression={$_."Last Name"}}, `
5. Now explore the cmdlet New-ADGroup to create a new group named 'Managers' in the container 'CN=Users,DC=Contoso,DC=Com' and set the GroupCategory, DisplayName, GroupScope, and Description properties on the new object. C:\PS>New-ADGroup -Name "Managers" -SamAccountName Managers -GroupCategory Security -GroupScope Global -DisplayName "Managers" -Path "CN=Users,DC=Contoso,DC=Com" -Description "Members of this group are floor Managers”
Exercise 6: Modifying Objects using Cmdlets Scenario Now that you are familiar with cmdlets used to search and create objects, you can explore some of the Active Directory cmdlets used to modify existing AD objects.
Task Description 1. In your PowerShell console, type the following command to get the cmdlets used to modify AD objects of various classes. PS Contoso:\> gcm set-ad* -commandtype cmdlet | ft name Name ---Set-ADAccountControl Set-ADAccountExpiration Set-ADAccountPassword Set-ADComputer Set-ADDefaultDomainPasswordPolicy Set-ADDomain Set-ADDomainMode Set-ADFineGrainedPasswordPolicy Set-ADForest Set-ADForestMode Set-ADGroup Set-ADObject Set-ADOrganizationalUnit Set-ADServiceAccount Set-ADUser
2. A simple example shown below updates the company and department attributes on a single target identity. Set-ADUser Dpark -Company ‘Contoso’ -Department 'Sales'
Bulk Modifications You might encounter scenarios with many users in an environment, who do not have a UserPrincialName (UPN) configured. In these scenarios, you can use Get-ADUser to search for users without a UPN and pipe the results to Set-ADUser to modify the user accounts. 3. If you simply want to set the user account to be the sAMAccountName with the domain suffix, you can use a command similar to the one shown below: Get-ADUser -filter {UserPrincipalname -notlike "*"} | ForEach-Object {Set-ADuser Identity $_ -UserPrincipalName "$($_.sAMAccountName)@contoso.com"}
Exercise 7: PowerShell Credential Objects and Using Alternative Credentials for Cmdlets Scenario The Active Directory cmdlets have the Credential parameter to use alternate credentials to perform a task in the current session. The default credentials are the credentials of the currently logged-on user, unless the cmdlet is run with the account associated with an Active Directory PowerShell provider drive. To specify this parameter, you can type a user name, such as "Contoso\User01" or you can specify a PSCredential object.
Task Description 1. If you specify a user name for this parameter, the cmdlet prompts for a password. Get-ADComputer –filter ‘samaccountname –notlike “syd*”’ –searchbase ‘OU=Domain Controllers,DC=contoso,dc=com’ -credential contoso\administrator
2. You can also create a PSCredential object by using a script or by using the GetCredential cmdlet. You can then set the Credential parameter to the PSCredential object. 3. The following example shows how to create credentials. $DomainCreds = Get-Credential "Contoso\administrator"
4. The following shows how to set the Credential parameter to these credentials. Get-ADuser –Identity tkim -Credential $DomainCreds
5. Often, when using alternate credentials or specifying specific server connection settings, it can become tedious to specify these parameters for every cmdlet being used. In addition, each time you specify these parameters, a new session is set up, which has some performance costs associated with it. A better approach is to use the Active Directory PSProvider to create a PSDrive, which connects to the Active Directory. New-PSDrive -PSProvider ActiveDirectory -Name Contoso -Root ` "AD:\dc=contoso,dc=com" –credential $DomainCreds
The syntax shown above creates a PSdrive named Contoso connected with the credentials specified in the DomainCreds variable.
Lesson 8 Hands-On : Active Directory Administration (cmdlets) Objectives The objective for this lab is to explore creating, modifying and searching Active directory objects using the Windows PowerShell Active Directory Cmdlets.
Prerequisites The lab requires a windows 7 client running in a domain environment.
Exercise 1: Creating Multiple Users in an Organizational Unit Objectives In this exercise, you will:
Create an Organizational Unit (OU)
Create nine temporary user accounts in the OU using concatenation
Specify certain attribute values for the users from a text file, populate those on the General, Address and Profile tabs
Scenario The AD administrator of Contoso Limited receives a request for creating lab users for their development work. The users belong to the same physical location, hence a common address. In addition to the name, surname, UPN and e-mail address attributes, the users would also have a home directory and roaming profile stored on the respective shares on the server Syddc01. The administrator will have to automate the user creation using the Active Directory modules for Windows PowerShell.
Duration 10 minutes
Task 1: Develop a script that will create AD Objects 1. Log on to the VM environment: Log on to Windows 7 Enterprise client as Contoso\Administrator with Password P@ssword 2. Open Notepad or another script editor 3. Open the file c:\pshell\part1\lesson8\lab8\address.txt. This file contains the address details that will be used for the test users. 4. Create a new file in the ISE or notepad and save it as c:\pshell\part1\lesson8\labs\lab8ex1.ps1 5. For the first line of the file enter the following code $error.clear()
This will ensure that only errors related to the script are reported. 6. Type the following line to load the Active Directory module. Import-module activedirectory
7. In order to create an OU named “LabUsers” in which the users will be created, type the following line New-ADOrganizationalUnit -Name LabUsers -Path "DC=CONTOSO,DC=COM”
8. Type the following code for the next line of the script $aryText = Get-Content -Path "c:\pshell\part1\lesson8\labs\address.txt"
This will load the address details from the file that will be used for the user accounts. 9. On the next line, type the following code to create a variable for the username prefix. $Username = "LabUser"
10. On the next line, type the following code to create the variable for the max user count. $intUsers = 9
11. On the next line, type the following code to create a variable for the user path. $userpath = "OU=LabUsers,DC=contoso,DC=com"
12. On the next line, type the following code on the next line to start the for loop. for ($i=1; $i -le $intUsers; $i++)
13. On the next line, type the following code to open the script block. {
14. On the next line, type the following code to create each user account with the attributes to be populated in the General, Address and Profile tabs. new-aduser -name $username$i -samaccountname $username$i -path $userpath ` -displayname "$username$i" -givenname "$username$i" -surname "surname" ` -Initials $i -Description $($aryText[0]) ` -UserPrincipalName "[email protected]" ` -EmailAddress "[email protected]" -StreetAddress "$($aryText[1])" ` -city "$($aryText[2])" -state "$($aryText[3])" -PostalCode "$($aryText[4])" ` -OfficePhone "02-$i$i$i$i-$i$i$i$i" ` -ProfilePath "\\syddc01\users\$username$i" -HomeDrive "h" ` -HomeDirectory "\\syddc01\userdata\$username$i"
15. On the next line, type the following code to close out the For loop. }
16. Now save the script. 17. Launch “Windows PowerShell” session. 18. In the PowerShell console, type the following to execute the script. c:\pshell\part1\lesson8\labs\lab8-ex1.ps1
The script should execute and create the users and populate the user properties. 19. In ADUC, check for the users in the LabUsers OU.
Exercise 2: Modifying AD objects via Cmdlets Objectives In this exercise, you will:
Modify the attributes of existing users using the Set-ADuser cmdlet
Perform a bulk deletion of the lab users
Scenario The Contoso management requires redeployment of first five lab users to a different development project. From now on, those lab users will be located at a different office. The AD administrator requires to automate the change of address details using the Active Directory modules for Windows PowerShell.
Duration 10 minutes
Task 1: Develop a script to modify AD Objects 1. Log on to the VM environment: Log on to Windows 7 Enterprise client as Contoso\Administrator with Password P@ssword 2. Open Notepad or another script editor. 3. Open the file c:\pshell\part1\lesson8\labs\NewAddress.txt. This file contains the new address details of the relocated lab users. 4. Create a new file in the ISE or notepad and save it as c:\pshell\part1\lesson8\labs\lab8ex2.ps1 5. For the first line of the file, enter the following code. $error.clear()
This will ensure that only errors related to the script are reported. 6. Type the following line to load the Active Directory module. Import-module activedirectory
7. Type the following code for the next line of the script. $aryText = Get-Content -Path "c:\pshell\part1\lesson8\labs\NewAddress.txt"
This will load the address details from the file that will be used to change or update the address details of the user accounts. 8. On the next line, type the following code to create a variable for the username prefix. $Username = "LabUser"
9. On the next line, type the following code to create the variable for the max user count to be modified. $intUsers = 5
10. On the next line, type the following code on the next line to start the For loop. for ($i=1; $i -le $intUsers; $i++)
11. On the next line, type the following code to open the script block. {
12. On the next line, type the following code to modify the target user accounts’ address details. set-aduser -identity $username$i -StreetAddress "$($aryText[0])" ` -city "$($aryText[1])" -state "$($aryText[2])" -PostalCode "$($aryText[3])"
13. On the next line, type the following code to close out the For loop. }
14. Now save the script. 15. Launch “Windows PowerShell” session. 16. In the PowerShell console, type the following to execute the script. c:\pshell\part1\lesson8\labs\lab8-ex2.ps1
The script should execute and modify the users’ address details. In ADUC, refresh the view and check for the users in the OU. 17. Check one of the users Address property tab. You will see that the user properties have been modified. 18. Open the script c:\pshell\part1\lesson8\lab8\lab8-ex2.ps1 and save it as c:\pshell\part1\lesson8\lab8\lab8-ex2a.ps1 19. Now delete the following lines of code from the script. set-aduser -identity $username$i -StreetAddress "$($aryText[0])" ` -city "$($aryText[1])" -state "$($aryText[2])" -PostalCode "$($aryText[3])"
20. Now type the following code between the { and } lines Remove-aduser -Identity "$username$i"
21. Save the script. 22. The new script will now delete the lab user accounts from Active Directory. 23. In the PowerShell console, type the following to execute the script. c:\pshell\part1\lesson8\lab8\lab8-ex2a.ps1
Exercise 3: Searching AD objects via Cmdlets Objectives In this exercise, you will:
Search Active Directory based on a filter syntax
Use the cmdlet Get-AdUser
Scenario During an Active Directory disaster recovery exercise, Contoso DR management team expressed the requirement to have a script that would populate all the objects that have been deleted in the last seven days. The AD administrator will need to write the script that will search the Deleted Objects container and list the objects deleted in the last seven days.
Duration 10 minutes
Task 1: Find AD Objects deleted in the past 7 days 1. Log on to the VM environment: Log on to on to Windows 7 Enterprise client as Contoso\Administrator with Password P@ssword 2. Open Notepad or another script editor. 3. Create a file named c:\pshell\part1\lesson8\labs\lab8-ex3.ps1 in notepad or the PowerShell ISE and save it. 4. For the first line of the file, after the comment section (#), enter the following code. $error.clear()
This will ensure that only errors related to the script are reported. 5. Type the following line to load the Active Directory module. Import-module activedirectory
6. Type the following code for the next line of the script to specify the CSV file path to which the output will be exported. $csvpath = "c:\pshell\part1\lesson8\labs\deletedobjects.csv"
7. On the next line, type the following code to create a variable to store the datetime (current date – 7 days) object. $deletedindays = (get-date).adddays("-7")
8. On the next line, type the following code to create the variable for the search filter string. $searchfilter= 'isdeleted -eq $true -and whenchanged -gt $deletedindays'
The filter above would search for objects that have their IsDeleted attribute set to True and the whenchanged attribute is within the last 7 days. 9. On the next line, type the following code to search AD according to the filter string (including the Deleted Objects container) and store the result in the designated CSV file. Get-ADObject -Filter $searchfilter -IncludeDeletedObjects | select name,objectclass | export-csv -Path $csvpath -notypeinformation
10. Now save the script. 11. Launch “Windows PowerShell” session. 12. In the PowerShell console, type the following to execute the script. c:\pshell\part1\lesson8\labs\lab8-ex3.ps1
The script should execute and search the deleted objects. 13. Open the CSV file "c:\pshell\part1\lesson8\lab8\deletedobjects.csv" and check for the desired results. notepad "c:\pshell\part1\lesson8\labs\deletedobjects.csv"
Lesson 9 Demonstration : Windows Management Instrumentation (WMI) Introduction In this section, you will cover the core concepts of Windows Management Instrumentation, better known as ‘WMI’. These concepts include working with classes, gathering data both locally and remotely as well as real-world applications.
Objectives After completing this lab, you will be able to:
Describe the core WMI concepts in Windows
Leverage the Get-WMIObject cmdlet to access WMI from within PowerShell
Review some of the most commonly used WMI classes
Discover gathering data remotely using Get-WMIObject
Filter and sort returned WMI data
Provide best practices when leveraging WMI in scripting
Prerequisites
A Windows 7 workstation logged in with administrator credentials
A Windows 2008 server logged in with administrator credentials
Exercise 1: Introduction to WMI Objectives In this exercise, you will:
Learn the fundamentals of WMI.
Identify the basic WMI components and related tools in Windows.
Understand basic information related to the service.
Scenario WMI is an integral part of Windows infrastructure and is installed by default. In this scenario, we will explore the WMI Management console and underlying services.
Task 1: Log on to the VM environment Log on to Windows 7 Enterprise client as:
Username: Contoso\Administrator
Password: P@ssword
Task 2: Open Windows PowerShell On the Windows taskbar, click
.
The PowerShell console opens.
Concepts of Instrumentation Instrumentation is the act of making data available through an avenue of communication. In programming terms, that translates to being able to gather trace information, performance data or verbose error logging. Instrumentation can be fully understood in a more familiar context. Consider an automobile. When we want to know the status of a vehicle's component, we rely on instrumentation to do it. Since we cannot “speak” directly to the car, we have to use an infrastructure that allows communication. The gauge on the dashboard interacts with various sensors throughout the vehicle and translates data, allowing you to see various conditions (such as current speed and fuel level). Hardware (Engine)
Data Translation (Gauge)
Raw data
Object
User readable
Instrumentation in Windows is very similar. It allows drivers and components to output data that can then be used by users or other processes. This effectively allows us to “speak” to deeper layers of the OS and hardware.
WMI Organization WMI is built around the concepts of Classes, Instances and Namespaces. A Class is essentially anything WMI can manage. It is a template for an underlying object and describes its function. All objects of each Class follow the same basic layout; however, the actual data they contain is unique to that object. Common Class Types Hardware Classes Software Classes Operating System Classes Performance Counter Classes
Describe Hardware events/data (static) Describe Software events/data (dynamic) Describe OS specific information Describe Performance data (Perfmon) counters
An Instance represents the objects within each class. Each object follows a template described by the parent Class in which it resides. Namespaces are logical groupings of Classes.
Namespace
WMI Class
Object Instance
WMI Class
Object Instance
Object Instance
Object Instance
All content for WMI resides in a database known as a Repository. The default Repository location in Windows is: %Systemroot%\WBEM\Repository
Task 3: Work with WMI: Control Console 1. Click Start > Run, and type the following command: WMIMGMT.MSC
2. Explore the WMI tabs for information. From this pane, you can gather basic information such as location of WMI repository on disk, WMI revision and Security information.
Task 4: Inspect the WMI Services 1. Using SC.EXE from the Command line to gather service information, you can see several key pieces of data on the WMI management service: C:\> sc.exe qc winmgmt SERVICE_NAME: winmgmt TYPE
The PowerShell output varies slightly from the SC.EXE returned information.
Task 5: List WMI Namespaces 1. In the PowerShell console, type the following command to list the WMI namespaces. Get-wmiobject –class __namespace –namespace root | select name
You will now see a list of the available namespaces in the WMI repository from the root. This, however, is only the top layer of the available namespaces. There are subnamespaces available but the command above does not display them. 2. In the PowerShell console, run the script recurse-namespaces.ps1
This script will display all the namespaces and sub-namespaces available for the current machine. For almost all purposes, you will use the root\cimv2 namespace. function searchns($ns) { write-host $ns -foregroundcolor white $colns = get-wmiobject -namespace $ns -class "__namespace" if ($colns -ne $null) { foreach ($i in $colns) { $subns = $i.__namespace+"\"+$i.name searchns($subns) } } } Write-host "The Following are all the namespaces and sub namespaces in `n WMI on the local machine" -foregroundcolor green searchns("root")
This script will now display the full list of available WMI namespaces and sub-name spaces. You will notice that there are many available namespaces and sub-namespaces.
Exercise 2: WMI Classes and Queries Now you will explore the types of data that can be returned from WMI via PowerShell. The primary and most common cmdlet for accessing WMI data is the Get-WmiObject commandlet. From this point forward, you will be primarily working with this commandlet and the subset of returned data. However, before looking into the cmdlet you need to list the available classes for a given namespace.
Task 1: List Available Classes 1. From the PowerShell console, type the following to list the available classes. Get-wmiobject -list
You will now see a list of the available WMI classes for the root\cimv2 namespace. Root\cimv2 is the default namespace used by WMI. This default namespace is used by the get-wmiobject Cmdlet if you do not specify it. 2. Type the following to display only the names of the WMI classes. Get-wmiobject –list | select name
Task 2: Understand WMI Metadata You will notice that in addition to the normal WMI classes, you also have metadata classes. Metadata is information about WMI. This could be:
Data about namespaces or classes
Other WMI information such as configuration
Additional information about a WMI class such as its superclass
The WMI metadata is visible as anything that starts with a double underscore or __. This makes it easy to filter as you can look for anything that does not start with __. 1. Type the following in the PowerShell console to filter out the metadata classes. Get-wmiobject –list | where-object {$_.name –like win32_*}
As you can see from the output, this displays all the properties of the class without the metadata. You can use the range wildcard to out the metadata for all WMI classes and other queries.
Task 3: Understand the Get-WMIObject Cmdlet The get-wmiobject cmdlet is the cmdlet that allows us easy access to WMI data from within PowerShell. This cmdlet allows for very simple access to local WMI data, as well as more complex access such as remoting and WMI queries. This cmdlet has been available from PowerShell version 1 and at that time was one of the few cmdlets that supported remote data collection. In PowerShell 2.0, the ability to use WMI as a background job as well as the ability to use WMI events. 2. From within the PowerShell console, inspect what the get-wmiobject cmdtlet can do Microsoft | Services
1. From the examples, it appears that the get-wmiobject cmdlet can return a wide variety of data from WMI objects. Now, perform a basic query on a Logical Disk Class. Get-WmiObject –Class “Win32_LogicalDisk”
You will notice that in this query, the namespace is not specified. PowerShell will use:
The default WMI scripting namespace defined via the WMI control console, or
What is defined in the registry key HKLM:\Software\Microsoft\WBEM\Scripting Default namespace
From this simple query, you can gather some useful information related to the current diskrelated hardware on the machine. The first entry lists the DeviceID “C:” and a DriveType of 3. There are other fields designating metrics such as Total Size and Volume Name. The second entry had a DeviceID of “E:” and has a different DriveType of 5. Note that there is no data for other fields. DriveType Reference # Type: -------------------------------------------------------------------------------------------------------------1 No Root Directory 2 Removable Disk 3 Local Disk 4 Network Drive 5 Compact Disc 6 RAM Disk
From this quick data collection, you can infer that “C” is a Hard Disk approximately 500Gigabytes in size, while “E” is a CD/DVD unit with no media loaded. For further details, you can use the WMI SDK file reference that is on the desktop of the workstation. The file is WMISKD_School.chm. You can find details for every WMI class in the MSDN documentation website.
Now, expanding on that concept, look at the Win32_Bios class and see what data can be gathered about the machine: PS> Get-WmiObject –Class Win32_Bios
SMBIOSBIOSVersion Manufacturer Name SerialNumber Version
: : : : :
090004 American Megatrends Inc. BIOS Date: 03/19/09 22:51:32 Ver: 09.00.04 0654-6116-5806-0058-2049-6801-11 VRTUAL - 3000919
This returned only a small portion of the available data held in the Win32_Bios class. To get the full output, pipe the contents to a Format-List. Get-WmiObject –class Win32_Bios | fl *
You will see here that the WMI metadata is also returned. To filter this metadata out, you can use the a-z range wildcard. Type the following to filter out the metadata and display only the properties for the class. Get-wmiobject –class win32_bios | format-list [a-g]*
In some cases, other cmdlets use WMI to return data (although often filtered in some fashion). Now, compare the output from Get-Service to Get-WmiObject against the Netlogon service: Get-wmiobject Win32_Service| ?{$_.name –eq “netlogon”} | fl * Name Status ExitCode DesktopInteract ErrorControl PathName ServiceType StartMode AcceptPause AcceptStop Caption CheckPoint CreationClassName
: : : : : : : : : : : : :
Netlogon OK 1077 False Normal C:\Windows\system32\lsass.exe Share Process Manual False False Netlogon 0 Win32_Service
Description : Maintains a secure channel between this computer and the domain controller for authenticating users and services. If this service is stopped, the computer may not authenticate users and records. If this service is disabled,any services that explicitly depend on it will fail to start. DisplayName InstallDate ProcessId ServiceSpecificExitCode Started StartName State SystemCreationClassName
Name RequiredServices CanPauseAndContinue CanShutdown CanStop DisplayName DependentServices MachineName ServiceName ServicesDependedOn ServiceHandle Status ServiceType Site Container
Both methods of access return data related to services, but the WMI object directly is far more verbose. To find out what other Classes are available to us, use the Get-WmiObject cmdlet to return an entire list (this may take a minute to enumerate depending on machine speed). PS:> Get-WmiObject -list
As you can see, there are more than a thousand default/base classes available for a wide range of components. Additional classes are often included for different product lines such as SharePoint, IIS and Exchange. If you need information on methods, this code snippet will query WMI and extract all the available methods for all classes. PS:> Get-WmiObject -List * | Where-Object{$_.Methods -ne $Null} | Select-Object -ExpandProperty Methods | Sort-Object Origin,Name | Select-Object Origin,Name -Unique
Task 4: Understand Get-wmiobject Parameters The get-WMIObject cmdlet has additional parameters that are very useful since they can be used to significantly change the behavior of the cmdlet . Some of these make it clear as to what the cmdlet is operating on, while others can change the type of query used by the cmdlet or what credentials or impersonation level the query is run as. Not all parameters will be covered, but some of the important ones that you should be aware of will be. -namespace Parameter The first parameter you will look at is the -namespace. This optional parameter is used to specify the namespace to query. In WMI, you always have to query a namespace; however, for most purposes the default namespace of root\cimv2 is used. In fact, if you do not specify a namespace this is the namespace that will be used. You can test this with the following examples:
1. In the PowerShell console, type the following command and press Enter. Get-wmiobject win32_computersystem
You will see that the information for win32_computer system is displayed. 2. In the PowerShell console, type the following command and press Enter. Get-wmiobject –namespace root\cimv2 win32_computersystem
You will see that the information for win32_computer system is displayed. This is the same as the information displayed when not specifying the namespace. This information is important for two main reasons.
Although most of the information you will be working with will come from root\cimv2, there are times that you may need to get information from other namespaces. An example of this is the System Center Configuration Manager client agent. The Client agent has its own WMI namespace, which can be used to trigger client agent actions such as check for advertisements or perform software or hardware inventory.
The other reason you should know about the -namespace parameter is because the default namespace on the machine might change. While this is rare, if you are writing scripts that rely on the default value and never check it or explicitly specify it, your code could have errors. It is good practice to always specify the namespace in scripts, to ensure you are addressing the correct namespace.
-class Parameter The class parameter is a required parameter and the default parameter. This means that the first value passed to the cmdlet will, by default, be assigned to the class parameter. The class is the WMI class that you wish to obtain information from. For example, the following are the same command: Get-wmiobject win32_process Get-wmiobject –class win32_process
Similarly, always specifying the namespace parameter in scripts, is also a good practice to specify the class parameter. This does not always apply to interactive console use, as it is important to minimize the amount of typing done in the PowerShell console. However, the parameter should always be used in scripts. So, for example, the following should be used in a PowerShell script. Get-wmiobject –namespace “root\cimv2” –class win32_process
-list Parameter The -list parameter is used to list the available classes for a given namespace. If the namespace is not specified then the default name space of root\cimv2 is used. -computer Parameter The -computer parameter is used to specify the computer to be queried. The parameter is optional and the local computer is used unless specified otherwise. In the WMI query language (WQL) that will be covered shortly, the local computer is referred to as a . You can specify the parameter and use the . to ensure you are working against the local computer or you can specify the NetBIOS, FQDN or even IP address of a remote machine to query.
For example, Get-wmiobject –computer syddc01 –namespace root\cimv2 –class win32_share
-credential Parameter Like several other cmdlets , the -credential parameter is used to allow the get-wmiobject cmdlet to be run as another account. This parameter requires a PowerShell credential object. If specified with the username, it will prompt for the password. This is typically used when also specifying the -computername parameter.
For example, $creds = get-credential Get-wmiobject –computer syddc01 –namespace root\cimv2 –class win32_share –credential $creds
-EnableAllPrivileges Parameter The -EnableAllPrivileges parameter is used to enable all privileges for the current user. This is sometimes needed, as some special WMI privileges are used with some methods that are not normally granted by default. The best example of this is the shutdown computer right. If the -EnableAllPrivileges parameter is not specified, calling the method will fail.
Task 5: Understand Queries using WQL WMI contains its own query language, called WMI query language and WQL for short. This language allows complex SQL-like queries to be run against a class or collection of classes to return specific data. However, WQL is not a complete T-SQL language and is instead a limited subset of T-SQL. As a result, WQL only supports fairly simple queries and limited keywords. The more complex programing statements of T-SQL are not available (such as if
statements). If you reference the WMI SDK and look for the topic on WQL, you will find the full list of keywords and operators available for WQL. The basic structure of a WQL query is very similar to SQL.