Компьютерный форум OSzone.net  

Компьютерный форум OSzone.net (http://forum.oszone.net/index.php)
-   Скриптовые языки администрирования Windows (http://forum.oszone.net/forumdisplay.php?f=102)
-   -   [решено] Проблема с двойным Foreach (http://forum.oszone.net/showthread.php?t=349622)

ivan.vas 15-09-2021 15:57 2966701

Проблема с двойным Foreach
 
Всем привет!
Помогите понять логику Foreach... Не могу понять почему скрипт который выглядит вот так:
Код:

$Time = (Get-Date) - (New-TimeSpan -Hours 24)
$events = @()
$events += Get-WinEvent -FilterHashtable @{Logname = "Security" ; ID = 4800,4801; StartTime = $Time}
$events += Get-WinEvent -FilterHashtable @{Logname = "System" ; ID = 7001,7002; StartTime = $Time}
$Date = Get-Date -format yyyy-MM-dd
$ArrayList = New-Object System.Collections.ArrayList
        Foreach ($Event in $Events)
        {
        [xml]$Xml = $Event.ToXml()
        $Row = "" | Select Username,TimeCreated,Operation
        $Row.Username = $EventProperties[1].value
        $Row.TimeCreated = $Event.TimeCreated.ToString()
        $Row.Operation = $Event.ID
        [void]$ArrayList.Add($Row)
        }
$ArrayList | Sort TimeCreated

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

Код:

$Time = (Get-Date) - (New-TimeSpan -Hours 24)
$Servers = Get-Content "C:\temp\Comp.txt"
Foreach ($Server in $Servers)
{
        if(Test-Connection $Server -Count 2 -Quiet ) {
        $events = @()
        $events += Get-WinEvent -ComputerName $Server -FilterHashtable @{Logname = "Security" ; ID = 4800,4801; StartTime = $Time}
        $events += Get-WinEvent -ComputerName $Server -FilterHashtable @{Logname = "System" ; ID = 7001,7002; StartTime = $Time}
        $Date = Get-Date -format yyyy-MM-dd
        $ArrayList = New-Object System.Collections.ArrayList
       
        Foreach ($Event in $Events)
        {
        [xml]$Xml = $Event.ToXml()
        $Row = "" | Select Username,TimeCreated,Operation
        $Row.Username = $EventProperties[1].value
        $Row.TimeCreated = $Event.TimeCreated.ToString()
        $Row.Operation = $Event.ID
        [void]$ArrayList.Add($Row)
        }
        }
        else {}
}
$ArrayList | Sort TimeCreated

Хочу к варианту который исправно работает (1 листинг) добавить возможность выборки имен компьютеров из файла txt.

Iska 15-09-2021 17:29 2966706

ivan.vas, Вы на каждом проходе внешнего цикла пересоздаёте содержимое переменной $ArrayList:
Код:

Foreach ($Server in $Servers) {
    if(Test-Connection $Server -Count 2 -Quiet ) {
        …
        $ArrayList = New-Object System.Collections.ArrayList
       
        Foreach ($Event in $Events) {
            …
            [void]$ArrayList.Add($Row)
        }
    …
    }
}
$ArrayList | Sort TimeCreated


ivan.vas 15-09-2021 17:59 2966710

Цитата:

Цитата Iska
$ArrayList »

честно говоря не понял. А где тогда правильно создать $ArrayList?

Iska 15-09-2021 18:04 2966711

ivan.vas, перед первым циклом.

ivan.vas 16-09-2021 09:17 2966748

Цитата:

Цитата Iska
перед первым циклом. »

Спасибо, помогло. Теперь скрипт выглядит вот так:
Код:

$Time = (Get-Date) - (New-TimeSpan -Hours 24)
$Date = Get-Date -format yyyy-MM-dd
$Servers = Get-Content "C:\temp\Comp.txt"
$ArrayList = New-Object System.Collections.ArrayList
Foreach ($Server in $Servers)
{
        if(Test-Connection $Server -Count 2 -Quiet ) {
        $events = @()
        $events += Get-WinEvent -ComputerName $Server -FilterHashtable @{Logname = "Security" ; ID = 4800,4801; StartTime = $Time}
        $events += Get-WinEvent -ComputerName $Server -FilterHashtable @{Logname = "System" ; ID = 7001,7002; StartTime = $Time}
        Foreach ($Event in $Events)
        {
        $Row = "" | Select PC,Username,TimeCreated,Operation
        $Row.PC = $Server
        $Row.Username = $EventProperties[1].value
        $Row.TimeCreated = $Event.TimeCreated.ToString()
        $Row.Operation = $Event.ID
        [void]$ArrayList.Add($Row)
        }
        }
        else {}
}
$ArrayList | Sort TimeCreated

Единственное, что смущает, графы TimeCreated и Operation он выводит верно. Я даже добавил вывод имени компьютера вначале, но вот вывод имени пользователя дублирует одно и тоже. Не можете подсказать почему так?

DJ Mogarych 16-09-2021 10:12 2966754

Гораздо быстрее будет работать, если воспользоваться Invoke-Command, типа

Код:

$Servers = Get-Content "C:\temp\Comp.txt"

Invoke-Command -ComputerName $Servers  -ScriptBlock {
$time = (get-date).AddDays(-1)
Get-WinEvent -FilterHashtable @{Logname = "System" ; ID = 7001,7002; StartTime = $Time} |select PSComputername,@{n="Username";e={$_.properties[1].value}},Timecreated,id
}


ivan.vas 16-09-2021 10:26 2966760

DJ Mogarych, но тогда нужно будет активировать у всех кто в списке Comp.txt - PSRemoting?

DJ Mogarych 16-09-2021 10:52 2966765

Да, но у серверов это уже должно быть включено по умолчанию.

ivan.vas 16-09-2021 12:49 2966786

DJ Mogarych, сервера разные бывают, иногда это даже 7 :)

Iska 16-09-2021 17:04 2966826

Цитата:

Цитата ivan.vas
но вот вывод имени пользователя дублирует одно и тоже. Не можете подсказать почему так? »

А откуда у Вас берётся $EventProperties[1]? Я вижу, что из воздуха. Может быть, $Event.Properties[1].value?

ivan.vas 16-09-2021 17:21 2966831

Цитата:

Цитата Iska
А откуда у Вас берётся $EventProperties[1]? »

Из события "дергается".

Iska 16-09-2021 21:44 2966849

ivan.vas, так «не дёргается». Именно «$EventProperties» — вообще ниоткуда.

DJ Mogarych 17-09-2021 09:06 2966884

Да просто точка пропущена.

Iska 17-09-2021 09:27 2966887

Цитата:

Цитата DJ Mogarych
Да просто точка пропущена. »

Я про это автору и написал выше:
Цитата:

Цитата Iska
Может быть, $Event.Properties[1].value? »

Отсутствие требования явного описания переменых — зло.

ivan.vas 17-09-2021 16:41 2966935

DJ Mogarych, Iska, вы правы, скрипт работал. Но потом вспомнив, почти тоже самое
Цитата:

Цитата Iska
Отсутствие требования явного описания переменых — зло. »

решил написать с заглавной буквы, это и была ошибка.
Правильно вот так выглядит:
Код:

[xml]$Xml = $Event.ToXml()
$Row = "" | Select Username,TimeCreated,Operation
$Row.Username = $eventProperties[1].value

Помогла вот эта картинка:

Iska 17-09-2021 21:04 2966962

ivan.vas, да без разницы, с заглавной или со строчной, PowerShell не различает регистр символов в переменной. Вы скорее всего пропустили точку, т.е. переменная зовётся не «$EventProperties», а «$Event», а «Properties» — её свойство/метод.

DJ Mogarych 18-09-2021 08:35 2966982

Так и есть, и я в своём сообщении №6 выше в коде эту ошибку учёл.

ivan.vas 20-09-2021 12:17 2967149

Iska, вы правы. Спасибо.


Время: 11:33.

Время: 11:33.
© OSzone.net 2001-