This article is a text version of a lesson from our free PowerShell and Active Directory Basics video course (to get full access use the secret word "blog").

This video course has proven to be extremely popular around the world and will take you through all the steps to create a complete set of directory service management tools Active Directory starting from the very basics.

Coding with PowerShell

At first, it may seem like a daunting task to get started with PowerShell, especially if over the years you have become accustomed to working with the cmd.exe command line and the so-called “batniks” (files with the .bat and .cmd extensions). In this article, written based on materials from lesson 2 of our video course, we will tell you how and why you should update your PowerShell skills, and also look at the basics of launching the PowerShell editor, master command auto-completion, and how to get up-to-date information in any difficult situation. help and examples.

Executing Commands

The PowerShell console is an interactive environment that allows you to run various commands in real time. Here you do not need to first edit the script in Notepad and only then run it on the command line, which will also significantly save your time.

If you currently work in any organization that exists for more than one day, then you probably already have several small scripts for every day that you run from command line cmd.exe. And this is great news! This means you can just as easily do all this from PowerShell. This was truly a smart design decision on Microsoft's part, as they made the transition to the new solution easier for administrators.

By appearance, the PowerShell editor looks and functions exactly like the cmd.exe command line environment. The techniques and skills you already know will work unchanged in PowerShell. And if you're also looking to upskill yourself and are working to move away from one-off tasks to more automated administration, getting into the habit of running PowerShell rather than the Command Prompt is a great way to start.

All your frequently used utilities such as ping, ipconfig, nslookup, etc. will work exactly as you expect.

How to find PowerShell commands

People love PowerShell because it's so, well, powerful! But that power comes from the absolutely insane amount of built-in capabilities. It's simply not possible, and probably not practical, for someone to remember all the different commands, cmdlets, flags, filters and other ways to tell PowerShell what to do and how to do it.

Luckily, there are several tools built right into the editor to help you deal with this.

Auto-completion of commands by pressing Tab

There is no need to remember different commands or the exact spelling of a command. Dial

Get-c
Now, by pressing the Tab key, you can go through all the available commands starting with the characters that you have already entered. Moreover, this works in any part of the command body that you are trying to reference: in command names and flags, and even when autocompleting full paths on the file system.

Get-Command

Even though Tab completion works great, what happens if you don't know correct name the command you need? In this case, you can use the command to find other available commands: Get-Command.

When looking for a command name, it is important to keep in mind that there is a syntax for them: Verb-Noun. Typically, Verbs such as – Get, Set, Add, Clear, Read and Write and Nouns – files, servers or other entities on your network and applications .

Get-Command is a tool for searching and exploring the commands available on your computer.

Command Syntax in PowerShell

Someone once described the Perl scripting language as “executable line noise”—an incredibly useful tool, with a wildly opaque syntax and a correspondingly high barrier to entry for learning it.

Although if you look at it, the traditional command line in Windows is not so far from this. Consider the general problem of finding all files in a directory whose names begin with 'foo'.

CMD: FOR /D /R %G IN (“Foo*”) DO @ECHO %G
FOR and DO indicate that this is a loop.
The /D flag indicates that this is a loop through all folders
The /R flag specifies to include all files and folders, including subdirectories
The search pattern that defines the set of files we are interested in is indicated by “IN”
ECHO indicates that the script should print the result of each loop and finally
%G is a “forced parameter” and was chosen because Microsoft programmers had previously used the letters A, D, F, N, P, S, T, and X during development. Therefore, starting with G is good form, i.e. To. this gives you the largest set of unused letters for the returned variable path formats (G, H, I, J, K, L, M) - in other words, it's a life hack.

Now compare the PowerShell equivalent:

PowerShell: Get-ChildItem -Path C:\ -Filter ‘Foo*’
The result is the same, but even with such a fairly trivial example, it will be much easier to understand what is happening. It's immediately obvious what each element in the command does and how you can change them. Well, maybe the wildcard '*' is used in both examples, but I think you already know very well what it means - that all elements should start with 'Foo' and something else at the end.

Do you feel your mood gradually improving? Now, what if you want to know how to select only files (not folders) in a path? You can delve into the manuals, or your best friend Can Google help you or can you try to figure it out from the command line? Quick tip: If you're in PowerShell, type “-” and press Tab, go through the flags until the obvious solution appears.

