Chimaera

Simple way to get all users on an offline drive?

8 posts in this topic

As the title really, im trying to find a simple way to give me a list of the users on an offline drive

which im then going to tie to some tasks i have to do

I cant use @AppData for example as the username in the middle of the string would be the machine im woking on, not the username of the offline drive im trying to fix.

The offline drive will be attached to the main machine in a caddy or docking station

Any pointers please?

Share this post


Link to post
Share on other sites



The question is a little confusing as you state the disk is offline, but guess you mean you have a windows system/boot disk mounted additionally to a computer and want to know which users have used it?

Wouldn't scanning drive:\Users be an option?

Jos


Visit the SciTE4AutoIt3 Download page for the latest versions        Beta files                                                          Forum Rules
 
Live for the present,
Dream of the future,
Learn from the past.
  :)

Share this post


Link to post
Share on other sites

#3 ·  Posted (edited)

I do this in so many of my "offline" scripts.  Let me see if I can find a code snippet. 

Here is my full "old computer info" script, You just want the Users part.

#include <ButtonConstants.au3>
#include <ComboConstants.au3>
#include <GUIConstantsEx.au3>
#include <StaticConstants.au3>
#include <WindowsConstants.au3>
#include <Array.au3>
#include <FileConstants.au3>
#include <File.au3>
#RequireAdmin

$vOldPC = InputBox("BoCC Automation", "Enter Old PC Drive Letter", "D:")
If @Error Then Exit
$vOldPC = StringLeft($vOldPC, 1) & ":"

While 1
Run(@ComSpec & " /c reg.exe load HKLM\OldSys " & $vOldPC & "\Windows\System32\Config\system")
Sleep(1000)
If _RegExistKey("HKLM\OldSys") = True Then ExitLoop
WEnd

#cs
If _RegExistKey("HKLM\OldSys") = False Then
    MsgBox(0, "BoCC Automation", "Could Not Load System Hive, Exiting Program")
    Exit
EndIf
#CE

SoundPlay("my-cpu-is-a-neural-net-processor-a-learning-computer.mp3")


;Part 1 Get Computer Name
$sOldPCName = RegRead("HKLM\OldSys\ControlSet001\Control\ComputerName\ComputerName", "ComputerName")
;MsgBox(0, "BoCC Automation", $sOldPCName)

#Region ### START Koda GUI section ### Form=C:\Users\it022565\Desktop\Form1.kxf
$Form1 = GUICreate("BoCC Automation", 430, 151, 192, 124)
$Label1 = GUICtrlCreateLabel("User Name", 16, 88, 57, 17)
$Label2 = GUICtrlCreateLabel("External Drive Information Extraction", 56, 0, 299, 24)
GUICtrlSetFont(-1, 12, 800, 0, "MS Sans Serif")
$Combo1 = GUICtrlCreateCombo("User Name", 16, 112, 145, 25, BitOR($CBS_DROPDOWN,$CBS_AUTOHSCROLL))
$Button1 = GUICtrlCreateButton("GO!", 270, 112, 75, 25)
$Label3 = GUICtrlCreateLabel("Drive Letter", 16, 40, 92, 20)
GUICtrlSetFont(-1, 10, 400, 0, "MS Sans Serif")
$Label4 = GUICtrlCreateLabel("Old Computer Name", 176, 40, 236, 20)
GUICtrlSetFont(-1, 10, 400, 0, "MS Sans Serif")
GUISetState(@SW_SHOW)
#EndRegion ### END Koda GUI section ###
GUICtrlSetData($Label3, "Drive Letter: " & $vOldPC)
GUICtrlSetData($Label4, "Old Computer Name: " & $sOldPCName)


$aOldUsers = _FileListToArray($vOldPC & "\Users", "*", $FLTA_FOLDERS)
GUICtrlSetData($Combo1, "|")
For $i = 1 to $aOldUsers[0]
GUICtrlSetData($Combo1, $aOldUsers[$i])
Next

While 1
    $nMsg = GUIGetMsg()
    Switch $nMsg
        Case $GUI_EVENT_CLOSE
            Exit
        Case $Button1
            ExitLoop
    EndSwitch
WEnd


