Powershell цикл for: Циклы Powershell — ForEach и ForEach-Object с примерами, команды while, continue и break

cmd — Как ввести переменную внутри цикла for в powershell? Области видимости в Windows

Решил написать скрипт для сравнения двух папок на разных носителях (один на диске H:\, другой на диске D:\) под Windows. В случае резервного копирования может быть полезным. Написал следующий код:

for /F "tokens=*" %%d in ('dir /B /S /AD') do (
    set ssd=d
    echo %ssd%
    set ssd=%ssd:H:\=D:\%
    comp "%%ssd" "%%d"
    cd %%d
    echo "inside %%d"
) 

Ожидается, что в цикле for будут рекурсивно пробегаться все вложенные папки и будет производиться сравнение папок командой comp.
Столкнулся с проблемой: команда set ssd=d не объявляет новую переменную. Это становится очевидно благодаря команде echo %ssd% — она просто печатает в консоли echo. Т.е. переменная ssd не создаётся вовсе! Думаю, что в цикле for своя область видимости и в Windows нужно как-то хитро объявлять подобные переменные. Подскажите пожалуйста, как это правильно делается?

  • windows
  • cmd
  • powershell
  • for






4

Если вы не пошутили насчёт PowerShell, приведя скрипт для cmd, то для рекурсивного сравнения файлов не требуются переменные.