One Long String vs. Object

Nobody needs websites if they are not online. This is why people spend a huge amount of time pretending to be sonar operators on a submarine and "pinging" the availability of their servers (yes, that's why it's called that).

While the output of the Ping command is useful (and you can use ping just as well in the PowerShell console), at the end of the day it's just a big, long string—a series of letters and numbers with some breaks in between.

PowerShell has a command that is similar to Ping, but returns data in a structured manner. This is the Test-Connection command.

Below is the result of this command exchanging packets with the 'DC' server in a completely different, completely structured form:

Not to mention that it's a lot easier to read, but the main thing is that you can now pass this information to the input of another team, make it even more useful (our full video course is designed for this), or simply customize it so that it made more sense.

Built-in help

Up to this point we've been focused on running specific commands using Tab padding, but once you start working with PowerShell more and more commands become more complex with even more complex parameters. While the Verb-Noun syntax helps, it helps even more to have:

1. Current documentation
2. Abundance of examples

Help with Cmdlets

In practice, you should combine Get-Command (to find what you should use) and then use Get-Help to find out how to use that particular command.

A practical example of how to do this: let's say you need to determine all running Windows services on the computer.

To get started, you can look for commands to interact with services:

Get-Command service
Which will tell you right away that you are on the right track. As you consider returning to the standard PowerShell Verb-Noun command syntax, you'd like to figure out how to properly use the 'Get-Service' command.

Microsoft documentation on the Get-Service command
To do this, use the ‘Get-Help’ command. Start typing
“Get-Help -” and then press the Tab key
You'll quickly discover the available options, with "Name" being the most obvious one, so it's worth a try:

Get-Help -Name Get-Service
You will immediately receive the full command syntax (and which options you can include or exclude based on filters).

If you want to explore the command further and drill down to each parameter, type:

Get-Help -Name Get-Service - Parameter Name

Help with PowerShell examples

We are all human and, no offense to Google bot, we all have our own psychological obstacles that we need to overcome when learning something unfamiliar and bring it into a form that we understand in order to accomplish what we need.

By entering “-examples” or adding the “-detail” flag to the “Get-Help” command, you will be given a set of examples to use the command.
For example, here is the output for the command:

Get-Help -Name Get-Service -Examples

Staying Informed

What could be worse than a broken example, or an example with an error in the documentation. This is often due to either outdated documentation, incorrect examples, or updated libraries.

To work around these problems and get new examples and fixes at the same time, enter:

Update-help
and the process of downloading the updated contextual help will begin.

You can help and transfer some funds for the development of the site

03/04/2011 Don Jones

Anyone who has written PowerShell scripts has probably spent a lot of time debugging them. Errors are inevitable when you need to get the computer to perform a particular action. At first glance, PowerShell doesn't have many features that make debugging easier. In this article, we'll look at a few basic debugging techniques and some tricks you can use to avoid errors.

PowerShell doesn't have a built-in graphical debugger for line-by-line inspection of scripts, but free and commercial third-party tools can help. In editors such as Quest Software's PowerGUI (powergui.org), Idera PowerShellPlus ( powershellplus.com) and PrimalScript from SAPIEN Technologies (www.primaltools.com) use various methods of line-by-line execution of PowerShell scripts to see the contents of variables and generally make debugging easier. However, to successfully use any of these tools, you must master general debugging skills.

Before you begin debugging, you need to define the search object, in other words, what is considered an error. There are two distinct types of errors.

First type of error: fat fingers

The first type is a simple syntax error. Typo. Operator failure. Thick fingers. Choose the name you like best. These errors are fairly easy to spot because PowerShell displays a message indicating the line number that contains the invalid character. However, knowing the line number is of little help to Notepad users because the program does not show line numbers. For this reason, it is recommended to replace Notepad with free program PowerGUI or commercial script editor.

The capabilities of commercial editors are not limited to just line numbering, and some of their functions will help prevent typos. The main one is syntax highlighting, that is, the presentation of the source text of the script in different colors. Key Feature color highlighting is that elements are painted in the desired color only if they are spelled correctly. Therefore, it is useful for users of editors with syntax highlighting to learn the color codes for commands, variables, literal strings, etc. If they do not appear in the correct color as you type, an error has occurred. Stop and find out the cause of the error.