While 1
Run(@ComSpec & " /c reg.exe load HKLM\OldUser " & $vOldPC & "\Users\" & GUICtrlRead($Combo1) & "\NTUSER.DAT")
Sleep(1000)
If _RegExistKey("HKLM\OldUser") = True Then ExitLoop
WEnd

#CS
If _RegExistKey("HKLM\OldUser") = False Then
    MsgBox(0, "BoCC Automation", "Could Not Load User Hive, Exiting Program")
    Exit
EndIf
#CE


;Local Printers
;HKLM\OldSys\ControlSet001\Control\Print\Printers

;Network Printers
;HKLM\OldUser\Printers\Connections

;Mapped Drives
;HKLM\OldUser\Network

_FileCreate(@DesktopDir & "\Old PC Info.txt")
$hFileOpen = FileOpen(@DesktopDir & "\Old PC Info.txt", $FO_OVERWRITE)

FileWriteLine($hFileOpen, "Old PC Info: Computer Name " & $sOldPCName & @CRLF & @CRLF)
FileWriteLine($hFileOpen, "Username: " & GUICtrlRead($Combo1) & @CRLF & @CRLF)
FileWriteLine($hFileOpen, "Mapped Drives" & @CRLF)


For $i = 1 To 100
    $var = RegEnumKey("HKLM\OldUser\Network", $i)
    If @error <> 0 Then ExitLoop
    ConsoleWrite($var)
    FileWriteLine($hFileOpen, $var)
    $var2 = RegRead("HKLM\OldUser\Network\" & $var, "RemotePath")
    FileWriteLine($hFileOpen, $var2)
Next

FileWriteLine($hFileOpen, @CRLF & "Network Printers" & @CRLF)

For $i = 1 To 100
    $var = RegEnumKey("HKLM\OldUser\Printers\Connections", $i)
    If @error <> 0 Then ExitLoop
    ConsoleWrite($var)
    FileWriteLine($hFileOpen, $var)
Next

FileWriteLine($hFileOpen, @CRLF & "Local Printers" & @CRLF)

For $i = 1 To 100
    $var = RegEnumKey("HKLM\OldSys\ControlSet001\Control\Print\Printers", $i)
    If @error <> 0 Then ExitLoop
    ConsoleWrite($var)
    FileWriteLine($hFileOpen, $var)
Next

FileClose($hFileOpen)






;Unload Hives
While 1
    Sleep(200)
    Run(@ComSpec & " /c reg.exe unload HKLM\OldSys")
    If _RegExistKey("HKLM\OldSys") = False Then ExitLoop
WEnd

While 1
    Sleep(200)
    Run(@ComSpec & " /c reg.exe unload HKLM\OldUser")
    If _RegExistKey("HKLM\OldUser") = False Then ExitLoop
WEnd

MsgBox(0, "BoCC Automation", "Information Gather Complete, See Log File On Desktop")



Func _RegExistKey($sKeyname)
    RegEnumVal ($sKeyname, 1)
    Return (@error <= 0)
EndFunc

Here is a much smaller script I use to get e-mail archives, this one I use StringinStr() to avoid the admin/default accounts.

#Include <SecurityEx.au3>
#Include <Reg.au3>
#Include <Array.au3>
#Include <FileConstants.au3>
#Include <File.au3>
#RequireAdmin

$vDrive = InputBox("Drive Letter Selection", "Enter Driver Letter For Scan (Do Not Include Colon:)", "C")
If @Error Then Exit
$vOutlookVer = InputBox("Enter Outlook Version", "Outlook 2013 = 15" & @CRLF & "Outlook 2010 = 14" & @CRLF & "Outlook 2007 = 12")
If @Error Then Exit

$aUsers = _FileListToArray($vDrive & ":\Users", "*", $FLTA_FOLDERS)
For $i = 1 to $aUsers[0]

    If NOT StringInStr($aUsers[$i], "Administrator") AND NOT StringInStr($aUsers[$i], "Default") AND NOT StringInStr($aUsers[$i], "All Users") AND NOT StringInStr($aUsers[$i], "Public") Then
        _RegLoadHive($vDrive & ":\Users\" & $aUsers[$i] & "\ntuser.dat", "HKU\" & $aUsers[$i])
        For $i2 = 1 to 200
            If $vOutlookVer = 12 Then
                $sSubKey = RegEnumVal("HKU\" & $aUsers[$i] & "\Software\Microsoft\Office\" & $vOutlookVer & ".0\Outlook\Catalog", $i2)
                If @Error Then ExitLoop
                Else
                $sSubKey = RegEnumVal("HKU\" & $aUsers[$i] & "\Software\Microsoft\Office\" & $vOutlookVer & ".0\Outlook\Search\Catalog", $i2)
                If @Error Then ExitLoop
            EndIf

            If StringRegExp($sSubKey, ".*\.pst$") Then
                DirCreate(@DesktopDir & "\Outlook Archives\" & $aUsers[$i])
               _FileWriteLog(@DesktopDir & "\Outlook Archives\Outlook Archives.txt", $aUsers[$i] & " - " & $sSubKey)
               $sSubKeyMod = StringRegExpReplace($sSubKey, "^.", $vDrive)
               FileCopy($sSubKeyMod, @DesktopDir & "\Outlook Archives\" & $aUsers[$i] & "\" & $aUsers[$i] & "-" & $i2 & ".pst")
            EndIf

        Next
        _RegUnloadHive("HKU\" & $aUsers[$i])
    EndIf

    Next

    MsgBox(0, "BoCC Automation", "Copy of Outlook Archives Completed")

 

So basically I just do a FileListToArray() for the Users folder and potentially exclude the admin/default users.  I only worry about 7/8/10 environments currently, I used to need to write a check for Windows XP since it uses a different users location, so keep that in mind if you still have XP in your environment. 

Edited by ViciousXUSMC

Share this post


Link to post
Share on other sites

The question is a little confusing as you state the disk is offline, but guess you mean you have a windows system/boot disk mounted additionally to a computer and want to know which users have used it?

Wouldn't scanning drive:\Users be an option?

Jos

I was talking about a drive with say for eg a windows problem but i can still access the drive from another machine when i put it in a caddy etc, i often work this way with troublesome machines to damage maybe a virus so i can get control of it.

@ViciousXUSMC

Thanks for those ill have a look

where ive probably got to get to is loading the other drive hive and making changes in the registry to further enable me to get control of it.

The bit im working on atm is removing temp files from the offline drive

None of the normal places will work like @UserProfileDir so i need to change out the C:\ for the new one which im doing atm then i need to isolate the user account 

Is there any point me changing the paths of @UserProfileDir or easier to just make variables $sUserProfileDir

Share this post


Link to post
Share on other sites

Can you  try this ? I have no offline OS, so I cannot test it.

#include <Security.au3>
 #include <WinAPI.au3>
 #include <WinAPIReg.au3>
 #include <Array.au3>

Local $sOffLineDrive = "X:", $aProfiles, $sUserProfileDir

_WinAPI_RegLoadKey($HKEY_USERS, "OfflineWindows", $sOffLineDrive & "\windows\system32\config\software")
If Not @error Then
   $aProfiles = _GetUserProfileList("HKEY_USERS\OfflineWindows\Microsoft\Windows NT\CurrentVersion\ProfileList")
    _ArrayDisplay($aProfiles)
   For $i = 1 To $aProfiles[0][0]
      $sUserProfileDir = StringRegExpReplace($aProfiles[$i][1], "^[A-Z]", $sOffLineDrive)
      MsgBox(0, "", "Profile path : " & $sUserProfileDir)
   Next
    _WinAPI_RegUnloadKey($HKEY_USERS, "OfflineWindows")
EndIf



 ; #FUNCTION# ====================================================================================================================
 ; Name ..........: _GetUserProfileList
 ; Description ...: Returns an array containing the users profiles
 ; Syntax ........: _GetUserProfileList()
 ; Parameters ....: None (added $sKey for this topic)
 ; Return values .: A 2D array :
 ;                    $aArray[0][0] - Number of profiles
 ;                    $aArray[1][0] - 1st domain\username of the account associated to the profile
 ;                    $aArray[1][1] - 1st profile path
 ;                    $aArray[1][2] - 1st user SID
 ;                    $aArray[n][0] - nth username
 ;                    ...
 ; Author ........: jguinch
 ; ===============================================================================================================================
 Func _GetUserProfileList($sKey = "HKLM\SOFTWARE\Microsoft\Windows NT\CurrentVersion\ProfileList")
     Local $iCount = 0, $sSubKey, $sProfileImagePath, $aAccountInfos

     Local $aReturn[1][3]

     While 1
         $iCount += 1
         $sSubKey = RegEnumKey($sKey, $iCount)
         If @error Then ExitLoop


         If StringRegExp($sSubKey, "(?i)S-1-5-21-(\d+-){3}\d+") Then
             $sProfileImagePath = StringReplace( _WinAPI_ExpandEnvironmentStrings ( RegRead($sKey & "\" & $sSubKey, "ProfileImagePath") ), "::", ":")
             If FileExists($sProfileImagePath) Then
                 Redim $aReturn[ UBound($aReturn) + 1][3]

                 $aAccountInfos = _Security__LookupAccountSid($sSubKey)
                 If IsArray($aAccountInfos) Then $aReturn[ UBound($aReturn) - 1][0] = $aAccountInfos[1] & "\" & $aAccountInfos[0]
                 $aReturn[ UBound($aReturn) - 1][1] = $sProfileImagePath
                 $aReturn[ UBound($aReturn) - 1][2] = $sSubKey
             EndIf
         EndIf
     WEnd
     $aReturn[0][0] = UBound($aReturn) - 1

     Return $aReturn
 EndFunc ; ===> _GetUserProfileList




Func _WinAPI_RegUnloadKey($hKey, $sSubkey)
    _SetRESTORE_NAMEPrivilege()
    If @error Then Return SetError(@error)
    _SetBACKUP_NAMEPrivilege()
    If @error Then Return SetError(@error)

    Local $aRet = DllCall('advapi32.dll', 'long', 'RegUnLoadKeyW', 'handle', $hKey, 'wstr', $sSubkey)
    If @error Then Return SetError(@error, @extended, 0)
    Return SetError($aRet[0], 0, $aRet[0] = 0)
EndFunc

Func _WinAPI_RegLoadKey($hKey, $sSubkey, $sFile)
    _SetRESTORE_NAMEPrivilege()
    If @error Then Return SetError(@error)
    _SetBACKUP_NAMEPrivilege()
    If @error Then Return SetError(@error)

    Local $aRet = DllCall('advapi32.dll', 'long', 'RegLoadKeyW', 'handle', $hKey, 'wstr', $sSubkey, 'wstr', $sFile)
    If @error Then Return SetError(@error, @extended, 0)
    Return SetError($aRet[0], 0, $aRet[0] = 0)
EndFunc



Func _SetRESTORE_NAMEPrivilege()
   ; thanks SMOKE_N : https://www.autoitscript.com/forum/topic/165774-two-process-with-same-name-but-diferent-folder-how-close-one-specific/?do=findComment&comment=1210720

    Local $h_curproc = _WinAPI_GetCurrentProcess()
    Local $h_token = _Security__OpenProcessToken($h_curproc, _
        BitOR($TOKEN_ADJUST_PRIVILEGES, $TOKEN_QUERY))
    If Not $h_token Then
        Return SetError(2, 0, 0)
    EndIf

    Local $n_sdn = _Security__LookupPrivilegeValue("", $SE_RESTORE_NAME)

    Local $t_tokenpriv = DllStructCreate("dword;dword;long;dword")
    Local $p_tokenpriv = DllStructGetPtr($t_tokenpriv)
    DLLStructSetData($t_tokenpriv, 1, 1)
    DLLStructSetData($t_tokenpriv, 2, $n_sdn)
    DLLStructSetData($t_tokenpriv, 3, 0)
    DLLStructSetData($t_tokenpriv, 4, $SE_PRIVILEGE_ENABLED)
    Local $n_tokensize = DllStructGetSize($t_tokenpriv)

    Local $b_ret = _Security__AdjustTokenPrivileges($h_token, False, _
        $p_tokenpriv, $n_tokensize)

    _WinAPI_CloseHandle($h_token)

    Return SetError(Not $b_ret, 0, $b_ret)
EndFunc

Func _SetBACKUP_NAMEPrivilege()
   ; thanks SMOKE_N : https://www.autoitscript.com/forum/topic/165774-two-process-with-same-name-but-diferent-folder-how-close-one-specific/?do=findComment&comment=1210720
    Local $h_curproc = _WinAPI_GetCurrentProcess()
    Local $h_token = _Security__OpenProcessToken($h_curproc, _
        BitOR($TOKEN_ADJUST_PRIVILEGES, $TOKEN_QUERY))
    If Not $h_token Then
        Return SetError(2, 0, 0)
    EndIf

    Local $n_sdn = _Security__LookupPrivilegeValue("", $SE_BACKUP_NAME)

    Local $t_tokenpriv = DllStructCreate("dword;dword;long;dword")
    Local $p_tokenpriv = DllStructGetPtr($t_tokenpriv)
    DLLStructSetData($t_tokenpriv, 1, 1)
    DLLStructSetData($t_tokenpriv, 2, $n_sdn)
    DLLStructSetData($t_tokenpriv, 3, 0)
    DLLStructSetData($t_tokenpriv, 4, $SE_PRIVILEGE_ENABLED)
    Local $n_tokensize = DllStructGetSize($t_tokenpriv)

    Local $b_ret = _Security__AdjustTokenPrivileges($h_token, False, _
        $p_tokenpriv, $n_tokensize)

    _WinAPI_CloseHandle($h_token)

    Return SetError(Not $b_ret, 0, $b_ret)
EndFunc

 

Share this post


Link to post
Share on other sites

That gives me no array or messagebox but it completes

Does it take into account you have to load a different hive to access an offline drive?, its a complicated script so im unable to tell.

Thx anyway, ill retest it at work to be sure when i get there

Share this post


Link to post
Share on other sites

Sorry it never even occurred to me to check that...

That now returns [0] 0

tried on two drives with accounts on them

 

I remembered seeing some code to do with user accounts a long time ago and i tracked down a piece by BrewmanNH

Ive got as far as this now

#include <File.au3>
#include <Array.au3>
#include <MsgBoxConstants.au3>
#AutoIt3Wrapper_AU3Check_Parameters=-d -w 1 -w 2 -w 3 -w- 4 -w 5 -w 6 -w- 7

;~ Global $OS = 'O:'
Global $aUserList[10], $X, $NewOS, $UserList, $sUserList
Global $OS = _DriveChoice()
ConsoleWrite( 'OS = ' & $OS & @CRLF)
Local $WinVer = StringLeft(FileGetVersion($OS & "\Windows\System32\WinVer.exe"), 3)
ConsoleWrite( 'WinVer = ' & $WinVer & @CRLF)


_UserAccounts()

Func _UserAccounts()
    If $WinVer >= 6.0 Then
        $NewOS = True
    ElseIf $WinVer >= 5.1 And $WinVer < 6.0 Then
        $NewOS = False
    Else
        MsgBox($MB_SYSTEMMODAL, "", "This Script only works on Windows XP and above.")
        Exit
    EndIf
    If Not $NewOS Then
        $UserList = _FileListToArray($OS & "\Documents and Settings", "*.*", 2)
        For $I = 1 To $UserList[0]
            Select
                Case $UserList[$I] = "All Users"
                Case $UserList[$I] = "Default User"
                Case $UserList[$I] = "NetworkService"
                Case $UserList[$I] = "LocalService"
                Case $UserList[$I] = "Administrator"
                Case Else
                    $aUserList[$X] = $UserList[$I]
                    $X += 1
                    If $X >= UBound($aUserList) Then
                        ReDim $aUserList[UBound($aUserList) + 10]
                    EndIf
            EndSelect
        Next
    Else
        $UserList = _FileListToArray($OS & "\Users", "*.*", 2)
        For $I = 1 To $UserList[0]
            Select
                Case $UserList[$I] = "All Users"
                Case $UserList[$I] = "Default"
                Case $UserList[$I] = "Default User"
                Case $UserList[$I] = "Public"
                Case Else
                    $aUserList[$X] = $UserList[$I]
                    $X += 1
                    If $X >= UBound($aUserList) Then
                        ReDim $aUserList[UBound($aUserList) + 10]
                    EndIf
            EndSelect
        Next
    EndIf
    ReDim $aUserList[$X]

    _ArrayDisplay($aUserList, 'User Accounts')
    $sUserList = _ArrayToString($aUserList, "|")
    ConsoleWrite($sUserList & @CRLF)

EndFunc   ;==>_UserAccounts

Func _DriveChoice()
    Local Const $sMessage = "Select a drive" ; Create a constant variable in Local scope of the message to display in FileSelectFolder.
    Local $sFileSelectFolder = FileSelectFolder($sMessage, "::{20D04FE0-3AEA-1069-A2D8-08002B30309D}") ; Display an open dialog to select a file.
    If @error Then ; If no drive was selected then display the error message.
        MsgBox($MB_SYSTEMMODAL, "", "No drive was selected.")
    Else
        Local $sFolderTrim = StringLeft($sFileSelectFolder, 2) ; trim the unwanted chars of the result
        Return $sFolderTrim
    EndIf
EndFunc   ;==>_DriveChoice

Its early days next stuff ill have to work out the right paths and open the different hive etc

Figure if i get all the details out the way now the rest of the script should be better laid out

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!


Register a new account

Sign in

Already have an account? Sign in here.


Sign In Now