Alkane Solutions
Alkane Solutions Fixed-Price Application Packaging | Trusted IT Partner
Alkane Solutions | G-Cloud Supplier Alkane Solutions | Microsoft Partner

Main menu

Skip to primary content
Skip to secondary content
  • Hire Us
    • End User Compute
      • Software Services
      • Hardware Services
      • Licensing Services
      • Security Services
      • Support Services
    • Tooling and Automation
      • Bespoke Tooling Services
      • Robotic Process Automation Services
    • Web
      • Web Hosting Services
      • Web Development Services
    • Team
    • Case StudiesCase studies of the work we have done for our clients.
  • Contact Us
  • Log In
  • Register

Use PowerShell to Find the User Profile Last Use Time

Posted on April 4, 2023 by Kae
Reply

Here we provide an example of how we can use PowerShell to find the user profile last use time.

The reason we were doing this was to purge any local profiles that hadn’t been used for, say, 4 weeks or more.  This could potentially free up valuable disk space on some of the smaller solid state drives that we maintain.

There were several methods we explored to find the most accurate time a profile was last used.

Use WMI to Find Last Use Time

One attempt included getting the LastUseTime of a user profile using WMI, but unfortunately the date just wasn’t accurate.

$computerName = "name"

Get-WmiObject -ComputerName $computerName -Class Win32_UserProfile | where-object {!($_.Special) -and !($_.Loaded) } | Sort-Object -Property LastUseTime -Descending | foreach {

    $lastusetime = [Management.ManagementDateTimeConverter]::ToDateTime($_.LastUseTime).tostring('dd/MM/yyyy HH:mm:ss')
    
    $objSID = New-Object System.Security.Principal.SecurityIdentifier ($_.SID)
    $objUser = $objSID.Translate( [System.Security.Principal.NTAccount])
    $username = $objUser.Value

    write-host $username $lastusetime   
}

Use NTUser.dat to Find Last Write Time

Another attempt was to use NTUser.dat to find the last use time, but the last write time wasn’t accurate either!

"c:\Users" | get-childitem -Directory | foreach {
    $username = $_.Name
    $path = $_.FullName
    If (Test-Path "$path\ntuser.dat")
    {
        $ntuserdat = Get-Item "$path\ntuser.dat" -force
        $ntuserdatLastWrite = $ntuserdat.LastWriteTime
        Write-Host $username $ntuserdatLastWrite   
    }
}

Find Last Logon Using Event Viewer

Finally we decided it’s most accurate to consult the event viewer logs.  Below we filter the Security auditing event log on interactive users logins, where the date of the log entry is within the last 2 weeks.

#logged in in last 14 days
$threshold = -14
$startDate = (get-date).AddDays($threshold)

#last login date (including screen unlock etc), interactive logins only, no virtual logins
$userLogins = Get-WinEvent -ProviderName 'Microsoft-Windows-Security-Auditing' -FilterXPath "*[System[EventID=4624] and EventData[Data[@Name='LogonType']='2'] and EventData[Data[@Name='VirtualAccount']='%%1843']]" | where-object TimeCreated -ge $startDate | Select-Object @{Name = 'LoginDate'; Expression = {$_.TimeCreated}}, @{Name = 'Username'; Expression = { $_.Properties.Value[5] }}, @{Name = 'SID'; Expression = { $_.Properties.Value[4]}} | Group-Object Username | 
Foreach-Object {$_.Group | Sort-Object LoginDate -Descending | Select-Object -First 1} | Foreach-Object {
    
    $username = $_.Username
    $logindate = $_.LoginDate
    $sid = $_.SID
    
    #get user profile by sid
    write-host "Processing username $username with last login date of $logindate and sid $sid"

    $wmiUserProfile = Get-WmiObject Win32_UserProfile -Filter "sid = '$sid'"
    if ($wmiUserProfile -ne $null) {        
        if (!$wmiUserProfile.Special -and !$wmiUserProfile.Loaded) {
            write-host "Attempting to remove profile for $username"
            $wmiUserProfile | Remove-WMIObject 
            
            $result = Get-WmiObject -Class Win32_UserProfile -Filter "sid = '$sid'"
            if ($result -eq $null) {
                write-host "$username profile deleted successfully."
            } else {
                write-host "Could not deleted $username profile."
            }    

        } else {
            write-host "Profile for $username is either special or currently loaded and will not be deleted."
        }
    } else {
        write-host "Could not find profile for username $username and sid $sid."
    }
}
Posted in PowerShell | Tagged ntuser.dat, User Profile | Leave a Reply

Contact Us!


    Your Name (required)

    Your Email (required)

    Subject

    Your Message

    Over

    15,000

    Applications
    Packaged

    Over

    27

    Successful
    Migrations

    Over

    100

    Happy
    Clients

    Application Packaging Services in Manchester, UK.
    12b Kennerleys Lane, Wilmslow, England, SK9 5EQ

    Application Packaging Services in London, UK.
    152-160 City Road, London, EC1V 2NX.

    © Alkane Solutions Ltd 2025
    Privacy Policy | Modern Slavery | LinkedIn | Blog Posts