Advertisement
bwood42

Powershell Get-Laslogon Example

May 30th, 2014
449
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 9.41 KB | None | 0 0
  1. Function Get-LastLogon
  2. {
  3. <#
  4.  
  5. .SYNOPSIS
  6. This function will list the last user logged on or logged in.
  7.  
  8. .DESCRIPTION
  9. This function will list the last user logged on or logged in. It will detect if the user is currently logged on
  10. via WMI or the Registry, depending on what version of Windows is running on the target. There is some "guess" work
  11. to determine what Domain the user truly belongs to if run against Vista NON SP1 and below, since the function
  12. is using the profile name initially to detect the user name. It then compares the profile name and the Security
  13. Entries (ACE-SDDL) to see if they are equal to determine Domain and if the profile is loaded via the Registry.
  14.  
  15. .PARAMETER ComputerName
  16. A single Computer or an array of computer names. The default is localhost ($env:COMPUTERNAME).
  17.  
  18. .PARAMETER FilterSID
  19. Filters a single SID from the results. For use if there is a service account commonly used.
  20.  
  21. .PARAMETER WQLFilter
  22. Default WQLFilter defined for the Win32_UserProfile query, it is best to leave this alone, unless you know what
  23. you are doing.
  24. Default Value = "NOT SID = 'S-1-5-18' AND NOT SID = 'S-1-5-19' AND NOT SID = 'S-1-5-20'"
  25.  
  26. .EXAMPLE
  27. $Servers = Get-Content "C:\ServerList.txt"
  28. Get-LastLogon -ComputerName $Servers
  29.  
  30. This example will return the last logon information from all the servers in the C:\ServerList.txt file.
  31.  
  32. Computer : SVR01
  33. User : WILHITE\BRIAN
  34. SID : S-1-5-21-012345678-0123456789-012345678-012345
  35. Time : 9/20/2012 1:07:58 PM
  36. CurrentlyLoggedOn : False
  37.  
  38. Computer : SVR02
  39. User : WILIHTE\BRIAN
  40. SID : S-1-5-21-012345678-0123456789-012345678-012345
  41. Time : 9/20/2012 12:46:48 PM
  42. CurrentlyLoggedOn : True
  43.  
  44. .EXAMPLE
  45. Get-LastLogon -ComputerName svr01, svr02 -FilterSID S-1-5-21-012345678-0123456789-012345678-012345
  46.  
  47. This example will return the last logon information from all the servers in the C:\ServerList.txt file.
  48.  
  49. Computer : SVR01
  50. User : WILHITE\ADMIN
  51. SID : S-1-5-21-012345678-0123456789-012345678-543210
  52. Time : 9/20/2012 1:07:58 PM
  53. CurrentlyLoggedOn : False
  54.  
  55. Computer : SVR02
  56. User : WILIHTE\ADMIN
  57. SID : S-1-5-21-012345678-0123456789-012345678-543210
  58. Time : 9/20/2012 12:46:48 PM
  59. CurrentlyLoggedOn : True
  60.  
  61. .LINK
  62. http://msdn.microsoft.com/en-us/library/windows/desktop/ee886409(v=vs.85).aspx
  63. http://msdn.microsoft.com/en-us/library/system.security.principal.securityidentifier.aspx
  64.  
  65. .NOTES
  66. Author: Brian C. Wilhite
  67. Date: "09/20/2012"
  68. Updates: Added FilterSID Parameter
  69. Cleaned Up Code, defined fewer variables when creating PSObjects
  70. ToDo: Clean up the UserSID Translation, to continue even if the SID is local
  71. #>
  72.  
  73. [CmdletBinding()]
  74. param(
  75. [Parameter(Position=0,ValueFromPipeline=$true)]
  76. [Alias("CN","Computer")]
  77. [String[]]$ComputerName="$env:COMPUTERNAME",
  78. [String]$FilterSID,
  79. [String]$WQLFilter="NOT SID = 'S-1-5-18' AND NOT SID = 'S-1-5-19' AND NOT SID = 'S-1-5-20'"
  80. )
  81.  
  82. Begin
  83. {
  84. #Adjusting ErrorActionPreference to stop on all errors
  85. $TempErrAct = $ErrorActionPreference
  86. $ErrorActionPreference = "Stop"
  87. #Exclude Local System, Local Service & Network Service
  88. }#End Begin Script Block
  89.  
  90. Process
  91. {
  92. Foreach ($Computer in $ComputerName)
  93. {
  94. $Computer = $Computer.ToUpper().Trim()
  95. Try
  96. {
  97. #Querying Windows version to determine how to proceed.
  98. $Win32OS = Get-WmiObject -Class Win32_OperatingSystem -ComputerName $Computer
  99. $Build = $Win32OS.BuildNumber
  100.  
  101. #Win32_UserProfile exist on Windows Vista and above
  102. If ($Build -ge 6001)
  103. {
  104. If ($FilterSID)
  105. {
  106. $WQLFilter = $WQLFilter + " AND NOT SID = `'$FilterSID`'"
  107. }#End If ($FilterSID)
  108. $Win32User = Get-WmiObject -Class Win32_UserProfile -Filter $WQLFilter -ComputerName $Computer
  109. $LastUser = $Win32User | Sort-Object -Property LastUseTime -Descending | Select-Object -First 1
  110. $Loaded = $LastUser.Loaded
  111. $Script:Time = ([WMI]'').ConvertToDateTime($LastUser.LastUseTime)
  112.  
  113. #Convert SID to Account for friendly display
  114. $Script:UserSID = New-Object System.Security.Principal.SecurityIdentifier($LastUser.SID)
  115. $User = $Script:UserSID.Translate([System.Security.Principal.NTAccount])
  116. }#End If ($Build -ge 6001)
  117.  
  118. If ($Build -le 6000)
  119. {
  120. If ($Build -eq 2195)
  121. {
  122. $SysDrv = $Win32OS.SystemDirectory.ToCharArray()[0] + ":"
  123. }#End If ($Build -eq 2195)
  124. Else
  125. {
  126. $SysDrv = $Win32OS.SystemDrive
  127. }#End Else
  128. $SysDrv = $SysDrv.Replace(":","$")
  129. $Script:ProfLoc = "\\$Computer\$SysDrv\Documents and Settings"
  130. $Profiles = Get-ChildItem -Path $Script:ProfLoc
  131. $Script:NTUserDatLog = $Profiles | ForEach-Object -Process {$_.GetFiles("ntuser.dat.LOG")}
  132.  
  133. #Function to grab last profile data, used for allowing -FilterSID to function properly.
  134. function GetLastProfData ($InstanceNumber)
  135. {
  136. $Script:LastProf = ($Script:NTUserDatLog | Sort-Object -Property LastWriteTime -Descending)[$InstanceNumber]
  137. $Script:UserName = $Script:LastProf.DirectoryName.Replace("$Script:ProfLoc","").Trim("\").ToUpper()
  138. $Script:Time = $Script:LastProf.LastAccessTime
  139.  
  140. #Getting the SID of the user from the file ACE to compare
  141. $Script:Sddl = $Script:LastProf.GetAccessControl().Sddl
  142. $Script:Sddl = $Script:Sddl.split("(") | Select-String -Pattern "[0-9]\)$" | Select-Object -First 1
  143. #Formatting SID, assuming the 6th entry will be the users SID.
  144. $Script:Sddl = $Script:Sddl.ToString().Split(";")[5].Trim(")")
  145.  
  146. #Convert Account to SID to detect if profile is loaded via the remote registry
  147. $Script:TranSID = New-Object System.Security.Principal.NTAccount($Script:UserName)
  148. $Script:UserSID = $Script:TranSID.Translate([System.Security.Principal.SecurityIdentifier])
  149. }#End function GetLastProfData
  150. GetLastProfData -InstanceNumber 0
  151.  
  152. #If the FilterSID equals the UserSID, rerun GetLastProfData and select the next instance
  153. If ($Script:UserSID -eq $FilterSID)
  154. {
  155. GetLastProfData -InstanceNumber 1
  156. }#End If ($Script:UserSID -eq $FilterSID)
  157.  
  158. #If the detected SID via Sddl matches the UserSID, then connect to the registry to detect currently loggedon.
  159. If ($Script:Sddl -eq $Script:UserSID)
  160. {
  161. $Reg = [Microsoft.Win32.RegistryKey]::OpenRemoteBaseKey([Microsoft.Win32.RegistryHive]"Users",$Computer)
  162. $Loaded = $Reg.GetSubKeyNames() -contains $Script:UserSID.Value
  163. #Convert SID to Account for friendly display
  164. $Script:UserSID = New-Object System.Security.Principal.SecurityIdentifier($Script:UserSID)
  165. $User = $Script:UserSID.Translate([System.Security.Principal.NTAccount])
  166. }#End If ($Script:Sddl -eq $Script:UserSID)
  167. Else
  168. {
  169. $User = $Script:UserName
  170. $Loaded = "Unknown"
  171. }#End Else
  172.  
  173. }#End If ($Build -le 6000)
  174.  
  175. #Creating Custom PSObject For Output
  176. New-Object -TypeName PSObject -Property @{
  177. Computer=$Computer
  178. User=$User
  179. SID=$Script:UserSID
  180. Time=$Script:Time
  181. CurrentlyLoggedOn=$Loaded
  182. } | Select-Object Computer, User, SID, Time, CurrentlyLoggedOn
  183.  
  184. }#End Try
  185.  
  186. Catch
  187. {
  188. If ($_.Exception.Message -Like "*Some or all identity references could not be translated*")
  189. {
  190. Write-Warning "Unable to Translate $Script:UserSID, try filtering the SID `nby using the -FilterSID parameter."
  191. Write-Warning "It may be that $Script:UserSID is local to $Computer, Unable to translate remote SID"
  192. }
  193. Else
  194. {
  195. Write-Warning $_
  196. }
  197. }#End Catch
  198.  
  199. }#End Foreach ($Computer in $ComputerName)
  200.  
  201. }#End Process
  202.  
  203. End
  204. {
  205. #Resetting ErrorActionPref
  206. $ErrorActionPreference = $TempErrAct
  207. }#End End
  208.  
  209. }# End Function Get-LastLogon
  210.  
  211.  
  212.  
  213.  
  214.  
  215. $serverlist = Get-ADComputer -Filter 'OperatingSystem -like "*Server*"'
  216.  
  217. foreach ($server in $serverlist)
  218. {
  219.  
  220. Get-lastlogon -Computername $server.name | Select * | Export-Csv e:\scripts\output\Last_Logon_Stuff.csv -Append -NoTypeInformation
  221.  
  222. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement