Vb.net get username that is running process - vb.net

I'm making a program that looks for processes and can see which user is using them. I've got the scanning code, but not the username code. The username has to be a string. For example: I have 2 people running some processes and the processes will show in the listview. The first column is for processes and the second is for the username. I want it to be like:
(process here) (username here)
(process here) (username here)....
You get the point I think and there's much more processes than that running on the computer. The question is: How do you get the username for someone using the process?
Edit: The code. This is my code.
For Each pr As Process In Process.GetProcesses
Dim lvi As ListViewItem = ListView1.Items.Add(CStr(pr.ProcessName))
'Now I need something to put for the username
Next
This is the other one that is most common.
Public Function GetProcessOwner(processId As Integer) As String
Dim query As String = "Select * From Win32_Process Where ProcessID = " + processId
Dim searcher As New ManagementObjectSearcher(query)
Dim processList As ManagementObjectCollection = searcher.[Get]()
For Each obj As ManagementObject In processList
Dim argList As String() = New String() {String.Empty, String.Empty}
Dim returnVal As Integer = Convert.ToInt32(obj.InvokeMethod("GetOwner", argList))
If returnVal = 0 Then
' argList(0) == User
' argList(1) == DOMAIN
Return argList(0)
End If
Next
Return "NO OWNER"
End Function

This code is taken from here, where you can find more information if you need it. Basically, on a console app this will print the process name and the user to the screen:
Public Shared Sub Main()
Dim selectQuery As SelectQuery = New SelectQuery("Win32_Process")
Dim searcher As ManagementObjectSearcher = New
ManagementObjectSearcher(selectQuery)
For Each proc As ManagementObject In searcher.Get
Console.WriteLine(proc("Name").ToString)
Dim s(1) As String
proc.InvokeMethod("GetOwner", CType(s, Object()))
Console.WriteLine(("User: " & (s(1) + ("\\" + s(0)))))
Next
Console.ReadLine()
End Sub
This could be implemented as a function, like:
Public Function GetUserName(ByVal ProcessName As String)
Dim selectQuery As SelectQuery = New SelectQuery("Win32_Process")
Dim searcher As ManagementObjectSearcher = New ManagementObjectSearcher(selectQuery)
Dim y As System.Management.ManagementObjectCollection
y = searcher.Get
For Each proc As ManagementObject In y
Dim s(1) As String
proc.InvokeMethod("GetOwner", CType(s, Object()))
Dim n As String = proc("Name").ToString()
If n = ProcessName & ".exe" Then
Return ("User: " & s(1) & "\\" & s(0))
End If
Next
End Function
Just for reference, proc.InvokeMethod("GetOwner", CType(s, Object())) will return an array like this:
Index 0: Owner/user name
Index 1: Domain
And in our case, will store it in s(1).
Hope this helps :)
Notes:
If the function returns something like User: \\ then the process is probably a special windows process. To see which processes will act like this (for windows users):
Right click on the task bar
Select Start Task Manager
In the Processes tab, in the User Name column, some processes will have a blank cell instead of a user name.
Edit:
The VB.NET function has been edited and should now work, although I have no idea why the console program still worked. At any rate I've left it alone, if it still works why change it?

Related

How to retrieve properties for an Active Directory user using DirectorySearcher in VB.Net

