Power shell For Loop, не Looping - PullRequest
       44

Power shell For Loop, не Looping

0 голосов
/ 27 сентября 2019

Таким образом, вывод работает нормально, но у меня проблема с выводом только последней строки, которую он запускает.Есть ли какой-либо способ проверить петли для проверки в будущем?

, но у меня есть список IP-адресов, и я пытаюсь проверить, включен ли брандмауэр в Windows или нет.Они на одной БОЛЬШОЙ (более 300 рабочих групп).Любая помощь в правильном цикле будет принята с благодарностью.Безопасность и другие вещи не являются проблемой, потому что у меня есть другие скрипты, которые работают нормально.И я не получаю никаких ошибок.только один выход.

Я уже пытался переместить массив, и это не помогло.я думаю, что это может быть частью PSCustomObject, так как я только начинаю изучать их.Или это могут быть мои входные и выходные форматы разные, и это вызывает проблемы ??

clear
$ComputerList = get-content C:\Users\Administrator\Desktop\DavidsScripts\TurnOffFirewall\input.txt
$Status = @(
foreach ($Computer in $ComputerList) {

netsh -r $Computer advfirewall show currentprofile state})[3] -replace 'State' -replace '\s' 


$Object = [PSCustomObject]@{
    Computer = $Computer
    Firewall = $Status
}

Write-Output $Object
$Object | Export-Csv -Path "C:\FirewallStatus.csv" -Append -NoTypeInformation

Ответы [ 2 ]

1 голос
/ 27 сентября 2019

Ваш предыдущий код не выходил из цикла, а только добавлял последний объект в цикле к объекту.

Лучший способ, который я нашел, - это создать временный объект и добавить его в массивсписок затем экспортировать это.Гораздо приятнее.

$ComputerList = get-content C:\Users\Administrator\Desktop\DavidsScripts\TurnOffFirewall\input.txt
$collectionVariable = New-Object System.Collections.ArrayList

ForEach ($Computer in $ComputerList) {
    # Create temp object
    $temp = New-Object System.Object
    # Add members to temp object
    $temp | Add-Member -MemberType NoteProperty -Name "Computer" -Value $Computer
    $temp | Add-Member -MemberType NoteProperty -Name "Firewall" -Value $((netsh -r $Computer advfirewall show currentprofile state)[3] -replace 'State' -replace '\s')
    # Add the temp object to ArrayList
    $collectionVariable.Add($temp)
}

Write-Output $collectionVariable
$collectionVariable | Export-Csv -Path "C:\FirewallStatus.csv" -Append -NoTypeInformation
0 голосов
/ 27 сентября 2019

Вот упрощенная, функциональная версия вашего кода с использованием одного конвейера:

Get-Content C:\Users\Administrator\Desktop\DavidsScripts\TurnOffFirewall\input.txt |
  ForEach-Object {
    [pscustomobject] @{
      Computer = $_
      Firewall = (-split ((netsh -r $_ advfirewall show currentprofile state) -match '^State'))[-1]    
    }
  } | Export-Csv -Path C:\FirewallStatus.csv -NoTypeInformation

Примечание:

  • Никаких промежуточных переменных не требуется;каждое имя компьютера, считываемое из входного файла, обрабатывается один за другим, и каждый созданный на его основе пользовательский объект отправляется в выходной CSV-файл.

  • Команда для извлечения состояния брандмауэра изВывод netsh был сделан более надежным для извлечения информации о состоянии на основе строки content (регулярное выражение ^State, то есть строки, начинающейся с State), а не строки индекс ([3]);унарная форма -split разбивает интересующую линию на токены по пробелам, а индекс [-1] извлекает последний токен, который является значением состояния.


Что касается то, что вы пытались :

  • Ваш foreach цикл закончился до того, как $Object был построен, поэтому вы в итоге построили только 1 объект для отправки в выходной файл с Export-Csv.

  • Если бы вы правильно отформатировали свой код, этот факт был бы более очевидным;попробуйте использовать код Visual Studio с расширением PowerShell , которое предлагает автоматическое форматирование с помощью команды >Format Document ( Shift + Alt + F ).

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