gci -Recurse .\PAPKA\ | `
  where { ! $_.PSIsContainer } | `
  % { $_.FullName } | `
  % { fc.exe "$_" "$($_.Replace('D:','H:'))" }

Этот скриптик

  • рекурсивно пройдёт по всем файлам из папки с именем PAPKA (каталоги будут отфильтрованы инструкцией where { ! $_.PSIsContainer }),
  • для каждого файла добудет строку, содержащую полный путь к файлу
  • вызовет утилиту fc.exe, заменив во втором параметре строку D: на строку H:

Если вам нужно именно comp, то замените fc.exe на comp.exe, хотя я бы не советовал.

Второе. В PowerShell нужно вызывать именно fc.exe, так как простое fc — это алиас на команду Format-Custom.

Действительно перепутал кучу интерпретаторов, поэтому решил проще решить задачу и написал скрипт на Python + CMD.

import os
def run_command(command):
    res = os.popen(command)
    for line in res:
        print(line. encode('cp1251').decode("cp866"))
command = "dir /B /S /AD"
dirs_inside = list(os.popen(command))
for dir_ in enumerate(dirs_inside):
    dirs_inside[dir_[0]] = dir_[1][:-1]
cur_dir = os.getcwd()
all_dirs = [cur_dir] + dirs_inside
disk = 'H'
command_template = 'comp "{path_1}" "{path_2}"'
for dir_ in all_dirs:
    path2 = disk + dir_[1:]
    path3 = dir_
    cur_command = command_template.format(path_1=path2, path_2=path3)
    run_command(cur_command)

В пакетных файлах области видимости всех переменных глобальные, проблема не в них. Проблема в том, что %%-переменные раскрываются в момент начала выполнения команды, а она у вас одна — весь цикл for.

Для решения этой проблемы следует использовать ENABLEDELAYEDEXPANSION и !!-переменные:

setlocal enabledelayedexpansion
for /F "tokens=*" %%d in ('dir /B /S /AD') do (
    set ssd=d
    echo !ssd!
    set ssd=!ssd:H:\=D:\!
    comp "!ssd!" "%%d"
    cd %%d
    echo "inside %%d"
) 







Зарегистрируйтесь или войдите

Регистрация через Google

Регистрация через Facebook

Регистрация через почту

Отправить без регистрации

Почта

Необходима, но никому не показывается

Отправить без регистрации



Почта

Необходима, но никому не показывается




By clicking “Отправить ответ”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.


Глава 1. Основы PowerShell — Ускоренное продвижение PowerShell: хакерство для не

Содержание

Глава 1. Основы PowerShell

Переменные и вывод на печать

Переключатель If/Else

Операторы условия/ логики

Логические операторы

Циклы

Цикл For и цикл While

Цикл For

Цикл While

Функции

Выводы

Давайте начнём с базовых элементов и быстро просмотрим переменные, циклы, операторы if/else,
переключатели и функции. Все они являются сердцем любого языка сценариев и поспособствуют вам в создании сценариев от простых
до сложных.

Я не погружаюсь в версии PowerShell или в то чем является PowerShell (но вот вам быстрое для понимания определение без особого
углубления: PowerShell это решение автоматизации задач составленных в командной строке оболочки и язык сценариев
{Прим. пер.: подробнее в нашем переводе 4 издания Книга рецептов автоматизации
Windows Server при помощи PowerShell Томаса Ли, Packt Publishing, 2021
}). Я также не хочу говорить о том в
каких платформах он может применяться или получать и устанавливать команды, потому как это не всеобъемлющая книга для
изучения данного языка.

Основной посыл этой книги состоит в обучении вас созданию сценариев, не обладая знаниями лежащих под капотом элементов. Это
подход, который я успешно применял со многими студентами. Постепенно они стали хорошо разбираться в этом языке программирования.

Не все обладают опытом программирования, и не все умеют создавать код. Однако, следуя описанному в этой книге подходу, вы
сможете быстро создавать собственные сценарии и автоматизировать ИТ системы/ процессы.

Замечание

Ко всем применяемым в данной книге кодам можно получить доступ кликнув по кнопке
Download Source Code, расположенной на
www. apress.com/9781484277584 (следите за
номерами листингов).

Переменные и вывод на печать

Для начала нам необходимо разобраться с основами, которые включают переменные и массивы. Всякая переменная в PowerShell
начинается с символа доллара ($), например:


$a = "1"
$b = "Vikas"
 	   

Когда вы набираете $a и $b, будут отображены значения, как это показано на Рисунке 1-1.

 

Рисунок 1-1


Переменные в PowerShell

Теперь для вывода на свой экран вы можете применить Write-host:


Input: PS C:\> Write-host $a
Output: 1
Input: PS C:\> Write-host $b
Output: vikas 
		
Совет

Возьмите за правило применять кавычки при присвоении значений переменным, как это показано в предыдущих двух
примерах.

Давайте изменим значение фонового цвета того, что отображается через Write-host:


Input: PS C:\& Write-host $b -ForegroundColor Green
Output: vikas
Input: PS C:\& Write-host "processing .........." -ForegroundColor Green
Output: processing ..........
PS C:\&
		

Рисунок 1-2 отображает получаемый результат:

 

Рисунок 1-2


Применение Write-host переменная

Давайте по- быстрому проиллюстрируем массивы. В PowerShell массивы могут определяться аналогичным переменным способом. Вот
некоторые образцы:


$b = "A","B","C","D","E"
		

Если вы определите это как переменную и разделяете все элементы запятой, PowerShell автоматически распознаёт что это
массив, как то отображено на Рисунке 1-3.

 

Рисунок 1-3


Иллюстрация массива

Надлежащим способом определения массива выступает показанный ниже, потому как это показано самим синтаксисом, именно это
представляет массив (что показано на Рисунке 1-4):


$c= @("server1","server2")
		

 

Рисунок 1-4


Синтаксис массива

Динамический массив может определяться как @(). Вы будете применять этот тип в
примерах данной книги для добавления элементов в свой массив и выработки отчётов:


$d= @()
		

Переключатель If/Else

If else является обработкой на основе условия. Это основа любого языка
программирования сценариев. Если некоторое условие истинно, вам необходимо обработать нечто; в противном случае обрабатывается
нечто иное.

Листинг 1-1 показывает два примера. Во- первых, вы
определяете значение переменной как 10 и затем вы пользуетесь соответствующим условными операторами и предложениями
if else для проверки больше ли это чем 9 или меньше. На основании полученного
результата вы применяете Write-host для вывода на экран, как это показано на
Рисунке 1-5.

Обратите внимание, что -gt означает больше чем, а
-lt меньше чем. Не беспокойтесь; я быстро пробегусь по ним в своём следующем
подразделе.

 

Листинг 1-1. Пример кода для применения оператора больше чем в If/Else


[int]$a= "10"

if($a -gt "9")
{
write-host "True" -foregroundcolor Green
}else {
Write-host "False" -foregroundcolor Red
}
 	   

И да, [int] означает целое. Если вы применяете префикс перед самой переменной, он
означает что вы исключительно определяете её как целое. Определять всегда лучше, но если вы не хотите, PowerShell достаточно
сообразителен чтобы выполнить это неявно. Существуют именуемые типы данных и они содержат [string],
[char], [int], [array]
и так далее.

 

Рисунок 1-5


Отображение применения -gt в if/else

Листинг 1-2 и
Рисунок 1-6
показывают фрагмент кода применения оператора меньше чем.

 

Листинг 1-2. Пример кода для применения оператора меньше чем в If/Else


[int]$a= "10"

if($a -lt "9"){
write-host "True" -foregroundcolor Green
}else {
Write-host "False" -foregroundcolor Red
}
 	   

 

Рисунок 1-6


Отображение применения -lt в if/else

w3.org/1999/xhtml»>
Операторы условия/ логики

Ниже приводится перечень операторов условия/ логики, которые вы можете применять в своих повседневных сценариях. Без них
многие операции сценариев были бы невозможны. Они всегда используются в предложениях сравнения if
else
, как это показано выше в родительском разделе.

  • -eq Равно

  • -ne Не равно

  • -ge Больше чем или равно

  • -gt Больше чем

  • -lt Меньше чем

  • -le Меньше чем или равно

  • -like     Сопоставление с символами подстановки

  • -notlike  Сопоставление с символами подстановки

  • -match   Сопоставление регулярным выражением

  • -notmatch Сопоставление регулярным выражением

  • -replace  Оператор замены

  • -contains Оператор включения

  • -notcontains Оператор включения

w3.org/1999/xhtml»>
Логические операторы

Логические операторы применяются когда вы желаете комбинировать свои условия. Давайте обновим приводимый ранее пример в
отображаемый в Листинге 1-3 пример. Вы выводите на печать true
когда значение переменной $a меньшем чем 9 или равно 10. Здесь вы сочетаете два
условия. Поскольку это оператор OR, TRUE
будет возвращаться при одном из совпадений. Здесь наше второе условие, $a -eq "10",
совпадает если значение равно 10. Посмотрите на полученный на
Рисунке 1-7
результат.

 

Листинг 1-3. Пример кода, отображающего логический оператор -or


[int]$a= "10"

If(($a -lt "9") -or ($a -eq "10")){
write-host "True" -foregroundcolor Green
}else {
Write-host "False" -foregroundcolor Red}
 	   

 

Рисунок 1-7


Отображение логического оператора -or

Когда вы применяете оператор OR, тогда должны совпадать оба условия если вы желаете
получить TRUE, что не происходит в обоих случаях. Смотрите
Листинге 1-4 и
Рисунок 1-8.

 

Листинг 1-4. Пример кода, отображающего логический оператор -and


[int]$a= "10"

If(($a -lt "9") -and ($a -eq "10")){
write-host "True" -foregroundcolor Green
}else {
Write-host "False" -foregroundcolor Red}
 	   

 

Рисунок 1-8


Отображение логического оператора -and

Not служит для отрицания. В целом, я не пользуюсь им часто. По моему опыту,
это приводит к человеческой ошибке когда вы спешите и недостаточно всё обдумаете.

В любом языке программирования сценариев существуют два основных цикла, и это верно и для PowerShell. Существуют и
прочие, но все они выступают вариантами этих двух.

Цикл For и цикл While


Цикл For

В PowerShell существуют три повтора для циклов for:

  • foreach

  • foreach-object

  • for

Давайте проведём различия между этими тремя циклами for рассмотрев их на примерах.

foreach: Вам требуется определить foreach $variable
в $collection: foreach ($i in $x).

Замечание

В Листинге 1-5 вы сочетаете операторы
if else и сравнения. На
Рисунке 1-9
вы можете наблюдать получаемые результаты.

 

Листинг 1-5. Код, отображающий цикл foreach


$x=@("1","2","3",,"4")

foreach ($i in $x) {
      if ($i -lt 2) { write-host "$i is Green" -foregroundcolor Green
      }
         else{ write-host "$i is yellow" -foregroundcolor yellow
      }
 }
 	   

 

Рисунок 1-9


Отображение оператора foreach

foreach-object: Вы пользуетесь конвейером (PIPE) с его коллекцией для достижения
тех же самых моментов (смотрите Листинг 1-6 и
Рисунок 1-10):


$x | foreach-object
 	   

 

Листинг 1-6. Код, отображающий цикл foreach-object


$x=@("1","2","3",,"4")

$x | foreach-object{
        if ($_ -lt 2) { write-host "$_ is Green" -foregroundcolor Green
		}
        else{ write-host "$_ is yellow" -foregroundcolor yellow
		}
     }
 	   

 

Рисунок 1-10


Отображение оператора foreach-object

for: Это именно то, что вы могли запомнить в свои школьные годы. Я почти не применяю
его вовсе и вижу меньше применений по всему сообществу. Посмотрите на его код в
Листинге 1-7 и получаемые результаты на
Рисунке 1-11.

 

Листинг 1-7. Код, отображающий цикл for


for($x=1; $x -le 5; $x++){
    if($x -lt 2){write-host "$x is Green" -foregroundcolor Green
    }
    else{ write-host "$x is yellow" -foregroundcolor yellow
    }
}
 	   

 

Рисунок 1-11


Отображение оператора for

w3.org/1999/xhtml»>
Цикл While

Цикл while является совсем другим, потому как он продолжается пока его условие
истинно. Давайте пройдёмся по некоторым образцам чтобы получить больше ясности.

Цикл while также обладает двумя повторами:

  • do-while

  • while

Для do-while вы выполняете нечто пока выполняется соответствие какого- то
условия. В Листинге 1-8
переменная x = 0 и внутри вы наращиваете значение этой переменной, пока оно не станет
равным 4. Для получаемых результатов посмотрите на Рисунок 1-12.

Замечание

Сначала вы делаете что- то, а потом проверяете соответствие условия.

 

Листинг 1-8. Код, отображающий цикл do-while


$x= 0

Do {$x++
if($x -lt 2){write-host "$x is Green" -foregroundcolor Green
              }
             else{ write-host "$x is yellow" -foregroundcolor yellow
}
 }while($x -ne 4)
 	   

 

Рисунок 1-12


Отображение оператора do-while

Для while вы также выполняете нечто пока выполняется соответствие какого- то
условия. В Листинге 1-9
переменная x = 0 и внутри вы наращиваете значение этой переменной, пока оно не станет
равным 4.

Замечание

Сначала вы осуществляете проверку и после этого выполняете свои дела.

Основное отличие между этими двумя, как вы можете видеть, состоит в том, что цикл while
(пример, который показан на Листинге 1-9) проверяет своё
условие перед самим циклом (повтором), а do-while осуществляет проверку после своего
выполнения. Для получаемых результатов взгляните на Рисунок 1-13.

 

Листинг 1-9. Код, отображающий цикл while


$x= 0

while($x -ne 4) {$x++
if($x -lt 2){write-host "$x is Green" -foregroundcolor Green
       }
       else{ write-host "$x is yellow" -foregroundcolor yellow
      }
}
 	   

 

Рисунок 1-13


Отображение оператора while

Функции

Функции это такие предметы, которые после определения могут вызываться в любом месте сценария. Применение функций
позволяет избегать повторов длинного кода. Это намёк для лучшего понимания. Я не буду вдаваться в подробности задания
параметров и расширенных функциональных возможностей функции, так как мой главный мотив здесь — слегка разобраться и
объединить свой код для выполнения необходимой работы. В
Листинге 1-10
вы создаёте функцию Add для сложения двух чисел. Получаемый результат показан на
Рисунке 1-14.

 

Листинг 1-10. Пример кода, отображающего функцию сложения двух чисел


Function Add ($a1, $b1)
{
$a1 + $b1
}
 	   

Add 5 6 # Вызов функции
		

 

Рисунок 1-14


Отображение функции Add сложения двух чисел

Аналогично, вы можете создать её для трёх и более чисел. Отсылаем вас к
Листингу 1-11 и
Рисунку 1-15.

 

Листинг 1-11. Пример кода, отображающего функцию сложения трёх чисел


Function Add ($a1, $b1, $c1)
{
$a1 + $b1 +$c1
}
 	   

Add 5 6 9 # Вызов функции
		

 

Рисунок 1-15


Отображение функции Add сложения трёх чисел

Выводы

В этой главе мы ознакомились с основами PowerShell, такими как переменные, массивы, операторы if/else и циклами,
которые выступают основными строительными блоками для создания мощных сценариев в промышленной среде. Эти основы
будут применяться и дальше в наших последующих главах.

PowerShell For Loop, ForEach и Do While/Until. Объяснение

Одной из самых фундаментальных функций в программировании, помимо функции «Если, иначе», являются циклы. Они позволяют обрабатывать данные или запускать функцию до тех пор, пока не будет достигнуто определенное условие. В PowerShell мы можем использовать различные типы циклов: For loop, ForEach, Do While и Do Until .

В этой статье мы рассмотрим различные функции цикла, которые мы можем использовать в PowerShell, как их использовать и в чем между ними разница.

Powershell For Loop

Цикл For в PowerShell — это практически самый простой цикл, который вы можете использовать. Он повторяет указанное количество раз часть скрипта, пока условие не будет выполнено.

Чтобы использовать цикл For в PowerShell, вам нужно указать счетчик $i , условие $i -lt 5 (выполнять до тех пор, пока $i меньше 5) и увеличить счетчик.

 Для ($i = 0; $i -lt 5; $i++) {
    Запись-хост $i
} 

Увеличение счетчика также можно выполнить внутри скрипта. Это позволяет вам увеличивать счетчик только тогда, когда в вашем скрипте выполняется определенное условие.

 Для ($i = 0; $i -lt 5) {
    Хост записи $i;
    $я++
} 

Вы также можете перебирать массив с помощью простого цикла For Loop в PowerShell. Мы можем взять длину массива как часть условия и перебирать массив, пока не обработаем все элементы в массиве.

Для обработки массива проще использовать цикл foreach, чем цикл for, об этом позже.

 $fruit = @('яблоко', 'груша', 'банан', 'лимон', 'лайм', 'манго')
# -le означает меньше или равно
Для ($i = 0; $i -le $fruit.length; $i++) {
    Write-Host $fruit[$i];
} 

PowerShell Foreach 1..10

В PowerShell также есть сокращение, которое можно использовать для цикла. Вы можете определить диапазон, например, 1..10 , а затем просмотреть каждое число в диапазоне с помощью оператора ForEach. Это позволяет вам указать, сколько раз вы хотите запустить сценарий, и просто передать сценарий позади него.

 $путь = "C:\temp"
# Создаем новый файл ForEach 1. .10 число
1..10 | % {
    $newFile = "$path\test_file_" + $_ + ".txt";
    Новый элемент $newFile
} 

PowerShell Foreach и цикл ForEach-Object

Для обработки каждого элемента в массиве или коллекции вы можете использовать функции ForEach в PowerShell.

В PowerShell есть два типа функций foreach, у нас есть foreach и ForEach-Object . Разница между ними заключается в том, что foreach загрузит всю коллекцию в память до того, как она начнет обработку данных, а ForEach-Object будет обрабатывать данные по одному. Это делает ForEach-Object идеальным для передачи за другой функцией.

ForEach-Object имеет два сокращения, которые вы можете использовать: ForEach и % . Место, где вы используете ForEach, определяет, какая из двух версий используется.

 $fruits = @('яблоко','груша','банан','лимон','лайм','манго')
# Foreach - Загружает все фрукты в память и обрабатывает их
# Занимает 21 4553 миллисекунды
Foreach ($ фрукты в $ фрукты) {
    Write-Host $fruit;
}
#Сокращение foreach
# Занимает 14 3926 миллисекунд
$fruits. foreach( {
    Хост записи $_;
})
# ForEach-Object
# Занимает 7,8812 миллисекунд
$ фрукты | ForEach-Object {Write-Host $_}
# Сокращение для ForEach-Object
# Занимает 7,3507 миллисекунд
$ фрукты | ForEach {Write-Host $_}
# Также сокращение для ForEach-Object
# занимает 7,2982 миллисекунды
$ фрукты | % {Write-Host $_} 

Как вы видите, foreach в этом примере немного медленнее, но причина этого в том, что для загрузки коллекции в память требуется немного времени.

Если мы возьмем большой набор данных, например, с 300 000 записей, то мы увидим, что foreach может быть намного быстрее, чем ForEach-Object . Только потребление памяти будет немного выше foreach.

 $элементов = 0..300000
# Занимает 180 мс для завершения
(Measure-Command { foreach ($i in $items) {$i } }). TotalMilliseconds
# На выполнение уходит 1300 мс
(Measure-Command {$items | ForEach-Object {$_}}).TotalMilliseconds
# Выполнение занимает 850 мс
(Measure-Command {$items.ForEach({$i})}).TotalMilliseconds 

Когда вы используете функцию, зависит от вашего набора данных. Если вам нужно обработать много данных, то ForEach-Object будет лучшим выбором, чтобы избежать проблем с памятью. Небольшие наборы данных прекрасно обрабатываются с помощью ForEach .

Еще одно преимущество ForEach-Object заключается в том, что за ним можно передать другой командлет, например экспортировать его в CSV.

Блоки сценария ForEach-Object

ForEach-Object позволяет вам использовать блоки сценария, которые могут быть очень полезны, когда вам нужно зарегистрировать процесс или выполнить очистку после завершения сценария.

 $путь = "C:\temp"
$общий размер = 0
Get-ChildItem $путь | ForEach-Object -Начало {
        Write-Host "Обработка папки $путь"
    } -Процесс {
        $totalSize += ($_. length / 1 КБ)
    } -Конец {
        Запись-хост $totalSize "Кб"
    } 

Powershell Do While Loop

PowerShell Do While Loop используется для запуска сценария до тех пор, пока условие истинно или выполняется . У вас также есть цикл While в PowerShell без части Do. Они в основном одинаковы, оба работают до тех пор, пока не будет выполнено условие.

Если вы запустите приведенные ниже сценарии, вы увидите, что они оба создают 10 тестовых файлов во временной папке. Оба выполняются до тех пор, пока $i меньше 10.

 $i = 0;
$путь = "C:\temp"
# Делаем цикл while
Делать {
    # Сделай что-нибудь
    $newFile = "$path\dowhile_test_file_" + $i + ".txt";
    Новый элемент $newFile
    $я++;
}
Пока ($i -lt 10)
# Пока цикл
$i = 0;
Пока ($i -lt 10) {
    # Сделай что-нибудь
    $newFile = "$path\while_test_file_" + $i + ". txt";
    Новый элемент $newFile
    $я++;
} 

Но есть у одно большое отличие между двумя . Do While всегда будет выполняться по крайней мере один раз, независимо от того, какое условие вы используете. Цикл while будет выполняться только при выполнении условия.

Возьмем следующий пример: мы хотим запустить скрипт, пока $i меньше 10. Но для начала мы установили счетчик на 15. Как вы увидите, когда вы запустите скрипт, Do While запускается один раз, а while не запускается вообще.

 $i = 15;
Делать {
    Write-host "Делать пока $i меньше 15";
    $я++;
}
Пока ($i -lt 10)
я = 15;
пока ($i -lt 10)
{
    Write-host "Пока $i меньше 15";
    $я++;
} 

Вы часто используете цикл do-while в PowerShell, когда ожидаете выполнения условия, например, пока процесс не завершится или, как в приведенном ниже примере, пока подключение к Интернету не будет отключено.

PowerShell не перейдет к строке Write-Host, пока не будет выполнено условие while. Итак, в этом примере мы тестируем интернет-соединение с помощью Test-Connection. Он вернет true, когда у нас есть соединение, в противном случае он вернет false.

 Сделать {
    Write-Host "Онлайн"
    Старт-Сон 5
}
Пока (Test-Connection -ComputerName 8.8.8.8 -Quiet -Count 1)
Write-Host "Оффлайн" 

Создание спящего цикла в PowerShell

Если вы хотите создать цикл, который проверяет, снова ли служба подключена к сети, или файл, который нужно создать, то лучше всего использовать спящий режим внутри вашего цикла.

Без спящей части скрипт будет работать максимально быстро, что может составлять пару 1000 итераций в секунду или больше.

С помощью командлета Start-Sleep мы можем инициировать небольшой перерыв перед следующей итерацией:

 Do {
    Write-Host "Онлайн"
    Старт-Сон 5
}
Пока (Test-Connection -ComputerName 8. 8.8.8 -Quiet -Count 1)
Write-Host "Оффлайн" 

В приведенном выше примере мы ждем 5 секунд, прежде чем снова протестируем соединение с 8.8.8.8. Вы также можете использовать миллисекунды вместо секунд в команде start-sleep.

 Start-Sleep -Miliseconds 50 

PowerShell Do Loop

Do until практически не отличается от Do While в PowerShell. Единственная разница заключается в том, в каком состоянии они работают.

  • Делать Пока продолжает работать пока выполняется условие . Когда условие ложно, оно остановится.
  • Делать до тех пор, пока продолжает работать до тех пор, пока условие ложно . Когда условие станет истинным, оно остановится.
 Сделать {
    Write-Host "Компьютер отключен"
    Старт-Сон 5
}
До (Test-Connection -ComputerName 'lab01-srv' -Quiet -Count 1)
Write-Host "Компьютер онлайн" 

Когда использовать Пока или Пока действительно зависит от того, что вы хотите сделать. Это основа, вы можете сказать, что когда условие выхода должно быть истинным, используйте «До». Если условие выхода отрицательное (ложное), вам следует использовать Пока.

Остановка цикла Do While/Until

В PowerShell мы можем использовать Break для преждевременной остановки цикла. Лучше ограничить использование разрывов в циклах, потому что они затрудняют чтение кода. Если вы хорошо структурировали свой код, то он вам действительно не нужен.

Если вам нужно использовать перерыв, то одна вещь может быть полезна, вы можете добавить за ним метку GoTo. Таким образом, вы можете перейти к другой функции цикла.

 $i=0;
Делать {
    Write-Host "Компьютер отключен"
    Старт-Сон 1
    $я++;
    если ($i -eq 2) {
        Перерыв: TestInternetConnection
    }
}
До (Test-Connection -ComputerName 'test' -Quiet -Count 1)
Write-Host "Компьютер онлайн"
:TestInternetConnection Сделать{
    Write-Host "Проверка подключения к интернету"
}
До (Test-Connection -ComputerName '8. 8.8.8' -Quiet -Count 1)
Запись-хост "Подключен" 

Использование Continue в цикле PowerShell

Еще один полезный метод, который вы можете использовать внутри цикла do-while/until в PowerShell, — это Continue . С помощью Continue вы можете остановить сценарий внутри тела Do и перейти к следующей итерации цикла.

Это может быть полезно, если у вас есть большой сценарий внутри блока Do и вы хотите перейти к следующему элементу при выполнении определенного условия.

 $servers = @('srv-lab01','srv-lab02','srv-lab03')
Foreach ($ сервер в $ серверах) {
    
    if ((Test-Connection -ComputerName $server -Quiet -Count 1) -eq $false) {
        Пишет-предупреждение "сервер $сервер отключен"
        Продолжать
    }
    # Делать что-то, когда сервер онлайн
} 

Примеры циклов PowerShell

Ниже вы найдете несколько примеров циклов, которые могут помочь в создании собственных циклов.

Бесконечный цикл PowerShell

Вы можете создать бесконечный цикл в PowerShell с помощью функции цикла While. Пока будет работать до тех пор, пока условие истинно. Таким образом, чтобы создать бесконечный цикл, мы можем просто сделать следующее:

 While ($true) {
    # Делать вещи навсегда
    Write-Host «зацикливается»
    # Используйте Break для выхода из цикла
    Если ($условие -экв $истина) {
        Перерыв
    }
} 

Чтобы выйти из бесконечного цикла, вы можете использовать либо Ctrl + C , либо на основе условия с Break .

Powershell Циклический просмотр файлов

Для циклического просмотра файлов мы будем использовать функцию foreach-object. Файлы — это объекты, которые мы можем получить с помощью команды get-childitem, поэтому мы можем передать за ней объект foreach-object. Еще одна причина использовать ForEach-Object вместо foreach заключается в том, что мы заранее не знаем, сколько файлов будем обрабатывать.

Foreach загрузит все данные в память, что нам не нужно с неизвестным набором данных.

 $путь = "C:\temp"
$csvItems = 0
Get-ChildItem $путь | ForEach-Object {
    $_.Имя;
    Если ($_.Extension -eq '.csv') {
        $csvItems++;
    }
}
Write-host "Всего файлов CSV: $csvItems"; 

Если вы хотите включить и подпапку, вы можете использовать опцию -recurse. Используйте -filter, например, чтобы получить только файлы .csv.

 Get-ChildItem $path -recurse -filter *. csv 

Циклический просмотр текстового файла

В PowerShell вы можете выполнять циклический просмотр текстового файла строка за строкой. Это может быть очень полезно, например, если вы хотите автоматически считывать файлы журналов.

Приведенный ниже пример отлично подходит для небольших файлов, но проблема в том, что командлет Get-Content считывает весь файл в память.

 $lineNr = 0
foreach (строка $ в Get-Content c:\temp\import-log.txt) {
    если($line-соответствие 'предупреждение'){
        # Работать здесь
        Write-warning "В строке $lineNr найдено предупреждение:"
        Предупреждающая запись $line
    }
    $линияNr++;
} 

Для чтения и обработки больших файлов с помощью PowerShell вы также можете использовать программу чтения файлов .Net:

 foreach($line in [System. IO.File]::ReadLines("c:\temp\import-log.txt" ))
{
       $строка
} 

Подведение итогов

Я надеюсь, что этот пример помог вам в создании циклов PowerShell For, Foreach-Object, Do While и Until. Если у вас есть какие-либо вопросы, просто напишите комментарий ниже.

Основы PowerShell: циклы (для циклов и циклов по каждому элементу)

Экспортировано в 11 ноября 2021 г. 11:56:07

Имя Тип Справочник по скрипту Значение по умолчанию Комментарий
Настроить узел Windows-сервер attuneNode Это узел настройки
Учетные данные узла Attune Учетные данные ОС Windows attuneNodeCredentials Это мои учетные данные узла Attune

Сведения о подключении изменились по сравнению с последним шагом.

Войти как пользователь
{Учетные данные узла Attune}
на узле
{Настроить узел}

  1. Подключиться через RDP
     mstsc /admin /v: узел Attune 
  2. Войти как пользователь {Учетные данные узла Attune}
  3. Затем откройте командную строку

Это
Сценарий PowerShell
убедитесь, что вы запускаете его с
powershell.exe
Нажмите меню «Пуск», введите «powershell» в строке поиска, затем выберите программу powerell

 #Region For Loop.
#================================================ ==============================
# Массив переменных ($array) объявлен и содержит массив строк.
$array = @("S","E","R","V","E","R","T","R","I","B","E")
# Это оператор цикла for.
for ($i = 0; $i -lt $array.Count; $i++) {
    
    # Это отображает текущее значение строки в массиве, когда условие выполнено. 
     # `n - создает новую строку после сообщения.
    # Это печать на экран CMDLET [Write-Host].
    Write-Host $array[$i] `n
    
    # Приостанавливает активность в скрипте на 1 секунду
    Старт-Сон -с 1
}
# Это печать на экран CMDLET [Write-Host]. -- Выводит количество букв, содержащихся в массиве.
Write-Host ($array) "имеет" $array.Count "буквы"
#================================================ ==============================
#EndRegion для цикла 

Войти как пользователь
{Учетные данные узла Attune}
на узле
{Настроить узел}

  1. Подключиться через RDP
     mstsc /admin /v: узел Attune 
  2. Войти как пользователь {Учетные данные узла Attune}
  3. Затем откройте командную строку

Это
Сценарий PowerShell
убедитесь, что вы запускаете его с
powershell.exe
Нажмите меню «Пуск», введите «powershell» в строке поиска, затем выберите программу powersell 9.