-1

I have simple csv file with column 'logins'

logins
john
mark
maria
...

Have powershell script to check their last logontime:

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
}

This works fine with output

john 2018-05-10 14:11:28
mark 2018-11-29 14:26:58
maria 2018-11-02 11:14:17
...

When I try to export results it to csv file by code

$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"

getting error

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)

}

I can't get it work over 2 hours :/

daedsidog
  • 1,732
  • 2
  • 17
  • 36
Curl User
  • 115
  • 1
  • 3
  • 12

2 Answers2

2

Edit: I've confused LastLogon and LastLogonTimestamp. LastLogonDate is based on LastLogonTimestamp. The differences between these properties are explained here and here. I will come back and update my answer.


You're using Write-Host to output data:

Write-Host $username $dt

This won't work. Write-Host means "write to the console screen, not to standard output." That will work just fine if you're trying to display data, but calling $x = Get-ADUserLastLogon -UserName $login will print the results to the console screen and nothing would be assigned to the $x variable. For example:

PS C:\> $x = Write-Host 0
0
PS C:\> $x
PS C:\>

See how Write-Host still wrote to the console and $x doesn't have a value?

Your function should look something like $username, $dt or Write-Output $username, $dt or return $username, $dt.

Although that's still not really going to work like you want. I would probably use a custom object (see Get-Help about_Object_Creation -ShowWindow) like this:

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"

Frankly, however, if I were doing what you're trying to do here, my actual code would look like this:

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 will pass just the bare value of the logins column. Get-ADUser accepts identities from the pipeline, and it fetches the LastLogonDate for each user, as long as the SamAccountName (a default property) which is the logon name.

The next line, Select-Object @{n = 'Logins'; e = {$_.SamAccountName}}, LastLogonDate uses a calculated property (See the examples in Get-Help Select-Object -ShowWindow) to rename the SamAccountName property in a column named Logins. You could use Select-Object SamAccountName, LastLogonDate if you don't care about the column name. And the -NoTypeInformation parameter on Export-Csv just keeps it from adding that annoying "#TYPE System.Management.Automation.PSCustomObject" nonsense on the first line.

Bacon Bits
  • 30,782
  • 5
  • 59
  • 66
  • Thanks for detailed information. Your codes works but logon date is different that from my function. I've checked which date is proper with cmd: net user %login% /domain and your script has wrong date.... – Curl User Dec 18 '18 at 16:35
  • @CurlUser Ah, you're right. I'm confusing LastLogon and LastLogonTimestamp. LastLogonDate is based on LastLogonTImestamp. Differences are explained [here](https://social.technet.microsoft.com/wiki/contents/articles/22461.understanding-the-ad-account-attributes-lastlogon-lastlogontimestamp-and-lastlogondate.aspx). I will update my answer. – Bacon Bits Dec 18 '18 at 17:45
0

$_ is the variable for the current value in pipeline. In your second part of code, since you don't have a pipeline, hence $_ is empty and doesn't have any property/method associated with it.

What you can do is -

$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"
} 

OR

$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"
} 

Although I would recommend not using the latter since $_ is an automatic variable $PSItem and beside you can have plenty other names for a variable which are not keywords, functions etc.

The use of += to extend an array requires creating a new instance behind the scenes in every iteration.

Vivek Kumar Singh
  • 3,223
  • 1
  • 14
  • 27
  • 1
    Rebuilding the array with += on every iteration is inefficient, better assign the output of the foreach directly to the variable `$results = foreach (` –  Dec 18 '18 at 13:28
  • Not exactly, when exporting directly, you don't need the `$results` variable at all. –  Dec 18 '18 at 14:47
  • doesn work...At C:\scripts\OstatnieLogowanie.ps1:19 char:3 + } | Export-CSV C:\scripts\Eksporty\logowania.csv -Append -encoding "u ... + ~ An empty pipe element is not allowed. + CategoryInfo : ParserError: (:) [], ParentContainsErrorRecordException + FullyQualifiedErrorId : EmptyPipeElement – Curl User Dec 18 '18 at 16:05
  • @CurlUser - Try it now. – Vivek Kumar Singh Dec 18 '18 at 18:03