Экспорт данных на основе логина foreach [Powershell]
У меня есть простой CSV-файл с колонкой "логины"
logins
john
mark
maria
...
Есть сценарий powershell для проверки времени последнего входа в систему:
Import-Module ActiveDirectory
function Get-ADUserLastLogon([string]$userName)
{
$time = 0
$user = Get-ADUser $userName | Get-ADObject -Properties lastLogon
if($user.LastLogon -gt $time)
{
$time = $user.LastLogon
}
$dt = [DateTime]::FromFileTime($time)
Write-Host $username $dt }
import-csv -Encoding UTF8 -path C:\scripts\loginy.csv | foreach {
Get-ADUserLastLogon -UserName $_.logins
}
Это прекрасно работает с выводом
john 2018-05-10 14:11:28
mark 2018-11-29 14:26:58
maria 2018-11-02 11:14:17
...
Когда я пытаюсь экспортировать результаты в файл CSV по коду
$users = import-csv -Encoding UTF8 -path C:\scripts\loginy.csv
$results = @()
foreach ($_.logins in $users) {
$results += Get-ADUserLastLogon -UserName $_.logins
}
$results | Export-CSV C:\scripts\Eksporty\logowania.csv -Append -encoding "utf8"
получать ошибку
At C:\scripts\OstatnieLogowanie.ps1:19 char:12
+ foreach ($_.logins in $users) {
+ ~
Missing 'in' after variable in foreach loop.
At C:\scripts\OstatnieLogowanie.ps1:19 char:29
+ foreach ($_.logins in $users)
}
Я не могу заставить его работать более 2 часов:/
2 ответа
Изменить: я перепутал LastLogon и LastLogonTimestamp. LastLogonDate основан на LastLogonTimestamp. Различия между этими свойствами объясняются здесь и здесь. Я вернусь и обновлю свой ответ.
Вы используете Write-Host
для вывода данных:
Write-Host $username $dt
Это не сработает. Write-Host
означает "запись на экран консоли, а не на стандартный вывод". Это будет работать нормально, если вы пытаетесь отобразить данные, но вызываете $x = Get-ADUserLastLogon -UserName $login
распечатает результаты на экране консоли и ничего не будет назначено $x
переменная. Например:
PS C:\> $x = Write-Host 0
0
PS C:\> $x
PS C:\>
Посмотрите, как Write-Host все еще пишет в консоль и $x
не имеет значения?
Ваша функция должна выглядеть примерно так $username, $dt
или же Write-Output $username, $dt
или же return $username, $dt
,
Хотя на самом деле это не сработает так, как ты хочешь. Я бы, вероятно, использовал пользовательский объект (см. Get-Help about_Object_Creation -ShowWindow
) как это:
Import-Module ActiveDirectory
function Get-ADUserLastLogon([string]$userName) {
$user = Get-ADUser $userName -Properties LastLogonDate
[PSCustomObject]@{'Logins' = $username; 'LastLogonDate' = $user.LastLogonDate}
}
$users = import-csv -Encoding UTF8 -path C:\scripts\loginy.csv
$results = foreach ($user in $users) {
Get-ADUserLastLogon -UserName $user.logins
}
$results | Export-CSV C:\scripts\Eksporty\logowania.csv -Append -encoding "utf8"
Честно говоря, однако, если бы я делал то, что вы пытаетесь сделать здесь, мой настоящий код выглядел бы так:
Import-Csv -Encoding -Path C:\scripts\loginy.csv |
Select-Object -ExpandProperty logins |
Get-ADUser -Properties LastLogonDate |
Select-Object @{n = 'Logins'; e = {$_.SamAccountName}}, LastLogonDate |
Export-Csv -Path C:\scripts\Eksporty\logowania.csv -Encoding UTF8 -NoTypeInformation
Select-Object -ExpandProperty logins
пройдет только голое значение столбца логинов. Get-ADUser принимает идентификационные данные из конвейера и извлекает LastLogonDate для каждого пользователя, при условии, что SamAccountName (свойство по умолчанию) является именем входа.
Следующая строка, Select-Object @{n = 'Logins'; e = {$_.SamAccountName}}, LastLogonDate
использует вычисляемое свойство (см. примеры в Get-Help Select-Object -ShowWindow
) переименовать свойство SamAccountName в столбце с именем Logins. Вы могли бы использовать Select-Object SamAccountName, LastLogonDate
если вас не волнует название столбца. И -NoTypeInformation
параметр на Export-Csv
просто мешает добавить эту раздражающую ерунду "#TYPE System.Management.Automation.PSCustomObject" в первой строке.
$_ - это переменная для текущего значения в конвейере. Во второй части кода, поскольку у вас нет конвейера, следовательно, $_
пуст и не имеет какого-либо свойства / метода, связанного с ним.
Что вы можете сделать, это -
$users = import-csv -Encoding UTF8 -path C:\scripts\loginy.csv
foreach ($user in $users) {
Get-ADUserLastLogon -UserName $user.logins | Export-CSV C:\scripts\Eksporty\logowania.csv -Append -encoding "utf8"
}
ИЛИ ЖЕ
$users = import-csv -Encoding UTF8 -path C:\scripts\loginy.csv
foreach ($_ in $users) {
Get-ADUserLastLogon -UserName $_.logins | Export-CSV C:\scripts\Eksporty\logowania.csv -Append -encoding "utf8"
}
Хотя я бы рекомендовал не использовать последний, так как $_
это автоматическая переменная $PSItem
кроме того, у вас может быть множество других имен переменных, которые не являются ключевыми словами, функциями и т. д.
Использование +=
для расширения массива требуется создание нового экземпляра за кулисами в каждой итерации.