Is there a way to find which user run what application on a server using Powershell - powershell

I am trying to find a way to find out who has ran an application (for example SQL) on a server, just to get some idea.
I tried Get-Process but this doesn't give me historic information, I want to get historical information
Get-Process -IncludeUserName *
what I want the return resule is "name of application", "user who ran it" and the last datetime it was ran by that user'

As for ...
I am trying to find a way to find out who has ran an application (for
example SQL) on a server, just to get some idea.
What you are asking for here is software metering.
SQL is a service that is always running once it is installed, so, no individual user is ever going to be running it. So, that is a bad example. MS Word for example would be a better example.
Yet there is nothing native in PowerShell that does this, software metering, but of course PowerShell can look at event logs. Yet if your auditing is not setup correctly then it's moot. This is better for a software metering tool, and there are several out there. So, why try and reinvent the wheel.
As for ...
I tried Get-Process but this doesn't give me historic information, I
want to get historical information
That is not what a process is nor what Get-Process is for. It, Get-Process only checks for and lists whatever process is currently running, regardless of what/who launched it.
As for...
what I want the return resule is "name of application", "user who ran
it" and the last datetime it was ran by that user'
As long as the process is running, you can get this, with that cmdlet.
However, what are you trying to accomplish by this?
Again, there are purpose built tools to meter software use.
https://learn.microsoft.com/en-us/sccm/apps/deploy-use/monitor-app-usage-with-software-metering
If you must go down this reinvent the wheel road, using scripting, then you need a task watcher on the target machines, which watches for the WinWord process to appear.
Get-Process -IncludeUserName |
Where ProcessName -EQ 'Winword'
... you then write those results to a file or database or your own event log each time you see that process.
Use PowerShell to Create and to Use a New Event Log
New-EventLog -LogName ScriptingGuys -Source scripts
When the command runs, no output appears to the Windows PowerShell console. To ensure the command actually created a new event log, I use
the Get-EventLog cmdlet with the –List parameter. Here is the command
and the associated output.
Write-EventLog -LogName ScriptingGuys -Source scripts -Message “Dude, it works … COOL!” -EventId 0 -EntryType information
Or just to a file
Get-Process -IncludeUserName |
Where ProcessName -EQ 'Winword' |
Select-Object -Property Name, StartTime, Username |
Export-Csv -Path 'F:\Temp\AppLaunchLog.csv' -Append
Import-Csv -Path 'F:\Temp\AppLaunchLog.csv'
# Results
Name StartTime UserName
---- --------- --------
WINWORD 5/23/2019 9:02:53 PM WS01\LabUser001

Related

Get-EventLog not parsing Message when run by SYSTEM user

Problem
I am trying to schedule a job that monitors events on remote machines.
I wrote the script based on the Get-EventLog command and it works properly when run by my account. But when I run the Get-EventLog as SYSTEM user, the .Message attribute of the returned objects shows the following error:
The description for Event ID '4724' in Source 'Microsoft-Windows-Security-Auditing' cannot be found. The local computer may not have the necessary registry information or message DLL files to display the message, or you may not have permission to access them. The following information is part of the event: {somedata}
When I use the Get-WinEvent command as SYSTEM user, the problem does not appear and the .Message part displays properly.
I would stick with Get-WinEvent, especially since the data is much easier to parse (thanks to the ToXML() method), but the Get-EventLog happens to be terribly faster :(
Question
Does anyone have any idea why the Get-EventLog fails to render .Message when run by SYSTEM user and perhaps how to fix it?
To avoid obvious answers:
the COMPUTER$ account is member of DOMAIN\Event Log Readers group,
the COMPUTER$ account does have the read privileges over the HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\EventLog\Security on remote machines,
obviously, the registry entries for Microsoft-Windows-Security-Auditing and related DLL's are identical on both the source and target computers.
Try:
Get-WinEvent -LogName “Microsoft-Windows-Security-Auditing” | where ID -eq 4724 | select-object -ExpandProperty Message

View recent remote powershell connections

Is there an event log of some kind that is made when a remote pssession is initiated on a computer? I need to be able to see where a remote session has originated from.
Currently I am running
Get-EventLog -LogName "Windows powershell" -newest 100 | Format-List -Property * | where {$_.UserID -eq "username"}
But it is not filtering and/or showing remote connections.
We are here to help you with code issues. This is really not a code issue, but a understanding of how to set up and where correlate such detail. So, it's potentially a question for another forum.
Anyway, to get you close to what you are after, there are extra steps you need to employ to get such information. More on that in a bit.
Now, once you get this all setup and you write your script to pull / look at such info and you are having issues with that, then post that back here for folks to see what can be done
So, that leads us to here:
There are three general areas for logging available:
• Module Logging
• Script Block Logging
• PowerShell Transcription
If you have not done so, I would advise enabling on PS auditing and script logging for more insight into this use case and well as transcript logging (which can capture all commands / code executed on a host machine). If you set all this up properly, you fist look to the transcript log for details and well as the log name you reference in your post for other details.
Set this enterprise wide via GPO or DSC.
There is lot's of guidance on how to set this up.
For Example:
Audit PowerShell Usage using Transcription and Logging
Get-Command -Name '*transcript*'
CommandType Name Version Source
----------- ---- ------- ------
Cmdlet Get-TRSTranscriptionJob 3.3.234.0 AWSPowerShell
Cmdlet Get-TRSTranscriptionJobList 3.3.234.0 AWSPowerShell
Cmdlet Start-Transcript 3.0.0.0 Microsoft.PowerShell.Host
Cmdlet Start-TRSTranscriptionJob 3.3.234.0 AWSPowerShell
Cmdlet Stop-Transcript 3.0.0.0 Microsoft.PowerShell.Host
https://learn.microsoft.com/en-us/powershell/wmf/5.0/audit_overview
Practical PowerShell Security: Enable Auditing and Logging with DSC
https://blogs.technet.microsoft.com/ashleymcglone/2017/03/29/practical-powershell-security-enable-auditing-and-logging-with-dsc
More New Stuff in PowerShell V5: Extra PowerShell Auditing
Get-Module Microsoft.* | Select Name, LogPipelineExecutionDetails
Get-Module Microsoft.* | ForEach { $_.LogPipelineExecutionDetails = $True }
(Import-Module ActiveDirectory).LogPipelineExecutionDetails = $True
Get-WinEvent -FilterHashtable #{LogName='Windows PowerShell';Id ='800'} -MaxEvents 1 | Select -Expand Message
https://learn-powershell.net/2014/08/26/more-new-stuff-in-powershell-v5-extra-powershell-auditing
Investigating PowerShell: Command and Script Logging
https://www.crowdstrike.com/blog/investigating-powershell-command-and-script-logging

Powershell: Re-create RDS Remote Apps by Looping?

I'm stumped. I can usually take the output of one powershell command and use it as the input to another powershell command. For example:
Get-Mailbox | Set-Mailbox -MaxSendSize 40MB
This will loop through every mailbox and then set the maximum send size to 40 MB in Exchange 2007.
...but the same doesn't work with get-rdremoteapp and new-rdremoteapp.
Get-RDRemoteApp | new-rdremoteapp -collectionname APPSNEW -connectionbroker edge-1.mydom.local
The goal of this command is that we are preparing to Migrate from a Windows 2012 RDS environment on virtual servers to a Windows 2012 R2 environment on physical servers.
On the virtual 'edge' server, I should be able to get all the RD Remote Apps, loop through them, and then use the 'new-rdremoteapp' command to create them on the new 'edge-1' server.
What actually happens is the command runs and creates the 1st remote app, then exits without an error. It doesn't process the apps in the list.
I think I need to use foreach-object, but after reading the docs and playing around, I can't seem to get it to work.
I couldn't find an easy out. I had to specify a bunch of parameters like so:
Get-RDRemoteApp | foreach-object -process {new-rdremoteapp -collectionname APPSNEW -connectionbroker edge-1.mydom.local -displayname $_.displayname -filepath $_.filepath -alias $_.alias -commandlinesetting $_.commandlinesetting -usergroups $_.usergroups}
Time to find a job that has more bash scripting... ;)