I am trying to retrieve the email address for a known Active Directory user by using their login ID and the DirectorySearcher.FindOne() method in VB.Net but I have been unable to get any results.
Sorry but I am new to VB.Net and do not know where I am going wrong. I have tried using various examples that I have found on the net but they all are in C#. I have been able to convert the code to VB but I am still not able to pull results using what I have found. In the latest example I found here! it is using the FindAll() method and putting the results in a SearchResultCollection object. The collection ended up with a count of 0 so I have tried using the FindOne() method and tried to put the result in a SearchResult object. This didn't work for me either.
Public Shared Sub RetrieveUser(ByVal username As String)
Dim propUsername As String = "samaccountname"
Dim propFirstName As String = "givenName"
Dim propLastName As String = "sn"
Dim propDisplayName As String = "cn"
Dim propMail As String = "mail"
Dim propGuid As String = "objectguid"
Dim results As SearchResultCollection
Dim result As SearchResult
Dim directoryEntry As DirectoryEntry = New DirectoryEntry("LDAP_PATH", "DOMIAIN\USERNAME", "PASSWORD", AuthenticationTypes.ServerBind)
Using directorySearcher As DirectorySearcher = New DirectorySearcher(directoryEntry)
directorySearcher.PropertiesToLoad.Add(propUsername)
directorySearcher.PropertiesToLoad.Add(propDisplayName)
directorySearcher.PropertiesToLoad.Add(propFirstName)
directorySearcher.PropertiesToLoad.Add(propLastName)
directorySearcher.PropertiesToLoad.Add(propMail)
directorySearcher.PropertiesToLoad.Add(propGuid)
directorySearcher.Filter = String.Format("({0})", "&(objectClass=user)(cn=" & username & ")")
directorySearcher.SearchScope = SearchScope.Subtree
' directorySearcher.SearchRoot.AuthenticationType = AuthenticationTypes.Secure
directorySearcher.PageSize = 100
'results = directorySearcher.FindAll()
result = directorySearcher.FindOne()
'For Each result In results
If result.Properties.Contains(propUsername) Then
Console.WriteLine("User Name: " & result.Properties(propUsername)(0))
End If
If result.Properties.Contains(propGuid) Then
Console.WriteLine("User GUID: " & BitConverter.ToString(CType(result.Properties(propGuid)(0), Byte())).Replace("-", String.Empty))
End If
If result.Properties.Contains(propMail) Then
Console.WriteLine("Mail ID: " & result.Properties(propMail)(0))
End If
If result.Properties.Contains(propDisplayName) Then
Console.WriteLine("DisplayName: " & result.Properties(propDisplayName)(0))
End If
'Next
directorySearcher.Dispose()
directoryEntry.Dispose()
End Using
End Sub

how I can get the process username

I wanna get process username a try p.StartInfo.UserName but it return Empty string
I run this code from windows service because I need to know how users logon the PC from service and write Event Log
Public Function GetUserName(ByVal ProcessName As String)
Dim selectQuery As SelectQuery = New SelectQuery("Win32_Process")
Dim searcher As ManagementObjectSearcher = New ManagementObjectSearcher(selectQuery)
Dim y As System.Management.ManagementObjectCollection
y = searcher.Get
For Each proc As ManagementObject In y
Dim s(1) As String
proc.InvokeMethod("GetOwner", CType(s, Object()))
Dim n As String = proc("Name").ToString()
If n = ProcessName & ".exe" Then
Return ("User: " & s(1) & "\\" & s(0))
End If
Next
End Function
Me.txtUser.Text = Environment.UserName
Me.txtDomain.Text = Environment.UserDomainName

How to kill Process by User?

I am using an application that kills the process iexplore (Internet Explorer) on a terminal server. The issue I am encountering is that I kill all processes of Internet Explorer on the terminal server, not just the one of the current user.
So if I log on as User1 and kill IE, it will be killed for User2, User3 and so on ... I only want User1's Internet Explorer to be killed. I use the following code to kill my process:
Private Sub ClearProcesses(ByVal ProcessName As String)
Dim myProcesses = Process.GetProcessesByName(ProcessName)
For Each Proc As Process In myProcesses
Try
Proc.Kill()
Catch ex As Exception
MsgBox(ex.Message, MsgBoxStyle.Critical, "ClearProcess")
End Try
Next
End Sub
Is there a way to only kill the process for User1?
You can use WMI to get the owner of a Process, and verify that the process is owned by the current user.
Using a Function like so:
Public Function GetProcessOwner(processId As Integer) As String
Dim query As String = "Select * From Win32_Process Where ProcessID = " + processId
Dim searcher As New ManagementObjectSearcher(query)
Dim processList As ManagementObjectCollection = searcher.[Get]()
For Each obj As ManagementObject In processList
Dim argList As String() = New String() {String.Empty, String.Empty}
Dim returnVal As Integer = Convert.ToInt32(obj.InvokeMethod("GetOwner", argList))
If returnVal = 0 Then
' argList(0) == User
' argList(1) == DOMAIN
Return argList(0)
End If
Next
Return "NO OWNER"
End Function
You should be able to do something like:
Private Sub ClearProcesses(ByVal ProcessName As String)
Dim myProcesses = Process.GetProcessesByName(ProcessName).Where(Function(p) GetProcessOwner(p.Id) = currentUser)
' Your current code...

Find out who is running the process on the remote machine

