Hello, this script does exactly what I need, except in my environment I need to use the invoke-command with credentials. However when I edit the script for it, it breaks. Can someone help?
2- Interactive (logon at keyboard and screen of system) Windows 2000 records Terminal Services logon as this type rather than Type 10.
3- Network (i.e. connection to shared folder on this computer from elsewhere on network or IIS logon - Never logged by 528 on W2k and forward. See event 540)
4- Batch (i.e. scheduled task)
5- Service (Service startup)
7- Unlock (i.e. unnattended workstation with password protected screen saver)
8- NetworkCleartext (Logon with credentials sent in the clear text. Most often indicates a logon to IIS with “basic authentication”)
9- NewCredentials
10- RemoteInteractive (Terminal Services, Remote Desktop or Remote Assistance)
11- CachedInteractive (logon with cached domain credentials such as when logging on to a laptop when away from the network)
#>
Another advantage to Mr. Simmers approach is that Invoke-Command requires Remote PowerShell enabled on the remote systems. His solution does not. Remote Powershell is not enabled by default for security reasons and getting it all worked out on a lot of systems (GPO or otherwise) can get ugly.
[quote quote=278478]Thank you Mr Simmers, this is exactly what I was looking / hoping for.
Tony- The reason I needed that method is we will not enable RPC or Remote PS enablement on our machines as you pointed out.
[/quote]
How are you remoting without RPC or WinRM (PS standard remoting)? Cmdlets that have a computername parameter but no session parameter use RPC for connection.
A lot of the commands that provide credentials are WMI wrappers. My assumption is that Get-WinEvent is using DCOM or WSMan to get information, which uses the underlying RPC protocol. WSMAN would require to be enabled to run Invoke-Command or create sessions. Regardless, if you are remotely connecting you would be using RPC or WSMAN to make that connection.
Mike R, in my environment, we either disable the Windows firewall(s) to allow for both Get-WinEvent and Get-WmiObject to work on remote systems, or we enable the following firewall rules if turning off the Windows Firewall is not an option. Keep in mind, we are also running McAfee as well which requires no changes.
This works now except I am unable to grab the unlock/lock/screensaver logs (auditing is enabled in GPO)
param (
[string]$Computer = (Read-Host Remote computer name),
[pscredential]$Credential = (Get-Credential),
[int]$Days = 30
)
$events = @()
$events += Get-WinEvent -ComputerName $Computer -Credential $Credential -FilterHashtable @{
LogName='Security'
Id=@(540,4634,4800,4801,4624,4608,4609,4778,4779,4802,4803)
StartTime=(Get-Date).AddDays(-$Days)
}
$events += Get-WinEvent -ComputerName $Computer -Credential $Credential -FilterHashtable @{
LogName='System'
Id=@(7001,7002)
StartTime=(Get-Date).AddDays(-$Days)
}
$type_lu = @{
7001 = 'Logon'
7002 = 'Logoff'
4800 = 'Computer was Locked'
4801 = 'Comupter was UnLocked'
529 = 'Logon Failed'
540 = 'Successful Network Logon'
4634 = 'An account was logged out'
4624 = 'An account was successfully logged in'
4647 = 'User initiated logoff'
4608 = 'Windows started up'
4609 = 'Windows shutting down'
4778 = 'A remote desktop session was reconnected'
4779 = 'A remote desktop session was disconnected'
4802 = 'screensaver started'
4803 = 'screensaver stopped'
}
$ns = @{'ns'='http://schemas.microsoft.com/win/2004/08/events/event'}
$target_xpath = "//ns:Data[@Name='TargetUserName']"
$usersid_xpath = "//ns:Data[@Name='UserSid']"
If($events) {
$results = ForEach($event in $events) {
$xml = $event.ToXml()
Switch -Regex ($event.Id) {
'4...' {
$user = (
Select-Xml -Content $xml -Namespace $ns -XPath $target_xpath
).Node.'#text'
Break
}
'7...' {
$sid = (
Select-Xml -Content $xml -Namespace $ns -XPath $usersid_xpath
).Node.'#text'
$user = (
New-Object -TypeName 'System.Security.Principal.SecurityIdentifier' -ArgumentList $sid
).Translate([System.Security.Principal.NTAccount]).Value
Break
}
}
New-Object -TypeName PSObject -Property @{
Time = $event.TimeCreated
Id = $event.Id
Type = $type_lu[$event.Id]
User = $user
}
}
If($results) {
#$results
$Results | Sort Time -Descending | Out-GridView
}
}
<#Logon types possible:
Logon Type- Description
2- Interactive (logon at keyboard and screen of system) Windows 2000 records Terminal Services logon as this type rather than Type 10.
3- Network (i.e. connection to shared folder on this computer from elsewhere on network or IIS logon - Never logged by 528 on W2k and forward. See event 540)
4- Batch (i.e. scheduled task)
5- Service (Service startup)
7- Unlock (i.e. unnattended workstation with password protected screen saver)
8- NetworkCleartext (Logon with credentials sent in the clear text. Most often indicates a logon to IIS with "basic authentication")
9- NewCredentials
10- RemoteInteractive (Terminal Services, Remote Desktop or Remote Assistance)
11- CachedInteractive (logon with cached domain credentials such as when logging on to a laptop when away from the network)
#>
ERROR:
PS C:\pstools> C:\PScripts\Audit.ps1
Remote computer name:
cmdlet Get-Credential at command pipeline position 1
Supply values for the following parameters:
New-Object : Constructor not found. Cannot find an appropriate constructor for type System.Security.Principal.SecurityIdentifier.
At C:\PScripts\Audit.ps1:57 char:21
PS C:\pstools> C:\PScripts\Audit.ps1
Remote computer name:
cmdlet Get-Credential at command pipeline position 1
Supply values for the following parameters:
New-Object : Constructor not found. Cannot find an appropriate constructor for type System.Security.Principal.SecurityIdentifier.
At C:\PScripts\Audit.ps1:56 char:26
Thanks, I tried those yesterday and they yielded the same results. I did also narrow down to one EID per Security and System and retrieved the same error.
If anyone has a better way to pull Lock/Unlock/Login/Logoff status into an xml, I would be open to hearing it. This was the best I could come up with for our needs.
This is what I use for Successful Logins. Does NOT include logoff. $System needs to be defined as the host you want to query.
$XPath = “(Event[System[EventID=4624 or EventID=4648]]) and (Event[EventData[Data[@Name=‘LogonType’] = ‘2’]] or Event[EventData[Data[@Name=‘LogonType’] = ‘3’]] or Event[EventData[Data[@Name=‘LogonType’] = ‘7’]] or Event[EventData[Data[@Name=‘LogonType’] = ‘10’]] or Event[EventData[Data[@Name=‘LogonType’] = ‘11’]]) and (Event[EventData[Data[@Name=‘SubjectUserSid’] != ‘S-1-0-0’]])”
That would work for logon, the primary need for my script is the Lock / Unlock (as they do not count as logon’s and will not show in that list. We have users that never log off, but do lock (via gpo enforcement timeout) and have to unlock to resume using the machine. We need an audit log of those events. 4800 4801
This should work (at least it did for me). And I am sure you know that unless you enable “Other Logon Events” in your advanced audit policy, 4800 and 4801 will not be logged. Again, adjust the EventID to include what you want. I added the exclusion TargetUserSid to reduce some of the noise. You should fine tune the results to get rid of more noise as there is a ton of it when you enable Other Logon Events.
$XPath = “Event[System[EventID=4624 or EventID=4648 0r EventID=4800 or EventID=4801]]) and (Event[EventData[Data[@Name=‘LogonType’] = ‘2’]]) -and (Event[EventData[Data[@Name=‘TargetUserSid’] != ‘S-1-5-18’]])”