Measure 'Idle' time between CTRL-ALT-DEL and user typing in password and loging on -Windows 7

Windows 7 has the built in 'Boot Performance Diagnostics' and judging by the numerous reboots i've done, it does generate every now and then a detailed log on the user's login process and possible slowness.
That is not good enough for what I'm after though.
I want to measure EVERY Boot on a given machine.
There is little information however available on how to force it, except fiddling with registry keys that are System Protected so you don't tamper with them.
Some of the information can be found in the eventlogs so i switched to tracing the eventid 12
$yesterday = (get-date) - (New-TimeSpan -day 2)
$startuplog= Get-WinEvent -FilterHashTable #{LogName='System'; ID=12;
StartTime=$yesterday} -ErrorAction SilentlyContinue
But does anyone know how one can measure when the system was ready (ctrl-alt-del) and when the user hit the enter button after typing in the password? Is there a flag that can be set to raise such an event in a (diagnostics) event log?
You can compare the power state timestamp to the "Last Interactive Logon" feature of AD DS. That feature requires a domain functional level (DFF) of Windows Server 2008 r2 to work and workstation infrastructure of windows vista or later. The "msDS-LastSuccessfulInteractiveLogonTime" attribute is what you want. It's the time stamp of the last successful interactive logon (ctrl+alt+del).
To enable Last Interactive Logon on your domain:
http://technet.microsoft.com/en-us/library/dd446680(v=ws.10).aspx
Command to query attribute:
$Computer = 'hostname'
Get-ADComputer -Filter "name -eq $Computer" -Properties * | Select msDS-LastSuccessfulInteractiveLogonTime
P.S. Try to get away from using "-ErrorAction". In it's place, use Try/Catch/Finally code blocks.
http://blogs.technet.com/b/heyscriptingguy/archive/2010/03/11/hey-scripting-guy-march-11-2010.aspx

check for last number of users logged in to machine?

I'm trying to come up with a powershell script thatcan determine the last number of users that logged on to a machine. I'm stuck on to how to approach it. If I'm correct, using a get-wmiobject call will only get the last user. I'm wondering if maybe there is a call I can do to get the history of something like the user folder and get the last users that modified that?Or is there some simpler way?
http://social.technet.microsoft.com/Forums/en/winserverpowershell/thread/c61dc944-6c40-4ab8-93f8-8c345c37b0d4
Basically, all user logins are saved in the security log of each windows server. These are set in the log with the following eventIDs: 528 and 540. These two IDs are for a direct or a remote login to a machine. For my specific need, I have to following line in my script. If you have a similar need, be sure to read up on windows eventIDs on a site like this one
Get-EventLog -logname security -ComputerName $svr -Newest 100 | where {$_.eventID -eq 528
-or 540} | select time,user
enjoy!