The Windows “Security” log contains rich audit information. By default, it logs all requests for privilege elevation which occurs when you run a program with full Administrator privileges.
To get a list of elevations that occurred on your machine, try this:
#requires -RunAsAdministrator function Get-ElevationInfo { param ( [DateTime]$Before, [DateTime]$After, [string[]]$ComputerName, $User = '*', $Privileges = '*', $Newest = [Int]::MaxValue ) $null = $PSBoundParameters.Remove('Privileges') $null = $PSBoundParameters.Remove('User') $null = $PSBoundParameters.Remove('Newest') Get-EventLog -LogName Security -InstanceId 4672 @PSBoundParameters | ForEach-Object { [PSCustomObject]@{ Time = $_.TimeGenerated User = $_.ReplacementStrings[1] Domain = $_.ReplacementStrings[2] Privileges = $_.ReplacementStrings[4] } } | Where-Object Path -like $Privileges | Where-Object User -like $User | Select-Object -First $Newest } Get-ElevationInfo -User pshero* -Newest 2 | Out-GridView
Get-ElevationInfo queries the System event log for events with ID 4672. Security information is protected, so you need to be an Administrator to run this code. This is why the code uses a #requires statement that prevents non-Admins from running the code.
The function also utilizes the automatic $PSBoundParameters hash table which contains all parameters that a user submitted. Only a part of these should be forwarded to Get-EventLog, so all parameters that serve other purposes are removed from the hash table. This way, the user can simply forward the parameters Before, After, and ComputerName to Get-EventLog.
Next, the event information is examined. All relevant information can always be found in the property ReplacementStrings which is an array. As it turns out, for events with ID 4672, the second (index 1) element is the user name, the third (index 2) is the domain, and the fifth (index 4) lists the security privileges granted.