Экспорт данных на основе логина 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 кроме того, у вас может быть множество других имен переменных, которые не являются ключевыми словами, функциями и т. д.

Использование += для расширения массива требуется создание нового экземпляра за кулисами в каждой итерации.

Другие вопросы по тегам