Get last user logon time without AD

December 25th, 2019 | Tags:
function Get-LastLogon {
    [CmdletBinding()]
    param(
        [Parameter(ValueFromPipeline = $true)]
        [String]$ComputerName = $env:COMPUTERNAME
    )

    process {
        Get-WmiObject Win32_UserProfile -ComputerName $ComputerName -Filter "Special='FALSE'" | ForEach-Object {    
            # Attempt to get the UserAccount using WMI
            $userAccount = Get-WmiObject Win32_UserAccount -Filter "SID='$($_.SID)'" -ComputerName $ComputerName

            # To satisfy WMI all single \ in a path must be escaped.
            # Prefer to use NTUser.dat for last modification
            $path = (Join-Path $_.LocalPath 'ntuser.dat') -replace '\\', '\\'
            $cimObject = Get-WmiObject CIM_DataFile -Filter "Name='$path'" -ComputerName $ComputerName
            if ($null -eq $cimObject) {
                # Fall back to the directory
                $path = $_.LocalPath -replace '\\', '\\'
                $cimObject = Get-WmiObject CIM_Directory -Filter "Name='$path'" -ComputerName $ComputerName
            }
            $lastModified = $null
            if ($null -ne $cimObject) {
                $lastModified = [System.Management.ManagementDateTimeConverter]::ToDateTime($cimObject.LastModified)
            }
            # See if LastUseTime is more useful.
            $lastUsed = $null
            if ($null -ne $_.LastUseTime) {
                $lastUsed = [System.Management.ManagementDateTimeConverter]::ToDateTime($_.LastUseTime)
            }

            # Profile type
            $profileType = switch ($_.Status) {
                1 { "Temporary" }
                2 { "Roaming" }
                4 { "Mandatory" }
                8 { "Corrupted" }
                0 { "LOCAL" }
            }

            [PSCustomObject]@{
                ComputerName = $ComputerName
                Username     = $userAccount.Caption
                LastChanged  = $lastModified
                LastUsed     = $lastUsed
                SID          = $_.SID
                Path         = $_.LocalPath
                ProfileType  = $profileType
            }
        }
    }
}

$myDomain = Get-Content C:\temp\Domain.txt
Get-Content C:\temp\Computers1.txt | ForEach-Object {
    $ComputerName = $_ + $myDomain 
    if (Test-Connection $ComputerName -Quiet -Count 3) {
        Get-LastLogon -ComputerName $ComputerName | Select-Object *, @{Name='Status';Expression={ 'OK' }} |
            Where-Object { $_.LastChanged -lt (Get-Date).AddDays(-30) }
    } else {
        # Normalise the output so we don't lose columns in the export
        $ComputerName | Select-Object @{Name='ComputerName';e={ $ComputerName }},
            Username, LastChanged, LastUsed, SID, Path, ProfileType, @{Name='Status';Expression={ 'PING FAILED' }}
    }
} | Export-Csv 'C:\temp\Profiles.csv' -NoTypeInformation
No comments yet.