This is part 5 of our mini-series covering PowerShell script block logging. We are almost done, and what’s missing is a better way to read logged code. In our previous approach, the user who executed the code was returned as a cryptic SID instead of a clear-text name. Here’s a function that turns the user SID into a real name, and also uses a clever cache to speed up the SID lookup:
function Get-LoggedCode { # to speed up SID-to-user translation, # we use a hash table with already translated SIDs # it is empty at first $translateTable = @{} # read all raw events $logInfo = @{ ProviderName="Microsoft-Windows-PowerShell" Id = 4104 } Get-WinEvent -FilterHashtable $logInfo | # take each raw set of data... ForEach-Object { # turn SID into user $userSID = $_.UserId # if the cache does not contain the user SID yet... if (!$translateTable.ContainsKey($userSid)) { try { # ...try and turn it into a real name, and add it # to the cache $identifier = New-Object System.Security.Principal.SecurityIdentifier($userSID) $result = $identifier.Translate( [System.Security.Principal.NTAccount]).Value $translateTable[$userSid] = $result } catch { # if this fails, use the SID instead of a real name $translateTable[$userSid] = $userSID } } else { } # create a new object and extract the interesting # parts from the raw data to compose a "cooked" # object with useful data [PSCustomObject]@{ # when this was logged Time = $_.TimeCreated # script code that was logged Code = $_.Properties[2].Value # if code was split into multiple log entries, # determine current and total part PartCurrent = $_.Properties[0].Value PartTotal = $_.Properties[1].Value # if total part is 1, code is not fragmented IsMultiPart = $_.Properties[1].Value -ne 1 # path of script file (this is empty for interactive # commands) Path = $_.Properties[4].Value # log level # by default, only level "Warning" will be logged Level = $_.LevelDisplayName # user who executed the code # take the real user name from the cache of translated # user names User = $translateTable[$userSID] } } }