Foreach — from the book PowerShell in depth

Chapter 19.3. It explains the construction of Foreach, how to use it.

This design has the same purpose as the ForEach-Object cmdlet. The ForEach-Object cmdlet has an alias of ForEach, which can easily be confused with the ForEach statement... because they have identical names. PowerShell looks at the context to figure out what the Foreach is used now. Here is an example of how the operator, and the cmdlet do the same thing
the
Get-Service –name B* | ForEach { $_.Pause() }

$services = Get-Service –name B*
ForEach ($service in $services) 
{
$service.Pause()
}


Let us examine how this Foreach statement, there are two variables in parentheses separated by the word in. The second variable is expected to contain one or more objects with which we want to do something. The first variable is for internal use, it will contain the turns in each pass the object from the second variable. If you wrote something in VBScript that kind of stuff should look familiar to you.

A common practice to name the second variable in the plural, and in the first one. It is not required by the agreement or the standard, although you can write Foreach( $Fred in $Rocvill ) provided that $Rockvill contain objects, PowerShell will be happy to handle it. But stick to the conscious naming of variables, then you have much less to remember.

PowerShell automatically takes one object from the second variable and puts it in first on each pass through the loop. Inside the construction you can use the first variable to do something with the object, for example you can call the Pause method of this object. Do not use $_ (or PSItem) operator, how do you do it in the cmdlet.

Sometimes, you may not be sure what design to use — the operator or the cmdlet. Theoretically, the transfer conveyor for the Foreach-object can use less memory in some situations. According to our observations, the cmdlet is slower with large sets of objects. If you have complex processing in the Assembly line, especially if you are processing a Foreach inside a Foreach is better to use full name to uniquely identify what ispolzuetsya.

You also need to be careful if you want to pass the belt to another cmdlet or function. Example
the
PS C:\> foreach ($service in $services) {
>> $service | select Name,DisplayName,Status
>> } | Sort Status
>>
An empty pipe element is not allowed.
At line:3 char:4
+ } | <<<< Sort Status
+ CategoryInfo : ParserError: (:) [],
ParentContainsErrorRecordException
+ FullyQualifiedErrorId : EmptyPipeElement

PowerShell threw an error, because there is nothing to pass down the Assembly line to Sort, but this example will work:
the
PS C:\> $services | foreach {
>> $_ | select Name,DisplayName,Status
>> } | Sort Status
>>
Name DisplayName Status
---- ----------- ------
Browser Computer Browser Stopped
BDESVC BitLocker Drive Encrypt... Stopped
bthserv Bluetooth Support Service Running
BFE Base Filtering Engine Running
BITS Background Intelligent Running ... 

Another factor is whether you will use a collection of objects again if you need further collection, it is better to use the operator not to get the data again. The last point is that many scripts you find online are actually conversion scripts in VBScript, it always had to iterate over collections of objects. Therefore it is always worth to stop and think for a second to determine the best approach and whether it is necessary to iterate over a collection in General.

Our advice — don't use too much if you have the opportunity not to. For example, let's rewrite our earlier code given differently:
the
Get-Service –name B* | Suspend-Service

and example of the sort would be much better if you write it like this:
the
Get-Service b* | Sort Status | select Name,DisplayName,Status

If you don't need for something to iterate through all objects don't do this. Use the Foreach cmdlet or operator is sometimes a sign that you are doing something that should not be done. This is certainly not true in all cases, but think PowerShell can do some of the work for you. Do not dwell on this issue, many of the cmdlets simply do not take the output from the line at which you may be necessary in this case, the use of Foreach becomes a necessity. It is more important to finish the job than to keep track of right or wrong, you wrote something.
this refers to the ability of polica to relate the parameters of objects on the conveyor according to the parameter names. If there is a chance that posh will not be able to uniquely identify the object parameter in the process "parameter binding" you will have to iterate the items one by one. For example WMI. The total recomende — use conveyor processing, the cycle usually breaks the belt, and sometimes leads to unnecessary iterations. For example it is more efficient to do the Select and then handling than the if inside the Foreach and processing

A good time to remind you about brackets. We FIB when he said that the Foreach statement requires two variables. From a technical point of view this requires only one variable. The second should contain a collection of objects which may be either a variable as in our examples before, or may be the result of the expression in parentheses, for example:
the
foreach ($service in (Get-Service –name B*)) {
$service.pause()
}

This version is harder to read, but is absolutely legitimate, eliminating the need to store intermediate results in a variable. Inner parentheses are evaluated first, and produces a collection of objects which is passed on.
Article based on information from habrahabr.ru

Comments

Popular posts from this blog

Powershell and Cyrillic in the console (updated)

Active/Passive PostgreSQL Cluster, using Pacemaker, Corosync

Automatic deployment ElasticBeanstalk using Bitbucket Pipelines