Want to win a PS4? Go Premium and enter to win our High-Tech Treats giveaway. Enter to Win

x
?
Solved

Enumerating User Accounts on a Remote Computer using VB.Net/WMI

Posted on 2009-06-29
3
Medium Priority
?
1,375 Views
Last Modified: 2013-11-25
Hello,

I had asked this question earlier.  Please see  http://www.experts-exchange.com/Programming/Languages/.NET/Visual_Basic.NET/Q_24434446.html

The suggestion given in the above PAQ still doesn't work.  Basically what happens I think is that my Select query tries to bring back the User accounts from the entire domain.  What I need is for it to bring back the User accounts ONLY for the remote computer name that I pass in.  I have tried several different WHERE clauses, but nothing seems to work.  I am attaching my code below.  It is VB.Net console application.
Option Strict Off
Imports System.Runtime.InteropServices
Imports System.IO
Imports log4net
Imports System.Configuration
Imports System
Imports System.Management
Imports System.Net.Dns
 
 
'Imports log4net
'Private Shared ReadOnly log As ILog = LogManager.GetLogger(Type.GetType(TestPage1).Name)
 
'Private Shared ReadOnly ILog log Property LogManager.GetLogger(() As =
'End Property
'  System.Reflection.MethodBase.GetCurrentMethod().DeclaringType)
 