I am trying to get a list of processes running on remote machine and the username running them. So far I've got:
Dim ps As System.Diagnostics.Process
For Each ps In System.Diagnostics.Process.GetProcesses("myserver")
ListBox1.Items.Add(ps.ProcessName)
Next
How to get permissions for using System.Diagnostics.Process.GetProcess(string)? - this might be a better way to do it. It is in C# I can translate it if you want.
''' using System.Management;
' don't forget! in VS you may have to add a new reference to this DLL
Dim op As New ConnectionOptions()
op.Username = "REMOTE_USER"
op.Password = "REMOTE_PASSWORD"
Dim sc As New ManagementScope("\\REMOTE_COMPUTER_NAME\root\cimv2", op)
Dim query As New ObjectQuery("Select * from Win32_Process")
Dim searcher As New ManagementObjectSearcher(sc, query)
Dim result As ManagementObjectCollection = searcher.[Get]()
For Each obj As ManagementObject In result
If obj("Caption") IsNot Nothing Then
Console.Write(obj("Caption").ToString() & vbTab)
End If
If obj("CommandLine") IsNot Nothing Then
Console.WriteLine(obj("CommandLine").ToString())
End If
Next
Public Function GetProcessOwner(processId As Integer) As String
Dim query As String = "Select * From Win32_Process Where ProcessID = " & processId
Dim searcher As New ManagementObjectSearcher(query)
Dim processList As ManagementObjectCollection = searcher.[Get]()
For Each obj As ManagementObject In processList
Dim argList As String() = New String() {String.Empty, String.Empty}
Dim returnVal As Integer = Convert.ToInt32(obj.InvokeMethod("GetOwner", argList))
If returnVal = 0 Then
' return DOMAIN\user
Return argList(1) & "\" & argList(0)
End If
Next
Return "NO OWNER"
End Function

Reading Console Output to write out an error log VB

I am running some commands on computers and I would like to have them output a seperate text file if the command cannot run.
For Each strUserName As String In strLines
Dim ReplaceCommand As String = sCommand.Replace("*", strUserName).Replace("$$$", saveFileDialog3.FileName & ".txt").Replace("###", exeSearch)
Shell("cmd.exe /c" & ReplaceCommand, AppWinStyle.Hide, True, )
' If Command Cannot Execute, List Why and Move onto Next Command
Using swrr As New StreamWriter(File.Open(ErrorLog, FileMode.OpenOrCreate))
If Console.Readline = "blahblah" Then swrr.WriteLine("FAIL") Else swrr.WriteLine("PASS")
End Using
Next
Am I on the right track? I am getting an output to a text file but its just one line ans always says PASS.
Several things: you're creating a new StreamWriter every time you want to write a line to it, instead of creating one then just writing to it when you need to. You're still using shell which is really basic, and not really suited for what you need. You should really be using a process for this.
I've written a function for you to use to execute the process instead of using the shell, which will return the output from the command execution to the ConsoleOutput variable, which you can then check for output strings.
Lastly, you should be using String.Format instead of replace to create the correct string for the command to run. For example:
Dim FirstName As String = "Jay"
Dim Age As String = "twenty"
Dim Greeting As String = String.Format("Hello {0}, I know you're {1} years old", FirstName, Age)
' Greetings value would be "Hello Jay, I know you're twenty years old"
So tweak the below to suit, specifically the Args variable, USING THE STRING.FORMAT function :)
Sub DoWork()
Dim ConsoleOutput As String = String.Empty
Using swrr As New StreamWriter(ErrorLog, True)
For Each strUserName As String In StrLines
ConsoleOutput = GetCMDOuput(strUserName, saveFileDialog3.FileName, exeSearch)
' If Command Cannot Execute, List Why and Move onto Next Command
If ConsoleOutput = "blahblah" Then swrr.WriteLine("FAIL") Else swrr.WriteLine("PASS")
Next
End Using
End Sub
Function GetCMDOuput(ByVal strUserName As String, ByVal strFileName As String, ByVal strExeSearch As String) As String
Dim Args As String = String.Format("/c -paramzero {0} -paramone {1} -paramtwo {2}", strUserName, strFileName, strExeSearch)
Dim CMD As New Process
CMD.StartInfo.FileName = "cmd.exe"
CMD.StartInfo.Arguments = Args
CMD.StartInfo.UseShellExecute = False
CMD.StartInfo.RedirectStandardInput = True
CMD.StartInfo.RedirectStandardOutput = True
CMD.StartInfo.CreateNoWindow = True
CMD.Start()
Dim retval As String = CMD.StandardOutput.ReadToEnd
CMD.WaitForExit()
Return retval
End Function