If something is missing, signals are sent from PowerShell. Please pay attention to error messages. Very often, administrators have difficulty troubleshooting problems simply because they do not read these messages. When they see red text on the screen, they panic and start trying different ways. But the message indicates which line of the source text contains the error. Therefore, concentrate, read the message carefully, understand its meaning and try to find the cause of the problem.

IN good editor scripts can be obtained Additional information by running a sort of “pre-flight test” of the script in PowerShell. This feature is usually called dynamic syntax checking. Often the user's attention is immediately drawn to simple errors, even before the script is run. Some editors use a red underline (as when checking spelling in Microsoft Word); others use different visual indicators.

Finally, to avoid trouble, follow some rules. Carefully structure your source text so that constructs are indented, aligned with curly braces, as in the following example:

Function get-anything ( # Source )

This is better than the following amorphous notation:

Function get-anything (# Source)

The second type of error: discrepancies between the desired and the actual

As a result of errors of the second type, it is not possible to achieve the desired results. The script runs smoothly, but does not solve the problem. PowerShell usually does not produce these types of error messages, or the messages do not contain useful information. There are only two possible reasons for this type of error.

Logical error. Sometimes programmers make simple logical mistakes. For example, a script has been compiled that must count from 1 to 10:

For ($i=0; $i -lt 10; $i++) ( Write-host $i )

The script runs successfully, but displays the numbers 0 through 9. The result is close, but not exactly what the programmer intended. In this case, it is useful to stop and remember the principles of executing scripts. Imagine how PowerShell program reads the script, note the contents of the variables at each step and the results of each step. For the given scenario, the line of reasoning could be as follows.

First you need to assign the variable $i the value 0 (write $i=0). Is 0 less than 10? Yes, so we use Write-Host to display the value 0 (result 0 is written) and increase the value of the $i variable by one. On at this stage$i contains 1 (write $i=1). Is 1 less than 10? Yes, so the value 1 is displayed (result 0 is written) and the variable $i is incremented by one. Now $i contains 2 (we write $i=2). This number is less than 10, so it is printed on the screen (result 2 is recorded), etc.

This continues until $i reaches 10. The comparison shows that 10 is not less than 10, so PowerShell doesn't display that number. As the example shows, basic logical errors become obvious if you take the time to simply analyze the algorithm.

Wrong assumptions. Step-by-step reproduction of the algorithm will help to find not only elementary, but also more serious logical errors, since the record on paper contains a list of expected states. Suppose the programmer mentally replayed the scenario and wrote down the events that he thought would happen. Something else happens as the script runs. This error can be called “false expectations” or “ignorance.” The reason is simple: the value of a variable, property, or method result is different than expected. As a result of the analysis of the logic of the scenario, a written list of expected states was compiled. You just need to make a similar list with using PowerShell and see what results differ from expected ones. Once you find the differences, you will find the error.

There are two main methods for generating a list in PowerShell that corresponds to the one created during the mental check of the algorithm. These methods are based on the Write-Debug and Set-PSDebug commands. There is a third way using the interactive debugger in the script editor. In essence, this method is a combination of two basic methods that will be discussed in this article. It is useful to master the basic techniques before using more advanced ones. in a convenient way interactive debugger in the editor.

Method 1: Write-Debug

The first method uses the Write-Debug command. By default, the output of this command is suppressed. To enable output, you need to add the line to the beginning of the script

$DebugPreference = "Continue"

You should then enter Write-Debug statements immediately after each statement that changes the contents of a variable, for example:

$var = get-service Write-Debug "`$var contains $var"

Note a little trick: the output of the Write-Debug command is enclosed in double quotes. As a result, the variables are replaced with their contents. The first variable uses a backtick (an escape character in PowerShell), so the $ character is escaped. This causes the first element of $var to be displayed as is and the variable name to be printed to the screen. The second element of $var is replaced with its contents.

You then need to enter a Write-Debug statement into each loop and decision construct. The listing shows how to use the method to for loop and if constructs. The Write-Debug statement in Fragment A uses the same technique with double quotes and a backtick to find out the contents of $i each time the for loop is repeated. The if construct uses two Write-Debug functions, including the else construct (fragment B). This allows diagnostic data to be collected regardless of the branch, despite the fact that there is no code to execute when $i is less than or equal to 2. Note that Write-Debug statements use a single quote to output the variable, so as not to replace $i with it. content.

After adding all the Write-Debug statements, you need to run the script and compare the output with the expected values ​​recorded. Note any differences. Expectations may need to be revised, but any difference should be considered an indication of potential error.

If the script runs as expected, simply replace $DebugPreference at the beginning of the script with

$DebugPreference = "SilentlyContinue"

and the diagnostic output will be suppressed. It is not necessary to remove Write-Debug statements. Leaving them in place can make it easier to debug the script in the future.

Method 2: Set-PSDebug

The second method is based on using the built-in step-by-step debugger Set-PSDebug to execute the script line by line. In long scripts this may seem tedious, but in PowerShell 1.0 you have to make do. PowerShell 2.0 introduced breakpoints, which will be discussed in the next article. With their help, you can set the moment when the script goes into standby mode without executing it line by line.

To launch the debugger, run the command

Set-PsDebug -step

You can disable it later with the command

Set-PsDebug -off

When the debugger is enabled, it affects all scripts (as well as commands entered at the command line). You just need to run the script and start debugging. Each time PowerShell encounters a script line, it displays it and asks for confirmation to continue execution. It's useful to have a printout with numbered lines so you can see exactly where in the script PowerShell is executing. To execute a line, press Enter. During execution, you can compare expected results with those actually obtained.

Do not press Enter every time a script modifies a variable or prepares to access a property of a variable or object. Instead, type S and press Enter. The script pauses and a special prompt appears on the screen. With it you can:

  • access variables to see their contents;
  • run commands to see their results;
  • View object properties to see their contents.

A difference between actual and expected results indicates an error. Issue the Exit command to exit sleep mode and resume execution of the script from where it left off.

It takes some time to get used to the step-by-step debugger. However, it is a useful tool for getting inside the running script.

Ready for debugging?

The debugging procedure does not have to be complicated if taken in a methodical and coordinated manner. Don't be discouraged when you receive an error message. Read carefully and understand the meaning of the message. Treat it as a helpful (if unsolicited) hint.

If the results are not what you expected, document your assumptions and find out why they are not true. The main cause of errors is that the programmer does not know what to expect at each step of the script. This is typical for new administrators who try, for example, to use scripts borrowed from the Internet. By taking the time to learn a script, you will not only speed up your debugging, but you will also learn more about PowerShell and be able to successfully create your own scripts in the future, and the ability to debug will always come in handy on the job.

Don Jones ( [email protected]) - PowerShell instructor (www.windowsitpro.com/go/DonJonesPowerShell), has the title of MVP; author of more than 35 books, speaks at technology conferences such as Microsoft TechEd and Windows Connections


Debugging in Windows PowerShell


Working in the PowerShell shell, we have not yet thought about how the system generates the lines of text that are displayed on the screen as a result of executing a particular command (remember that PowerShell cmdlets return .NET objects, which, as a rule, do not know how display yourself on the screen).

In fact, PowerShell has a database (a collection of XML files) that contains default formatters for various types of .NET objects. These modules determine which object properties are displayed in the output and in what format: list or table. When an object reaches the end of the pipeline, PowerShell determines its type and looks for it in the list of objects that have a formatting rule defined. If this type is found in the list, then the corresponding formatting module is applied to the object; if not, then PowerShell simply displays the properties of that .NET object.

PowerShell can also explicitly set rules for formatting data output from cmdlets, and, like the Cmd.exe command interpreter, redirect this data to a file, to a printer, or to a blank device.

Formatting the output information

In traditional shells, commands and utilities themselves format the output. Some commands (for example, dir in the Cmd.exe interpreter) allow you to customize the output format using special parameters.

In PowerShell, output is formatted by only four special Format cmdlets (Table 17.3). This makes it easier to learn because you don't have to remember formatting options for other commands (other cmdlets don't format output).

Table 17.3. PowerShell Cmdlets for Output Formatting
Cmdlet Description
Format-Table Formats the command output as a table whose columns contain object properties (calculated columns can also be added). Supports the ability to group output data
Format-List The output is formatted as a list of properties, with each property displayed in new line. Supports the ability to group output data
Format-Custom A custom view is used to format the output.
Format-Wide Formats objects as a wide table that displays only one property per object

As noted above, if none of the Format cmdlets are explicitly specified, the default formatter is used, which is determined by the type of data being displayed. For example, when you run the Get-Service cmdlet, the data defaults to a table with three columns (Status, Name, and DisplayName):

PS C:\> Get-Service Status Name DisplayName ------ ---- ----------- Stopped Alerter Announcer Running ALG Application Level Gateway Service Stopped AppMgmt Application Management Stopped aspnet_state ASP.NET State Service Running Ati HotKey Poller Ati HotKey Poller Running AudioSrv Windows Audio Running BITS Background Intelligent Per... Running Browser Computer Browser Stopped cisvc Indexing Service Stopped ClipSrv Exchange Folder Server Stopped clr_optimizatio... .NET Runtime Optimization Service v... Stopped COMSysApp System application COM+ Running CryptSvc Cryptography services Running DcomLaunch Launching server processes DCOM Running Dhcp DHCP client...

To change the format of the output data, you need to pipe it to the appropriate Format cmdlet. For example, the following command will list services using the Format-List cmdlet:

PS C:\> Get-Service | Format-List Name: Alerter DisplayName: Announcer Status: Stopped DependentServices: () ServicesDependedOn: (LanmanWorkstation) CanPauseAndContinue: False CanShutdown: False CanStop: False ServiceType: Win32ShareProcess Name: ALG DisplayName: Application Level Gateway Service Status: Running DependentServices: () ServicesDependedOn : () CanPauseAndContinue: False CanShutdown: False CanStop: True ServiceType: Win32OwnProcess . . .

As we can see, the list format displays more information about each service than the table format (instead of three columns of data about each service, the list format displays nine rows of data). However, this does not mean that the Format-List cmdlet retrieves additional information about services. This data is contained in the objects returned by the Get-Service cmdlet, but the default Format-Table cmdlet discards it because it cannot display more than three columns.

When formatting output using the Format-List and Format-Table cmdlets, you can specify the names of the object properties that should be displayed (recall that the Get-Member cmdlet discussed earlier allows you to view the list of properties that an object has). For example:

PS C:\> Get-Service | Format-List Name, Status, CanStop Name: Alerter Status: Stopped CanStop: False Name: ALG Status: Running CanStop: True Name: AppMgmt Status: Stopped CanStop: False . . .

You can display all the properties that objects have using the * parameter, for example:

PS C:\> Get-Service | Format-table *

Redirecting Output Information

PowerShell has several cmdlets that you can use to control your output. These cmdlets start with the word Out and can be seen as follows:

PS C:\> Get-Command out-* | Format-Table Name Name ---- Out-Default Out-File Out-Host Out-Null Out-Printer Out-String

By default, the output information is passed to the Out-Default cmdlet, which in turn delegates all the work of displaying strings to the Out-Host cmdlet. For understanding this mechanism It should be taken into account that the PowerShell architecture implies a distinction between the shell core itself (the command interpreter) and the main application (host) that uses this core. In principle, the main application can be any application that implements a number of special interfaces that allow you to correctly interpret the information received from PowerShell. In our case, the main application is the console window in which we work with the shell, and the Out-Host cmdlet passes the output to this console window.

The Paging parameter of the Out-Host cmdlet, like the more command of the Cmd.exe interpreter, allows you to organize page-by-page output of information, for example:

Get-Help Get-Process –Full | Out-Host-Paging

Saving data to a file

The Out-File cmdlet allows you to direct output to the console window instead of text file. The redirection operator (>) solves a similar problem, but the Out-File cmdlet has several additional parameters that allow you to more flexibly control the output: set the file encoding type (Encoding parameter), set the length of the output lines in characters (Width parameter), select the mode overwriting the file (parameters Append , noClobber ). For example, the following command will send information about the services registered on the computer to the file C:\service.txt, and this file will be written in ASCII format.

Let's finish working with data output.

In the event that we do not need to display information on the console screen (let's say it is simply unnecessary for us, and we just need certain commands to work without displaying the results on the screen), we can use the Out-Null cmdlet.

What happens if you add Out-Null to the well-known Get-Process cmdlet?

Get-Process | Out-Null
Out-Null Action Example in PowerShell

As you can see, absolutely nothing happened. Or, more precisely, nothing visible to our eyes. The Get-Process cmdlet worked, but we did not want to see the results of its work. Of course, this action was pointless.

You can give an example of a more meaningful action. Let's go to the root of drive C and create a primer directory there.

cd c:\ mkdir primer

As we can see, PowerShell has given us the contents of the newly created directory. If we don't need this, we can use Out-Null.

mkdir primer | Out-Null

So, Out-Null is a useful tool for performing those actions that should be performed under the hood.

PowerShell is an object-oriented programming engine and scripting language with a command line interface that provides IT professionals with greater configuration options operating systems MS Windows family. Simply put, it is a kind of universal administration tool. This article will discuss basic techniques for writing scripts in PowerShell, which allow you to automate the management of your Windows environment in a simple way.

PowerShell offers both a pure console interface and a full development environment PowerShell ISE(Integrated Scripting Environment, built-in scripting environment) for scripts. To launch the command line interface, type powershell in the Run menu (WinKey + R). PowerShell ISE is launched using the "PowerShell ISE" command in the same menu.

ISE is more preferable as it provides more opportunities to the developer thanks to syntax highlighting, code auto-completion and other features inherent in many “big” IDEs.

Writing and running scripts

Scripts are saved as files with the extension .ps1. Even though PowerShell has long been a native part of Windows, you won't be able to run its scripts easily. double click. To do this you need to click right click according to the script and select “Run in PowerShell”.

There are also system policies that restrict script execution. You can check your current policy settings by running the Get-ExecutionPolicy command. The result will be one of the following values:

  • Restricted- execution of scripts is prohibited. Standard configuration;
  • AllSigned- you can run scripts signed by a trusted developer; Before running the script, PowerShell will ask you for confirmation;
  • RemoteSigned- you can run your own scripts or those signed by a trusted developer;
  • Unrestricted- you can run any scripts.

To get started, you need to change the startup policy setting to RemoteSigned using the Set-ExecutionPolicy command:

Cmdlets

Cmdlets are commands with a predefined function, like conditional statements in programming languages. They have several key features:

  • There are system, user and optional cmdlets;
  • the result of executing the cmdlet will be an object or an array of objects;
  • Cmdlets can process data and pass it to other cmdlets using pipelines;
  • cmdlets are case insensitive, so there is no difference between Get-ADUser , get-aduser , and gEt-AdUsEr ;
  • a symbol is used as a separator; .

Each cmdlet contains a verb and a noun separated by a hyphen. For example:

  • Get-Process- display current processes running on the computer;
  • Get-Service- display a list of services and their status;
  • Get-Content- display content specified file, for example Get-Content C:\Windows\System32\drivers\etc\hosts .

If necessary, you can list all available cmdlets using Get-Help-Category:

You can also create your own cmdlets.

Options

Each cmdlet has several parameters that determine how it works. PowerShell ISE automatically suggests all available parameters and displays their type. For example, Get-Service-NameW* returns a list of services whose name begins with W . If you forget what parameters the cmdlet you entered has, use Get-Member . For example, Get-Process | Get-Member:

If you don't find what you need, or aren't sure how to set the parameters correctly, you can even request examples using the -Examples parameter:

Some cmdlets can also be called using aliases, for example, instead of Get-Help you can simply write Help .

When writing large scripts or team development, you can use comments. Each comment begins with a # character, and the comment block is limited to combinations of characters<# и #>at the beginning and at the end respectively.

Conveyor

PowerShell Allows you to exchange data between cmdlets using a pipeline. For example:

  • GetService | SortObject -property Status - sorting running services by status;
  • “Hello World!” | Out-File C:\ps\test.txt - writing text to a file.

Multiple conveyors can be used. For example, the following script lists the names of all services except stopped ones:

Get-Service | WHERE ($_.status -eq “Running”) | SELECT displayname

Conclusion

So, thanks to this tutorial, newbies have an idea of ​​what PowerShell is all about. We also looked at options for changing the script execution policy, what a cmdlet is, how they exchange data using a pipeline, and how to get the properties of the desired object. Remember that if you have any problems, you can use the Get-Help cmdlet.