where are the windows users names stored in xp...? - vb.net

I am writing an application that searches for a particular file in the C:\Documents and Settings\user accounts\Application Data folder. Now i am trying to make this application generic. I can make this application search in a particular users application data folder. But what i am tryin to do is take the user name from a certain file or place where windows xp stores it. Then make it search for that user. Is there a particular way to do it.
Need ideas and suggestions.

User Names are Stored in Windows Registry or Use Can get FolderNames as C:\Documents and Settings contains Every Folder with a UserName

The problem here is that Microsoft has not provided an API method of doing this directly. Perhaps it was an oversight. That being said, any solution you find is going to be some kind of workaround and is going to present some kind of limitations.
Using the registry to get this information is not officially supported by Microsoft and thus, may not work going forward.
Iterating through user profile folders is unreliable because the folder is not always named after its user and because you can change its location.
And so on.
All of that being said, I use a combination of WMI and the registry to accomplish this. Here's what it looks like in VBScript, you should be able to adapt it to your needs.
' Create some arrays to hold the data.
arrUsers = Array()
arrSIDs = Array()
arrAppDataFolders = Array()
' Get a list of all the non-system users with their SID
strComputer = "."
Set objWMIService = GetObject("winmgmts:\\" & strComputer & "\root\cimv2"
Set colUsers = objWMIService.ExecQuery _
("Select * from Win32_UserAccount Where Status = 'OK'")
i = 0
For Each objUser in colUsers
ReDim Preserve arrUsers(i)
ReDim Preserve arrSIDs(i)
arrUsers(i) = objUser.Name
arrSIDs(i) = objUser.SID
i = i + 1
Next
Set colUsers = Nothing
Set objWMIService = Nothing
' Now go to the registry and get the Document folder location using the SID
Const HKEY_USERS = &H80000003
Set objRegistry = GetObject("winmgmts:{impersonationLevel=impersonate}!\\" _
& strComputer & "\root\default:StdRegProv")
ReDim arrAppDataFolders(UBound(arrSIDs))
For i = 0 to UBound(arrSIDs)
strKeyPath = arrSIDs(i) & "\Software\Microsoft\Windows\CurrentVersion\Explorer\Shell Folders"
strValueName = "AppData" ' or "Local AppData"
intReturn = objRegistry.GetExpandedStringValue HKEY_USERS, strKeyPath, strValueName, strValue
If (intReturn = 0) And (Err.Number = 0) Then
arrAppDataFolders(i) = strValue
Else
arrAppDataFolders(i) = vbNull
End If
Next
Set objRegistry = Nothing

net user
from a command prompt will return a list of all users... probably more than what you're asking for. Your best bet is to do what you had already planned on doing with your Documents and Settings.

Related

Get active directory groups for a specific user, nested using LDAP

I'm new to this way of making queries against ldap.I'm stuck on using the LDAP_MATCHING_RULE_IN_CHAIN ("member:1.2.840.113556.1.4.1941:=....
I have searched for information, I'm getting confused on how to use it.
I have a VB snippet where I'm trying to fetch all the groups a user is member of, direct or indirect. I get an empty result back.
I have some things I'm uncertain about,
I have set the base to the root of AD, is that correct?
Do I need to specify ObjectCategory and objectClass at all to get an result or are they "just" used to narrow the result set once something is returned?
In the LDAP_MATCHING_RULE_IN_CHAIN ("memberOf:1.2.840.113556.1.4.1941:= I have various different suggestions to add a reference to a group, but the point here is to get a list of groups back, do I need to specify any ref. to a group to make this filter work?
I'm searching for a user "AD User" that's the CN in AD, I've tried other users with same result (nothing)
Does anyone see what I'm doing wrong here?
Private Sub Button2_Click(sender As Object, e As EventArgs) Handles Button2.Click
Dim adoCommand, adoConnection, strBase, strFilter, strAttributes
Dim objRootDSE, strDNSDomain, strQuery, adoRecordset, strName, strCN
' Setup ADO objects.
adoCommand = CreateObject("ADODB.Command")
adoConnection = CreateObject("ADODB.Connection")
adoConnection.Provider = "ADsDSOObject"
adoConnection.Open("Active Directory Provider")
adoCommand.ActiveConnection = adoConnection
' Search entire Active Directory domain.
objRootDSE = GetObject("LDAP://RootDSE")
strDNSDomain = objRootDSE.Get("defaultNamingContext")
strBase = "<LDAP://" & strDNSDomain & ">"
' Filter on user objects.
'strFilter = "(&(objectCategory=Person)(objectClass=user)"
strFilter = "(&(objectCategory=Group)"
strFilter = strFilter & "(member:1.2.840.113556.1.4.1941:=(CN=AD User,DC=hnitservice,DC=local)))"
' Comma delimited list of attribute values to retrieve.
strAttributes = "sAMAccountName,cn"
' Construct the LDAP syntax query.
strQuery = strBase & ";" & strFilter & ";" & strAttributes & ";subtree"
adoCommand.CommandText = strQuery
adoCommand.Properties("Page Size") = 100
adoCommand.Properties("Timeout") = 30
adoCommand.Properties("Cache Results") = False
' Run the query.
adoRecordset = adoCommand.Execute
' Enumerate the resulting recordset.
Do Until adoRecordset.EOF
' Retrieve values and display.
strName = adoRecordset.Fields("sAMAccountName").Value
strCN = adoRecordset.Fields("cn").value
' Wscript.Echo "NT Name: " & strName & ", Common Name: " & strCN
' Move to the next record in the recordset.
adoRecordset.MoveNext
Loop
' Clean up.
adoRecordset.Close
adoConnection.Close
End Sub
All Groups a User is a member of including Nested Groups#
This Extensible Match Rule is often referred to as LDAP_MATCHING_RULE_IN_CHAIN
As an example, to find all the groups that "CN=UserName,CN=Users,DC=YOURDOMAIN,DC=NET" is a member of, set the base to the groups container DN; for example (OU=groupsOU,DC=MyDomain,DC=NET) and the scope to subtree, and use the following filter.
(member:1.2.840.113556.1.4.1941:=(CN=UserName,CN=Users,DC=YOURDOMAIN,DC=NET))
Will return all of the Groups the user is a member including nested groups.
I am sorry, I can not help with vb.net but you may need to be certain you are following referrals and that your baseDN is appropriate.
This is not helpful:
' Filter on user objects.
'strFilter = "(&(objectCategory=Person)(objectClass=user)"
As you want to return groups.
I always recommend you perform your Queries with a "known" good utility and make sure the Query works. (I like Apache Studio)

Access vba Check if file exists

I have a database split in FrontEnd and BackEnd.
I have it running:
i) in my office
ii) updating/testing in my personal computer.
My BackEnd file is running in different Folder location according to computer running.
I want to place a code and check if file exist.
Code:
Sub FileExists()
Dim strPath As String '<== Office.
Dim strApplicationFolder As String
Dim strPathAdmin As String '<== Admin.
strPath = "\\iMac\Temp\"
strApplicationFolder = Application.CurrentProject.Path
strPathAdmin = strApplicationFolder & "\Temp\"
If Dir(strApplicationFolder & "SerialKey.txt") = "" Then
'===> Admin User.
If Dir(strPathAdmin & "*.*") = "" Then
'===> Empty Folder.
Else
'===> Files on folder.
End If
Else
'===> Office User.
If Dir(strPath & "*.*") = "" Then
'===> Empty Folder.
Else
'===> Files on folder.
End If
End If
End Sub()
I have this until now.
Any help.
Thank you...
Create a small function to check if a file exists and call it when needed.
Public Function FileExists(ByVal path_ As String) As Boolean
FileExists = (Len(Dir(path_)) > 0)
End Function
Since the backend database paths dont change, why dont you declare two constants and simply check their value?
Sub Exist()
Const workFolder As String = "C:\Work Folder\backend.accdb"
Const personalFolder As String = "D:\Personal Folder\backend.accdb"
If FileExists(workFolder) Then
'Work folder exists
End If
'....
If FileExists(personalFolder) Then
'Personal folder exists
End If
End Sub
This is a very belated reply, but don't reinvent the wheel. VBA can access the FileSystemObject, which includes a powerful set of methods that fetch file and folder information without requiring you to write your own functions, and the resulting code is much easier to read.
Second, borrowing on the previous answer, you know the folders you want the code to look at, and they don't change much, but because they could, I would also move your parameters into the declaration so they can be customized if needed or default to existing values.
Finally, FileExists is a verb, which should scream Function rather than Sub, so I'm guessing you want to return something and use it elsewhere in higher level code. It so happens that FileExists is already the name of a method in FileSystemObject, so I'm going to rename your function to LocatePath. You could return the valid path of the file you're looking for and decide by convention to quietly return an empty string "" if the target isn't found, and handle that in the calling procedure.
fs.BuildPath(strRootPath, strFileOrSubDir) appends strFileOrSubDir to strRootPath to construct a properly
formatted, full pathname and you don't need to worry about
whether you have backslashes (or too many) between the two.
It can be used to append files, or subdirectories, or
files in subdirectories.
fs.FileExists(strFullPath) is simple, returns True if strFullPath exists,
and False otherwise.
fs.GetFolder(strFolderName) returns a Folder object that has a
.Files property, which is a Collection object. Collection
objects in turn have a .Count property, which in this example
indicates how many files are in strFolderName. The Collection
object could also be used to iterate over all the files in the
folder individually.
What follows is your code refactored to incorporate all the changes I recommend according to what I think you're trying to achieve. It's not as symmetric as I'd like, but mirrors your code, and it's simple, easy to read, and finished in the sense that it does something.
Function LocatePath(Optional strWorkPath as String = "\\iMac",
Optional strHomePath as String = CurrentProject.Path,
Optional strFile as String = "SerialKey.txt"
Optional strSubDir as String = "Temp") as String
Dim fs as Object
Set fs = CreateObject("Scripting.FileSystemObject")
If fs.FileExists(fs.BuildPath(strHomePath, strFile)) Then
If fs.GetFolder(fs.BuildPath(strHomePath, strSubDir).Files.Count > 0 Then '===> Admin User.
LocatePath = fs.BuildPath(strHomePath, strFile)
ElseIf fs.GetFolder(fs.BuildPath(strWorkPath, strSubDir).Files.Count > 0 Then '===> Office User
LocatePath = fs.BuildPath(strWorkPath, strFile)
End If
Else 'Target conditions not found
LocatePath = ""
End If
Set fs = Nothing
End Function()
Ideally, I probably wouldn't specify strHomePath as String = CurrentProject.Path because strWorkPath as String = CurrentProject.Path is probably also true when you're at work, and you would want to do a better job of differentiating between the two environments. This is also what causes the little problem with symmetry that I mentioned.

Add new network location, not map network drive

Let's say I have 100 users and I need to add several network locations for each user. They cannot be network drives (e.g. Q:) as some users already have more than 26 drives mapped.
I was hoping to do this using either a batch file or a VB script. I've managed to get it working using a VB script by adding network shortcuts but this isn't the solution the users need.
I've been searching and can't find anything related specifically to Network Locations.
I'm open to trying other methods.
EDITED to properly answer the question; the original answer, that creates a shortcut in Network Locations, is kept at the end.
After some testing, a network location is a read-only folder located in the %AppData%\Microsoft\Windows\Network Shortcuts folder, with two files inside: desktop.ini with a precise content (see in code) and a target.lnk shortcut to the target.
Option Explicit
Function CreateNetworkLocation( networkLocationName, networkLocationTarget )
Const ssfNETHOOD = &H13&
Const fsATTRIBUTES_READONLY = 1
Const fsATTRIBUTES_HIDDEN = 2
Const fsATTRIBUTES_SYSTEM = 4
CreateNetworkLocation = False
' Instantiate needed components
Dim fso, shell, shellApplication
Set fso = WScript.CreateObject("Scripting.FileSystemObject")
Set shell = WScript.CreateObject("WScript.Shell")
Set shellApplication = WScript.CreateObject("Shell.Application")
' Locate where NetworkLocations are stored
Dim nethoodFolderPath, networkLocationFolder, networkLocationFolderPath
nethoodFolderPath = shellApplication.Namespace( ssfNETHOOD ).Self.Path
' Create the folder for our NetworkLocation and set its attributes
networkLocationFolderPath = fso.BuildPath( nethoodFolderPath, networkLocationName )
If fso.FolderExists( networkLocationFolderPath ) Then
Exit Function
End If
Set networkLocationFolder = fso.CreateFolder( networkLocationFolderPath )
networkLocationFolder.Attributes = fsATTRIBUTES_READONLY
' Write the desktop.ini inside our NetworkLocation folder and change its attributes
Dim desktopINIFilePath
desktopINIFilePath = fso.BuildPath( networkLocationFolderPath, "desktop.ini" )
With fso.CreateTextFile(desktopINIFilePath)
.Write "[.ShellClassInfo]" & vbCrlf & _
"CLSID2={0AFACED1-E828-11D1-9187-B532F1E9575D}" & vbCrlf & _
"Flags=2" & vbCrlf
.Close
End With
With fso.GetFile( desktopINIFilePath )
.Attributes = fsATTRIBUTES_HIDDEN + fsATTRIBUTES_SYSTEM
End With
' Create the shortcut to the target of our NetworkLocation
Dim targetLink
targetLink = fso.BuildPath( networkLocationFolderPath, "target.lnk" )
With shell.CreateShortcut( targetLink )
.TargetPath = networkLocationTarget
.Save
End With
' Done
CreateNetworkLocation = True
End Function
CreateNetworkLocation "Tests", "\\192.168.1.2\c$"
Tested in Windows 7.
Original answer - Just in case someone finds it useful.
All you need to do is to create a shortcut in the folder:
%AppData%\Microsoft\Windows\Network Shortcuts
Just a VBScript sample (as indicated in the question, not sure if the tags points to another needs):
Option Explicit
Const ssfNETHOOD = &H13&
Dim fso, shell, shellApplication
Set fso = WScript.CreateObject("Scripting.FileSystemObject")
Set shell = WScript.CreateObject("WSCript.Shell")
Set shellApplication = WScript.CreateObject("Shell.Application")
Dim networkLocationsFolder
networkLocationsFolder = shellApplication.Namespace( ssfNETHOOD ).Self.Path
With shell.CreateShortcut(fso.BuildPath( networkLocationsFolder, "Test PC.lnk" ))
.TargetPath = "\\192.168.1.10\c$"
.WindowStyle = 1
.IconLocation = "shell32.dll, 9"
.Description = "Access to Test computer drive"
.WorkingDirectory = "\\192.168.1.10\c$"
.Save
End With

VB.Net: How To Display Previous Shadow Copy Versions of File Allowing User to Choose One

I'm writing an Excel file recovery program with VB.Net that tries to be a convenient place to gather and access Microsoft's recommended methods. If your interested in my probably kludgy, error filled, and lacking enough cleanup code it's here: http://pastebin.com/v4GgDteY. The basic functionality seems to work although I haven't tested graph macro table recovery yet.
It occurred to me that Vista and Windows 7 users could benefit from being offered a list of previous versions of the file within my application if the Shadow Copy Service is on and there are previous copies. How do I do this?
I looked at a lot of web pages but found no easy to crib code. One possibility I guess would be to use vssadmin via the shell but that is pretty cumbersome. I just want to display a dialogue box like the Previous Versions property sheet and allow users to pick one of the previous versions. I guess I could just display the previous version property sheet via the shell by programmatically invoking the context menu and the "Restore previous versions choice", however I also want to be able to offer the list for Vista Home Basic and Premium Users who don't have access to that tab even though apparently the previous versions still exist. Additionally if it possible I would like to offer XP users the same functionality although I'm pretty sure with XP only the System files are in the shadow copies.
I looked at MSDN on the Shadow Copy Service and went through all the pages, I also looked at AlphaVSS and AlphaFS and all the comments. I'm kind of guessing that I need to use AlphaVss and AlphFS and do the following?
Find out the list of snapshots/restore points that exist on the computer.
Mount those snapshots.
Navigate in the mounted volumes to the Excel file the user wants to recover and make a list of those paths.
With the list of paths handy, compare with some kind of diff program, the shadow copies of the files with the original.
Pull out the youngest or oldest version (I don't think it matters) of those shadow copies that differ from the recovery target.
List those versions of the files that are found to be different.
This seems cumbersome and slow, but maybe is the fastest way to do things. I just need some confirmation that is the way to go now.
I finally decided to go ahead and start coding. Please make suggestions for speeding up the code or what do with files that are found to be different from the recovery file target. Is there a simpler way to do this with AlphaVSS and AlphaFS?
Private Sub Button1_Click_2(sender As System.Object, e As System.EventArgs) Handles Button1.Click
'Find out the number of vss shadow snapshots (restore
'points). All shadows apparently have a linkable path
'\\?\GLOBALROOT\Device\HarddiskVolumeShadowCopy#,
'where # is a simple one, two or three digit integer.
Dim objProcess As New Process()
objProcess.StartInfo.UseShellExecute = False
objProcess.StartInfo.RedirectStandardOutput = True
objProcess.StartInfo.CreateNoWindow = True
objProcess.StartInfo.RedirectStandardError = True
objProcess.StartInfo.FileName() = "vssadmin"
objProcess.StartInfo.Arguments() = "List Shadows"
objProcess.Start()
Dim burp As String = objProcess.StandardOutput.ReadToEnd
Dim strError As String = objProcess.StandardError.ReadToEnd()
objProcess.WaitForExit()
Dim xnum As Integer = 0
Dim counterVariable As Integer = 1
' Call Regex.Matches method.
Dim matches As MatchCollection = Regex.Matches(burp, _
"HarddiskVolumeShadowCopy")
' Loop over matches.
For Each m As Match In matches
xnum = xnum + 1
'At the max xnum + 1 is the number of shadows that exist
Next
objProcess.Close()
Do
'Here we make symbolic links to all the shadows, one at a time
'and loop through until all shadows are exposed as folders in C:\.
Dim myProcess As New Process()
myProcess.StartInfo.FileName = "cmd.exe"
myProcess.StartInfo.UseShellExecute = False
myProcess.StartInfo.RedirectStandardInput = True
myProcess.StartInfo.RedirectStandardOutput = True
myProcess.StartInfo.CreateNoWindow = True
myProcess.Start()
Dim myStreamWriter As StreamWriter = myProcess.StandardInput
myStreamWriter.WriteLine("mklink /d C:\shadow" & counterVariable _
& " \\?\GLOBALROOT\Device\HarddiskVolumeShadowCopy" _
& counterVariable & "\")
myStreamWriter.Close()
myProcess.WaitForExit()
myProcess.Close()
' Here I compare our recovery target file against the shadow copies
Dim sFile As String = PathTb.Text
Dim sFileShadowPath As String = "C:\shadow" & _
counterVariable & DelFromLeft("C:", sFile)
Dim jingle As New Process()
jingle.StartInfo.FileName = "cmd.exe"
jingle.StartInfo.UseShellExecute = False
jingle.StartInfo.RedirectStandardInput = True
jingle.StartInfo.RedirectStandardOutput = True
jingle.StartInfo.CreateNoWindow = True
jingle.Start()
Dim jingleWriter As StreamWriter = jingle.StandardInput
jingleWriter.WriteLine("fc """ & sFile & """ """ _
& sFileShadowPath & """")
jingleWriter.Close()
jingle.WaitForExit()
Dim jingleReader As StreamReader = jingle.StandardOutput
Dim JingleCompOut As String = jingleReader.ReadToEnd
jingleReader.Close()
jingle.WaitForExit()
jingle.Close()
Dim jingleBoolean As Boolean = JingleCompOut.Contains( _
"no differences encountered").ToString
If jingleBoolean = "True" Then
MsgBox(jingleBoolean)
Else
'I haven't decided what to do with the paths of
'files that are different from the recovery target.
MsgBox("No")
End If
counterVariable = counterVariable + 1
Loop Until counterVariable = xnum + 1
End Sub

Use a variable in file path in .vbs

Is it possible to usa variable in a path in .vbs. My basic situation is I have a vbs script that will often be run on a computer with one person logged in and run by an admin with a completely different user name (assume the file will be right clicked and "Run As").
The script edits an ini file that is located in the user directory for the person logged in. I know in batch I could simply insert the variable "C:\Users\%Logger%\AppData\Local\stat.ini" and the variable would be replaced. But I can't do this in .vbs. My script thus far. Or look at the bulk of it in an answer here.
Dim blnRes: blnRes = 0
Dim strOld, strNew, logger
strOld = "frogg"
strNew = "frog"
logger = Inputbox("What is your Domain ID exactly as entered when you log into this machine?","Domain ID")
On Error Resume Next
Call update("C:\Users\logger\AppData\Local\stat.ini", strOld, strNew)
blnRes = blnRes Or (Err.Number = 0): Err.Clear
Is there some way I can flag logger as a variable, or is there an easier way to do this?
I guess you meant a script variable. Try this:
logger = Inputbox("What is ID?","Domain ID")
Call update("C:\Users\"& logger &"\AppData\Local\stat.ini", strOld, strNew)
You can use command line arguments with vbs. See the following technet site:
http://technet.microsoft.com/en-us/library/ee156618.aspx
using the example vbs at the bottom, you can have Ping.vbs reply based on the computer name entered after the script name when its called (C:\scripts\Ping.vbs Hostname)
Here's more info on WScript.Aurguments
https://www.google.com/search?q=WScript.Arguments&sourceid=ie7&rls=com.microsoft:en-us:IE-Address&ie=&oe=
'Ping.vbs:
Dim arArguments, strArgument
Set arArguments = WScript.Arguments
WScript.Echo WScript.Arguments.Count
For Each strArgument in arArguments
If Ping(strArgument) Then
WScript.Echo strArgument & " is available."
Else
WScript.Echo strArgument & " is not available."
End If
Next
Function Ping( myHostName )
Dim colPingResults, objPingResult, strQuery
strQuery = "SELECT * FROM Win32_PingStatus WHERE Address = '" & myHostName & "'"
Set colPingResults = GetObject("winmgmts://./root/cimv2").ExecQuery( strQuery )
For Each objPingResult In colPingResults
If Not IsObject( objPingResult ) Then
Ping = False
ElseIf objPingResult.StatusCode = 0 Then
Ping = True
Else
Ping = False
End If
Next
Set colPingResults = Nothing
End Function
If I understand what you're after correctly, you're either going to need to do a string concatenation where you build a string like "string part 1" & logger & "string part 2" or use the replace function to replace %Logger% (e.g. Replace(templateString, "%Logger%", logger)) with your logger variable. There's not a direct equivalent to the %1 sort of format used in batch files.
This worked for me:
Dim fs, ws, Path
Set ws = CreateObject( "WScript.Shell" )
Path = ws.ExpandEnvironmentStrings( "%UserProfile%\testfile.txt" )
ws = Nothing
Set fs = CreateObject("Scripting.FileSystemObject")
Set f = fs.CreateTextFile (Path, True)
f.WriteLine("This is a test")
f.Close()
f = Nothing
Don't assume "C:\Users" will be valid on every system. There are times when you may want to use a different location for user profiles. I also looked at the %AppData% environment variable, but in my case that pointed to AppData\Roaming, and you want AppData\Local.