'----------------------------------------------------------------
' Converted from C# to VB .NET using CSharpToVBConverter(1.2).
' Developed by: Kamal Patel (http://www.KamalPatel.net) 
'----------------------------------------------------------------
Module Module1
   
    Public MasterDirectory As String = ConfigurationSettings.AppSettings("MasterDirectory")
    Public SubDirectory1 As String = ConfigurationSettings.AppSettings("SubDirectory1")
    Public SubDirectory2 As String = ConfigurationSettings.AppSettings("SubDirectory2")
 
    Public objOS As ManagementObjectSearcher
    Public objCS As ManagementObjectSearcher
    Public objMgmt As ManagementObject
 
 
    'Logger instance {DEBUG,INFO,WARN,ERROR,FATAL,OFF}
    Private ReadOnly log As log4net.ILog = log4net.LogManager.GetLogger("TaskRunnerAccountDiscovery")
 
    Sub Main()
        Dim strDomainName, TaskRunnerServer As String
        Dim strTextFileBldr As New System.Text.StringBuilder
        Dim strCSVBldr As New System.Text.StringBuilder
        Dim arlAccountList As New ArrayList
        Dim bolFoundTaskRunner As Boolean = False
        Dim bolNoInputServers As Boolean = True
 
        Try
            log.Info("Beginning Run")
            log.Info("MasterDirectory: " & MasterDirectory)
 
            Dim arlRuntimeServers As New ArrayList
            Dim arlTextFileServers As New ArrayList
            Dim arlFinalArray As New ArrayList
            Dim arlTotalServersSearched As New ArrayList
            Dim intTaskRunnerServersFound As Integer = 0
 
            Dim strEntry As String
            Dim intNumberOfServers As Integer
            Dim intCounter As Integer = 0
            Dim ss As Integer
 
            
            arlFinalArray.Add("Archtest201")
            arlFinalArray.Add("Archtest301")
 
            If arlFinalArray.Count <= 0 Or arlFinalArray Is Nothing Then
                log.Error("Error: Server arraylist is Empty! -Exiting Program!")
            Else
                intNumberOfServers = arlFinalArray.Count.ToString
                bolNoInputServers = False
                For Each strEntry In arlFinalArray
                    strDomainName = arlFinalArray.Item(intCounter)
                    intCounter = intCounter + 1
                    If intCounter < 26 Then
                        Dim bolIsAccessDenied As Boolean = False
                        arlAccountList = EnumerateLocalAccounts(strDomainName, bolIsAccessDenied)
                        'strAccountInfo = FindAccountsOnServer(strDomainName)
                        'If strAccountInfo <> "Not Available" Then
                        If bolIsAccessDenied Then
                            strTextFileBldr.Append((Trim(strDomainName)).ToString() & "Access is Denied - Unauthorized Access Exception" & vbCrLf)
                        Else
                            If arlAccountList.Count >= 1 Then
                                strTextFileBldr.Append((Trim(strDomainName)).ToString() & vbCrLf)
                                For Each ss In arlAccountList
                                    strTextFileBldr.Append(ss).ToString()
                                    strTextFileBldr.Append(",")
                                Next
                                strTextFileBldr.Append(" " & vbCrLf & vbCrLf)
                                arlTotalServersSearched.Add(strDomainName)
                                bolFoundTaskRunner = FindIfTaskRunnerIsUsed(arlAccountList, strDomainName)
                                If bolFoundTaskRunner Then
                                    intTaskRunnerServersFound += 1
                                    strCSVBldr.Append((Trim(strDomainName)).ToString & vbCrLf)
                                End If
                            End If
                        End If
                    End If
                Next
            End If
            If bolNoInputServers Then
                Exit Sub
            Else
                WriteUserAccountsInfoToOutputFile(strTextFileBldr, arlTotalServersSearched)
                WriteServerNameToOutputFile(strCSVBldr, intTaskRunnerServersFound)
            End If
        Catch ex As Exception
            Console.WriteLine("Error Occurred: " & ex.ToString)
            log.Error("Error: " & ex.Message)
        End Try
 
        'added so the DOS screen won't flash by.... remove this when running program outside of the debugger.
        Console.ReadLine()
 
    End Sub
 
   
    Public Function EnumerateLocalAccounts(ByVal machineName As String, ByRef bolIsAccessDenied As Boolean) As ArrayList
        ''''''bolIsAccessDenied is ByRef
 
        Dim arlArrayOfAccounts As New ArrayList
        Dim strAccount As String
        Dim strDomain As String
 
        'Dim strNumbers As String = "0,1,2,3,4,5,6,7,8,9"
        'Dim strSplitNumbers() As String = Split(strNumbers, ",")
        'Dim i As Integer = 0
 
        ''If this is an IP Address....bypass
        'For i = 0 To strSplitNumbers.GetUpperBound(0)
        '    If machineName.StartsWith(strSplitNumbers(i)) Then
        '        Return arlArrayOfAccounts
        '    End If
        'Next
 
 
              Try
 
            Dim pathMachine As New Management.ManagementPath("\\" & machineName & "\root\cimv2")
 
            Dim scopeRemoteMachine As New Management.ManagementScope(pathMachine)
 
            Dim queryAccounts As New Management.ObjectQuery("SELECT * FROM Win32_Account")
            'Dim queryAccounts As New Management.ObjectQuery("SELECT * FROM Win32_Account where LocalAccount=TRUE")
 
            'Dim queryAccounts As New Management.ObjectQuery("SELECT * FROM Win32_Account where LocalAccount=TRUE And Domain = '" & machineName & "'")
 
            '("Select * from Win32_Account WHERE Domain = '" & domain & "' AND Name = '" & username & "'")
 
            'Dim queryAccounts As New Management.ObjectQuery("SELECT * FROM Win32_Account where MachineName = '" & machineName & "'")
 
 
            Dim searcherAccounts As New Management.ManagementObjectSearcher(scopeRemoteMachine, queryAccounts)
 
            Dim objectAccount As Management.ManagementObject
 
            For Each objectAccount In searcherAccounts.Get
                strAccount = (objectAccount("Name"))
                arlArrayOfAccounts.Add(strAccount)
                'Debug.WriteLine(objectAccount("Name"))
            Next
 
            Return arlArrayOfAccounts
 
        Catch uae As UnauthorizedAccessException
            log.Error("Error occurred on machinename: " & machineName & " - " & uae.Message)
            bolIsAccessDenied = True
 
        Catch ex As Exception
            log.Error("Error occurred: " & ex.Message)
        End Try
 
 
           End Function
 
 
   
   
    Function FindIfTaskRunnerIsUsed(ByVal arlAccountList As ArrayList, ByVal strDomainName As String) As Boolean
        'Dim StringArray() As String
        Dim s As String
        Dim intCounter As Integer = 0
        Dim bolServerHasTaskRunner As Boolean = False
        Try
            '''''' Split the contents of sOutput using System.Environment.Newline as the delimeter.
            'StringArray = Split(sOutput, System.Environment.NewLine)
            Dim intLen As Integer = arlAccountList.Count()
            For Each s In arlAccountList
                intCounter += 1
                If arlAccountList(intCounter).ToUpper.ToString = "TASKRUNNER".ToString Then
                    bolServerHasTaskRunner = True
                    Exit For
                End If
            Next
            Return bolServerHasTaskRunner
        Catch ex As Exception
            log.Error("Error occurred: " & ex.Message)
        End Try
    End Function
 
    Public Function MergeBothArraylists(ByVal arlRuntimeServers, ByVal arlTextFileServers) As ArrayList
        'Private Function MergeArrayLists(ByVal L1 As ArrayList, ByVal L2 As ArrayList) As Hashtable
        'Dim ht As New Hashtable
        'Dim s As String
 
        'For Each s In arlRuntimeServers
        '    If Not ht.ContainsKey(s) Then
        '        ht.Add(s, s)
        '    End If
        'Next
        'For Each s In arlTextFileServers
        '    If Not ht.ContainsKey(s) Then
        '        ht.Add(s, s)
        '    End If
        'Next
        'Return ht
 
        Dim arl As New ArrayList
        Dim s As String
 
        For Each s In arlRuntimeServers
            If Not arl.Contains(s) Then
                arl.Add(s)
            End If
        Next
        For Each s In arlTextFileServers
            If Not arl.Contains(s) Then
                arl.Add(s)
            End If
        Next
        arl.Sort()
        Return arl
    End Function
 
    Public Function ReadTextFile() As ArrayList
 
        Dim TextFileLocation As String = ConfigurationSettings.AppSettings("TextFileLocation")
        Dim arlArray As New ArrayList
        Dim oFile As System.IO.File
        Dim oRead As System.IO.StreamReader
        'oRead = oFile.OpenText("C:\sample.txt")
        oRead = oFile.OpenText(TextFileLocation)
 
 
        While oRead.Peek <> -1
            arlArray.Add(oRead.ReadLine())
        End While
        oRead.Close()
 
        Return arlArray
 
    End Function
 
    Public Function WriteFile( _
    ByVal FileName As String, _
    ByVal SubDirectory As String, _
    ByVal strFileContent As String _
)
        Try
 
            Dim objReader As StreamWriter
            If Not Directory.Exists(MasterDirectory & "\" & SubDirectory) Then
                Directory.CreateDirectory(MasterDirectory & "\" & SubDirectory)
            End If
            Dim fullpath As String = MasterDirectory & "\" & SubDirectory & "\" & FileName
            objReader = New StreamWriter(fullpath)
            objReader.Write(strFileContent)
            objReader.Close()
 
        Catch Ex As Exception
            log.Error("Error: " & Ex.ToString)
        End Try
    End Function
 
    Public Function WriteServerNameToOutputFile(ByVal strStringBldr As System.Text.StringBuilder, ByVal intRows As Integer)
 
        '''''''' This function writes a unique file for each run (e.g. TaskRunnerServersMMDDYYYY HH MM AM/PM.CSV) in a directory called 'CSVFiles' within the
        '''''''' MasterDirectory.  
        ''''''''
 
        Try
            Dim output, filename As String
            output = output & "Total Number of  Servers Searched: " & intRows.ToString & vbCrLf
            output = output & strStringBldr.ToString()
            filename = "TaskRunnerServers" & Now.ToShortDateString & " " & Now.ToShortTimeString & ".txt"
            filename = filename.Replace(":", " ")
            filename = filename.Replace("/", "")
            WriteFile(filename, SubDirectory2, output)
        Catch ex As Exception
            log.Error("Error occurred: " & ex.Message)
        End Try
 
    End Function
 
    Public Function WriteUserAccountsInfoToOutputFile(ByVal strTextFileRowBldr As System.Text.StringBuilder, ByVal arlTotalServersSearched As ArrayList)
        ''''''''
        '''''''' This function writes a unique file for each run (e.g. UserAccountInfoMMDDYYYY HH MM AM/PM.CSV) in a directory called 'CSVFiles' within the
        '''''''' MasterDirectory.  
        ''''''''
        Dim strBldrToString As String = strTextFileRowBldr.ToString()
        Dim intRows As Integer = arlTotalServersSearched.Count()
 
        Try
            Dim output, filename As String
            output = output & "Total Number of  Servers that use TaskRunner Account: " & intRows.ToString & vbCrLf
            'output = output & strTextFileRowBldr.ToString()
            output = output & strBldrToString
            filename = "UserAccountInfo" & Now.ToShortDateString & " " & Now.ToShortTimeString & ".txt"
            filename = filename.Replace(":", " ")
            filename = filename.Replace("/", "")
            WriteFile(filename, SubDirectory1, output)
        Catch ex As Exception
            log.Error("Error occurred: " & ex.Message)
        End Try
    End Function
 
 
 
 
 
 
End Module

Open in new window

0
Comment
Question by:msyed1
[X]
Welcome to Experts Exchange

Add your voice to the tech community where 5M+ people just like you are talking about what matters.

  • Help others & share knowledge
  • Earn cash & points
  • Learn & ask questions
3 Comments
 
LVL 96

Expert Comment

by:Bob Learned
ID: 24746712
If the remote machine is a domain controller, then I don't think that there is a distinction between local and domain user names...
0
 

Author Comment

by:msyed1
ID: 24757313
TheLearnedOne:  The remote machine is NOT a domain controller.  As you can see in my Sub Main, I have (for the sake of testing) hard-coded the machine names I am passing in to two test servers we have:

arlFinalArray.Add("Archtest201")
arlFinalArray.Add("Archtest301")

Is there a way I can change the query to find out if a certain user account (in my case a user account called 'taskrunner' is defined on the machine ??  That is all I am trying to do.  I have a list of machine names in an arraylist.  I need to determine which machines have the 'taskrunner' account defined on them....then what I have to do is to change the password of that user account.....but so far I haven't been able to find out which machines have 'taskrunner' account defined.  Hope you can help me. msyed1.
 
0
 
LVL 13

Accepted Solution

by:
lciprianionut earned 2000 total points
ID: 24757610
Here is the code you are looking for with some modification of course.
The script is search on local computer the local admin by SID, then search id there are any services that run under that account, change the password of the account and rename it.
To fit to your needs just replace
Set colAccountItems = objWMIService.ExecQuery ("Select * From Win32_UserAccount Where Domain='" & strComputer & "'")
with
 Set colAccountItems = objWMIService.ExecQuery ("Select * From Win32_UserAccount Where Domain='" & strComputer & "' and Name='taskrunner'")

Get-User.txt
0

Featured Post

VIDEO: THE CONCERTO CLOUD FOR HEALTHCARE

Modern healthcare requires a modern cloud. View this brief video to understand how the Concerto Cloud for Healthcare can help your organization.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

Communication between departments might not happen in two different languages, but they do exist in two different worlds. With different targets and performance goals the same phrase often means something completely different to each party. Learn ho…
Originally, this post was published on Monitis Blog, you can check it here . In business circles, we sometimes hear that today is the “age of the customer.” And so it is. Thanks to the enormous advances over the past few years in consumer techno…
Learn how to match and substitute tagged data using PHP regular expressions. Demonstrated on Windows 7, but also applies to other operating systems. Demonstrated technique applies to PHP (all versions) and Firefox, but very similar techniques will w…
Starting up a Project
Suggested Courses

610 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question