Skip to content

Instantly share code, notes, and snippets.

@jschlackman
Last active September 20, 2025 00:42
Show Gist options
  • Select an option

  • Save jschlackman/d7a2ffe4bc917f6065c5b1a8f2ef9fc5 to your computer and use it in GitHub Desktop.

Select an option

Save jschlackman/d7a2ffe4bc917f6065c5b1a8f2ef9fc5 to your computer and use it in GitHub Desktop.
#Requires -RunAsAdministrator
<#
.SYNOPSIS
Sets the last logged on AD user at the login screen.
.DESCRIPTION
Sets the last logged on user on the Windows login screen to a specified AD user. If not specified
at launch, it Will first check for a user in the managedBy attribute of the current computer and
offer the option to use that user automatically. If declined, prompts for an AD username to use instead.
This script uses ADSI for AD queries instead of the ActiveDirectory module since that module is not
installed by default on standard workstations.
Author: James Schlackman <[email protected]>
Last Modified: Aug 19 2025
.PARAMETER SamAccountName
Logon name of the user to set as the last logged on user. If specified, the managedBy attribute
of the computer's AD account will be ignored.
.PARAMETER Domain
FQDN of domain to query. If not specified, will attempt to query the default domain automatically.
.PARAMETER IgnoreManagedBy
Ignore any value set in the managedBy attribute of the computer's AD account.
#>
function Set-LastLoggedOnUser {
Param (
[String] $SamAccountName,
[String] $Domain,
[Switch] $IgnoreManagedBy
)
If (!$Domain) {
# Attempt to connect to default domain automatically
$rootDse = New-Object System.DirectoryServices.DirectoryEntry('LDAP://RootDSE')
$Domain = @($rootDse.DefaultNamingContext)[0]
}
If (!$Domain) {
Write-Warning 'Default domain could not be determined.'
} Else {
$root = New-Object System.DirectoryServices.DirectoryEntry(('LDAP://{0}' -f $Domain))
$searcher = New-Object System.DirectoryServices.DirectorySearcher($root)
$userDN = $null
# If a user was already specified, skip checking the computer object
If ($SamAccountName) {
$IgnoreManagedBy = $true
}
# Check the computer object now unless we are ignoring it
If (!$IgnoreManagedBy) {
# Get computer name from environment variable
$ComputerName = $env:COMPUTERNAME
# Find a single computer matching this name in the current domain
$searcher.Filter = '(&(objectClass=computer)(name={0}))' -f $ComputerName
[System.DirectoryServices.SearchResult]$compAccount = $searcher.FindOne()
# If we found a computer, get its description
if ($compAccount)
{
# If the computer has the managedBy attribute set, suggest that user
[String]$managedBy = $compAccount.Properties['managedBy']
if ($managedBy) {
# Confirm if we want to use this user
Write-Host 'Found the following user in the computer AD object: ' -ForegroundColor Green -NoNewline
Write-Host $managedBy
$response = (Read-Host 'Set this user as the last logged-on user? (y/N)').ToUpper()
}
If ($response -eq 'Y') {
$userDN = $managedBy
}
}
}
# Search for a specific user
If (!$userDN) {
If ($SamAccountName) {
$findName = $SamAccountName
} Else {
# Suggest possible usernames based on cached profile data
$localSIDs = (Get-LocalUser).SID.Value
$localProfiles = ((Get-ChildItem 'HKLM:\SOFTWARE\Microsoft\Windows NT\CurrentVersion\ProfileList') | Where-Object {$_.PSChildName -notin $localSIDs} | Get-ItemProperty -Name ProfileImagePath,FullProfile -ErrorAction Ignore | Where-Object {$_.FullProfile -eq 1}).ProfileImagePath | Split-Path -Leaf -ErrorAction Ignore
If ($localProfiles) {
Write-Host 'Suggested usernames based on cached user profiles:' -ForegroundColor Cyan
Write-Host ("{0}`n" -f ($localProfiles -join "`n"))
}
}
# Get a new username to set as the last logged on user
While (!$userDN) {
# Prompt for a username if one is not already specified
if (!$findName) {
$findName = Read-Host 'Enter a username to find in AD'
}
# Find the corresponding AD object
$searcher.Filter = '(&(objectClass=user)(sAMAccountName={0}))' -f $findName
[System.DirectoryServices.SearchResult]$userAccount = $searcher.FindOne()
If ($userAccount) {
$userDN = $userAccount.Properties['distinguishedname']
} Else {
$findName = $null
Write-Host 'Could not find that user in AD.' -ForegroundColor Red
}
}
# Confirm if we want to use this user
Write-Host 'Found this user in AD: ' -ForegroundColor Green -NoNewline
Write-Host $userDN
$response = (Read-Host 'Set this user as the last logged-on user? (y/N)').ToUpper()
}
# If user found and confirmed, set the registry entries to make it appear as the last logged on user
If ($response -eq 'Y') {
# Search for the user by the retrieved DN
$searcher.Filter = '(distinguishedName={0})' -f @($userDN)[0]
# Now search for the user object
$searcher.PropertiesToLoad.AddRange(('msDS-PrincipalName','displayName','objectSid'))
[System.DirectoryServices.SearchResult]$user = $searcher.FindOne()
# Get the SID of the returned user
$userSid = (New-Object System.Security.Principal.SecurityIdentifier $user.Properties['objectSid'][0],0).Value
# Now populate the registry keys needed to set this as the last logged on user
$logonUI = 'HKLM:\Software\Microsoft\Windows\CurrentVersion\Authentication\LogonUI'
$displayName = @($user.Properties['displayName'])[0]
$userName = @($user.Properties['msDS-PrincipalName'])[0]
Write-Host ('Setting {0} ({1}) as last logged on user.' -f $userName, $displayName)
Set-ItemProperty -Path $logonUI -Name 'LastLoggedOnDisplayName' -Value $displayName
Set-ItemProperty -Path $logonUI -Name 'LastLoggedOnUser' -Value $userName
Set-ItemProperty -Path $logonUI -Name 'LastLoggedOnSAMUser' -Value $userName
Set-ItemProperty -Path $logonUI -Name 'LastLoggedOnUserSID' -Value $userSid
Set-ItemProperty -Path $logonUI -Name 'SelectedUserSID' -Value $userSid
}
}
}
Set-LastLoggedOnUser
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment