 |
|
Проблема с двойным 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.
|
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
|
честно говоря не понял. А где тогда правильно создать $ArrayList?
|
ivan.vas, перед первым циклом.
|
Спасибо, помогло. Теперь скрипт выглядит вот так:
Код:
$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
}
|
DJ Mogarych, но тогда нужно будет активировать у всех кто в списке Comp.txt - PSRemoting?
|
DJ Mogarych |
16-09-2021 10:52 2966765 |
Да, но у серверов это уже должно быть включено по умолчанию.
|
DJ Mogarych, сервера разные бывают, иногда это даже 7 :)
|
Цитата:
Цитата ivan.vas
но вот вывод имени пользователя дублирует одно и тоже. Не можете подсказать почему так? »
|
А откуда у Вас берётся $EventProperties[1]? Я вижу, что из воздуха. Может быть, $Event .Properties[1].value?
|
Цитата:
Цитата Iska
А откуда у Вас берётся $EventProperties[1]? »
|
Из события "дергается".
|
ivan.vas, так «не дёргается». Именно «$EventProperties» — вообще ниоткуда.
|
DJ Mogarych |
17-09-2021 09:06 2966884 |
Да просто точка пропущена.
|
Цитата:
Цитата DJ Mogarych
Да просто точка пропущена. »
|
Я про это автору и написал выше:
Цитата:
Цитата Iska
Может быть, $Event .Properties[1].value? »
|
Отсутствие требования явного описания переменых — зло.
|
DJ Mogarych, Iska, вы правы, скрипт работал. Но потом вспомнив, почти тоже самое
Цитата:
Цитата Iska
Отсутствие требования явного описания переменых — зло. »
|
решил написать с заглавной буквы, это и была ошибка.
Правильно вот так выглядит:
Код:
[xml]$Xml = $Event.ToXml()
$Row = "" | Select Username,TimeCreated,Operation
$Row.Username = $eventProperties[1].value
Помогла вот эта картинка:

|
ivan.vas, да без разницы, с заглавной или со строчной, PowerShell не различает регистр символов в переменной. Вы скорее всего пропустили точку, т.е. переменная зовётся не «$EventProperties», а «$Event», а «Properties» — её свойство/метод.
|
DJ Mogarych |
18-09-2021 08:35 2966982 |
Так и есть, и я в своём сообщении №6 выше в коде эту ошибку учёл.
|
Время: 11:33.
© OSzone.net 2001-