Jump to content

Finding Unique hardware ID and lock Windows OS


Iznogoud
 Share

Recommended Posts

  • Replies 41
  • Created
  • Last Reply

Top Posters In This Topic

Top Posters In This Topic

Posted Images

1 hour ago, Nine said:

ya you change the if statement, i didnt invest most time understanding your detailed needs, if it is the contrary. change <> with =

This is the code i am working on now, and it seems to work.

#Region ;**** Directives created by AutoIt3Wrapper_GUI ****
#AutoIt3Wrapper_Change2CUI=y
#EndRegion ;**** Directives created by AutoIt3Wrapper_GUI ****
#include <Constants.au3>
#include <WinAPISys.au3>

Opt ("MustDeclareVars", 1)

   Local $data


   While 1

   Local $dvcn = Run(@comspec & ' /c devcon.exe hwids * | findstr "HID\VID_1050&PID_0114&REV_0340&MI_01"', _
          @ScriptDir, @SW_HIDE, $STDIN_CHILD + $STDOUT_CHILD)

      sleep(3000)

         $data &= StdoutRead($dvcn)

         if $data = "" then
            _WinAPI_LockWorkStation()
            Exit
         Else
            $data = ""
         EndIf
      ConsoleWrite("USB Drive connected" & @CRLF )
   WEnd

But i don't know if this is efficient or there is a better way.

The sleep of 3000 is nessecary for running the compsec on a heavy load system. Sometimes it does a random lock from the OS...

One problem i had now was the disconnecting from the Yubikey / USB Device and the ConsoleWrite stopped, but the screen wasn't locked :blink:

I hope this was a one timer.

Link to comment
Share on other sites

you told me you wanted to run it every second, and now you put a 3 secs sleep.  Second the while, should be around the $data &= as you will miss some read.  Bring back my script cause yours ain't gonna work.  If you want to loop you must create another one around the whole script.

Link to comment
Share on other sites

9 hours ago, Nine said:

you told me you wanted to run it every second, and now you put a 3 secs sleep.  Second the while, should be around the $data &= as you will miss some read.  Bring back my script cause yours ain't gonna work.  If you want to loop you must create another one around the whole script.

Yes i would like to run it every sec. but then it randomly locks my screen and i think this is happening because the comspec part with the findstr is not ready yet in 1 sec. That is the reason i made it 3 sec. 

But i will change it back, but then it doesn't work correctly.

Link to comment
Share on other sites

I just tested it extensively with a usb memory key.  And the problem seems that stdoutread is interfering with findstr when it reads too rapidly.  So I changed the sleep (25) to a sleep (250) and never got a glitch since.

As i said previously, create another while starting just before the run and put the Wend after a sleep (3000) at the very end.

And FYI, I tested the solution that I proposed initially with a txt file, and I get about the same load on the CPUs....

Link to comment
Share on other sites

#Region ;**** Directives created by AutoIt3Wrapper_GUI ****
#AutoIt3Wrapper_Change2CUI=y
#EndRegion ;**** Directives created by AutoIt3Wrapper_GUI ****
#include <Constants.au3>
#include <WinAPISys.au3>

Opt ("MustDeclareVars", 1)

While 1
   Local $data =""
   Local $dvcn = Run(@comspec & ' /c devcon.exe hwids * | findstr "HID\VID_1050&PID_0114&REV_0340&MI_01"', _
          @ScriptDir, @SW_HIDE, $STDIN_CHILD + $STDOUT_CHILD)
sleep(1000)
    While True
        $data &= StdoutRead($dvcn)
        If @error Then ExitLoop
        Sleep(250)
    WEnd

   ;Msgbox (0,"",$data)


   if $data = "" then _WinAPI_LockWorkStation()

WEnd

I needed to add sleep(1000) after the Run command because sometimes when you stress out the CPU it will lock the computer even when the drive is still connected.

EDIT

While i am working it still locks the computer even when the drive is connected, so something is not going correct.

Edited by Iznogoud
Link to comment
Share on other sites

20 minutes ago, Iznogoud said:

While i am working it still locks the computer even when the drive is connected, so something is not going correct.

Hmmm....

Again I will suggest to abandon devcon and use WMI instead. There must be a way for you to do this without the external program and it's overhead.

When I look into "SELECT * FROM Win32_PnPEntity" I can for certain see a list of device IDs.

AutoIt Scriptomatic is our friend!

; Generated by AutoIt Scriptomatic

$wbemFlagReturnImmediately = 0x10
$wbemFlagForwardOnly = 0x20
$colItems = ""
$strComputer = "localhost"

$Output=""
$Output = $Output & "Computer: " & $strComputer  & @CRLF
$Output = $Output & "==========================================" & @CRLF
$objWMIService = ObjGet("winmgmts:\\" & $strComputer & "\root\CIMV2")
$colItems = $objWMIService.ExecQuery("SELECT * FROM Win32_PnPEntity", "WQL", _
                                          $wbemFlagReturnImmediately + $wbemFlagForwardOnly)

If IsObj($colItems) then
   For $objItem In $colItems
      $Output = $Output & "Availability: " & $objItem.Availability & @CRLF
      $Output = $Output & "Caption: " & $objItem.Caption & @CRLF
      $Output = $Output & "ClassGuid: " & $objItem.ClassGuid & @CRLF
      $strCompatibleID = $objItem.CompatibleID(0)
      $Output = $Output & "CompatibleID: " & $strCompatibleID & @CRLF
      $Output = $Output & "ConfigManagerErrorCode: " & $objItem.ConfigManagerErrorCode & @CRLF
      $Output = $Output & "ConfigManagerUserConfig: " & $objItem.ConfigManagerUserConfig & @CRLF
      $Output = $Output & "CreationClassName: " & $objItem.CreationClassName & @CRLF
      $Output = $Output & "Description: " & $objItem.Description & @CRLF
      $Output = $Output & "DeviceID: " & $objItem.DeviceID & @CRLF
      $Output = $Output & "ErrorCleared: " & $objItem.ErrorCleared & @CRLF
      $Output = $Output & "ErrorDescription: " & $objItem.ErrorDescription & @CRLF
      $strHardwareID = $objItem.HardwareID(0)
      $Output = $Output & "HardwareID: " & $strHardwareID & @CRLF
      $Output = $Output & "InstallDate: " & WMIDateStringToDate($objItem.InstallDate) & @CRLF
      $Output = $Output & "LastErrorCode: " & $objItem.LastErrorCode & @CRLF
      $Output = $Output & "Manufacturer: " & $objItem.Manufacturer & @CRLF
      $Output = $Output & "Name: " & $objItem.Name & @CRLF
      $Output = $Output & "PNPClass: " & $objItem.PNPClass & @CRLF
      $Output = $Output & "PNPDeviceID: " & $objItem.PNPDeviceID & @CRLF
      $strPowerManagementCapabilities = $objItem.PowerManagementCapabilities(0)
      $Output = $Output & "PowerManagementCapabilities: " & $strPowerManagementCapabilities & @CRLF
      $Output = $Output & "PowerManagementSupported: " & $objItem.PowerManagementSupported & @CRLF
      $Output = $Output & "Present: " & $objItem.Present & @CRLF
      $Output = $Output & "Service: " & $objItem.Service & @CRLF
      $Output = $Output & "Status: " & $objItem.Status & @CRLF
      $Output = $Output & "StatusInfo: " & $objItem.StatusInfo & @CRLF
      $Output = $Output & "SystemCreationClassName: " & $objItem.SystemCreationClassName & @CRLF
      $Output = $Output & "SystemName: " & $objItem.SystemName & @CRLF
      if Msgbox(1,"WMI Output",$Output) = 2 then ExitLoop
      $Output=""
   Next
Else
   Msgbox(0,"WMI Output","No WMI Objects Found for class: " & "Win32_PnPEntity" )
Endif


Func WMIDateStringToDate($dtmDate)

    Return (StringMid($dtmDate, 5, 2) & "/" & _
    StringMid($dtmDate, 7, 2) & "/" & StringLeft($dtmDate, 4) _
    & " " & StringMid($dtmDate, 9, 2) & ":" & StringMid($dtmDate, 11, 2) & ":" & StringMid($dtmDate,13, 2))
EndFunc

And maybe some inspiration from here:

 

 

Edited by ModemJunki
Add USB drive monitor link

Always carry a towel.

Link to comment
Share on other sites

19 minutes ago, ModemJunki said:

Hmmm....

Again I will suggest to abandon devcon and use WMI instead. There must be a way for you to do this without the external program and it's overhead.

When I look into "SELECT * FROM Win32_PnPEntity" I can for certain see a list of device IDs.

AutoIt Scriptomatic is our friend!

; Generated by AutoIt Scriptomatic

$wbemFlagReturnImmediately = 0x10
$wbemFlagForwardOnly = 0x20
$colItems = ""
$strComputer = "localhost"

$Output=""
$Output = $Output & "Computer: " & $strComputer  & @CRLF
$Output = $Output & "==========================================" & @CRLF
$objWMIService = ObjGet("winmgmts:\\" & $strComputer & "\root\CIMV2")
$colItems = $objWMIService.ExecQuery("SELECT * FROM Win32_PnPEntity", "WQL", _
                                          $wbemFlagReturnImmediately + $wbemFlagForwardOnly)

If IsObj($colItems) then
   For $objItem In $colItems
      $Output = $Output & "Availability: " & $objItem.Availability & @CRLF
      $Output = $Output & "Caption: " & $objItem.Caption & @CRLF
      $Output = $Output & "ClassGuid: " & $objItem.ClassGuid & @CRLF
      $strCompatibleID = $objItem.CompatibleID(0)
      $Output = $Output & "CompatibleID: " & $strCompatibleID & @CRLF
      $Output = $Output & "ConfigManagerErrorCode: " & $objItem.ConfigManagerErrorCode & @CRLF
      $Output = $Output & "ConfigManagerUserConfig: " & $objItem.ConfigManagerUserConfig & @CRLF
      $Output = $Output & "CreationClassName: " & $objItem.CreationClassName & @CRLF
      $Output = $Output & "Description: " & $objItem.Description & @CRLF
      $Output = $Output & "DeviceID: " & $objItem.DeviceID & @CRLF
      $Output = $Output & "ErrorCleared: " & $objItem.ErrorCleared & @CRLF
      $Output = $Output & "ErrorDescription: " & $objItem.ErrorDescription & @CRLF
      $strHardwareID = $objItem.HardwareID(0)
      $Output = $Output & "HardwareID: " & $strHardwareID & @CRLF
      $Output = $Output & "InstallDate: " & WMIDateStringToDate($objItem.InstallDate) & @CRLF
      $Output = $Output & "LastErrorCode: " & $objItem.LastErrorCode & @CRLF
      $Output = $Output & "Manufacturer: " & $objItem.Manufacturer & @CRLF
      $Output = $Output & "Name: " & $objItem.Name & @CRLF
      $Output = $Output & "PNPClass: " & $objItem.PNPClass & @CRLF
      $Output = $Output & "PNPDeviceID: " & $objItem.PNPDeviceID & @CRLF
      $strPowerManagementCapabilities = $objItem.PowerManagementCapabilities(0)
      $Output = $Output & "PowerManagementCapabilities: " & $strPowerManagementCapabilities & @CRLF
      $Output = $Output & "PowerManagementSupported: " & $objItem.PowerManagementSupported & @CRLF
      $Output = $Output & "Present: " & $objItem.Present & @CRLF
      $Output = $Output & "Service: " & $objItem.Service & @CRLF
      $Output = $Output & "Status: " & $objItem.Status & @CRLF
      $Output = $Output & "StatusInfo: " & $objItem.StatusInfo & @CRLF
      $Output = $Output & "SystemCreationClassName: " & $objItem.SystemCreationClassName & @CRLF
      $Output = $Output & "SystemName: " & $objItem.SystemName & @CRLF
      if Msgbox(1,"WMI Output",$Output) = 2 then ExitLoop
      $Output=""
   Next
Else
   Msgbox(0,"WMI Output","No WMI Objects Found for class: " & "Win32_PnPEntity" )
Endif


Func WMIDateStringToDate($dtmDate)

    Return (StringMid($dtmDate, 5, 2) & "/" & _
    StringMid($dtmDate, 7, 2) & "/" & StringLeft($dtmDate, 4) _
    & " " & StringMid($dtmDate, 9, 2) & ":" & StringMid($dtmDate, 11, 2) & ":" & StringMid($dtmDate,13, 2))
EndFunc

And maybe some inspiration from here:

 

This looks really good, but way to difficult for my skill level....

I tried the USB Drive Monitor script, but that gives me an error also: 

==> Variable must be of type "Object".:
$colEvents = $objWMIService.ExecNotificationQuery ("Select * From __InstanceOperationEvent Within 5 Where " & "TargetInstance isa 'Win32_LogicalDisk'")
$colEvents = $objWMIService^ ERROR
>Exit code: 1    Time: 0.3105

Edited by Iznogoud
Link to comment
Share on other sites

I'm bored.

Surely there must be a better way than my code, but - it seems to work. Just change the "$s_DeviceID" to yours... can be partial string or full path.

#include <winapi.au3>
#include <array.au3>
;~ #include <debug.au3>
;~ $s_DeviceID = "VID_0781&PID_5530" ; can be partial string
$s_DeviceID = "USB\VID_0781&PID_5530\20052443900EBFD165D2" ; can be full path of string

_MainFunc($s_DeviceID, 3000)

Func _MainFunc($s_ID, $s_Delay)
    $i = 1
    Do
        If _ArrayFindAll(_GetPnPEntity($s_ID), $s_ID) Then
            ConsoleWrite("Found device!" & @CRLF)
            ContinueLoop 1
        Else
            ConsoleWrite("No device found." & @CRLF)
            _WinAPI_LockWorkStation()
            ContinueLoop 1
        EndIf
        Sleep($s_Delay)
    Until $i = 0
EndFunc   ;==>_MainFunc

;~ ; You can play with the below to see all the datas retrieved from the PnPEntity WMI query
;~ $a_PnP = _GetPnPEntity($s_DeviceID)
;~ _ArraySort($a_PnP, "", "", "", 1)
;~ _ArrayDisplay($a_PnP, "PnPEntity", "", "", "", "Availability|Caption|ClassGuid|CompatibleID|ConfigManagerErrorCode|ConfigManagerUserConfig|CreationClassName|Description|DeviceID|ErrorCleared|ErrorDescription|HardwareID|InstallDate|LastErrorCode|Manufacturer|Name|PNPClass|PNPDeviceID|PowerManagementCapabilities|PowerManagementSupported|Present|Service|Status|StatusInfo|SystemCreationClassName|SystemName")
;~ _DebugArrayDisplay($a_PnP, "PnPEntity", "", "", "", "Availability|Caption|ClassGuid|CompatibleID|ConfigManagerErrorCode|ConfigManagerUserConfig|CreationClassName|Description|DeviceID|ErrorCleared|ErrorDescription|HardwareID|InstallDate|LastErrorCode|Manufacturer|Name|PNPClass|PNPDeviceID|PowerManagementCapabilities|PowerManagementSupported|Present|Service|Status|StatusInfo|SystemCreationClassName|SystemName")

Func _GetPnPEntity($s_DeviceID = "")
    If StringInStr($s_DeviceID, "\") Then $s_DeviceID = StringReplace($s_DeviceID, "\", "\\")
    Local $colItems, $objWMIService, $objItem
    Local $strComputer = "localhost"
    Dim $aPnPEntity[1][26], $i = 1
    Local $objWMIService = ObjGet("winmgmts:\\" & $strComputer & "\root\CIMV2")
    If $s_DeviceID = "" Then
        Local $colItems = $objWMIService.ExecQuery("SELECT * FROM Win32_PnPEntity", "WQL") ; , 0x10 + 0x20)
    Else
        Local $colItems = $objWMIService.ExecQuery("SELECT * FROM Win32_PnPEntity WHERE DeviceID LIKE '%" & $s_DeviceID & "%'", "WQL") ; , 0x10 + 0x20)
    EndIf

    If IsObj($colItems) Then
        For $objItem In $colItems
            ReDim $aPnPEntity[UBound($aPnPEntity) + 1][26]
            $aPnPEntity[$i][0] = $objItem.Availability & @CRLF
            $aPnPEntity[$i][1] = $objItem.Caption & @CRLF
            $aPnPEntity[$i][2] = $objItem.ClassGuid & @CRLF
            Local $strCompatibleID = $objItem.CompatibleID(0)
            $aPnPEntity[$i][3] = $strCompatibleID & @CRLF
            $aPnPEntity[$i][4] = $objItem.ConfigManagerErrorCode & @CRLF
            $aPnPEntity[$i][5] = $objItem.ConfigManagerUserConfig & @CRLF
            $aPnPEntity[$i][6] = $objItem.CreationClassName & @CRLF
            $aPnPEntity[$i][7] = $objItem.Description & @CRLF
            $aPnPEntity[$i][8] = $objItem.DeviceID & @CRLF
            $aPnPEntity[$i][9] = $objItem.ErrorCleared & @CRLF
            $aPnPEntity[$i][10] = $objItem.ErrorDescription & @CRLF
            Local $strHardwareID = $objItem.HardwareID(0)
            $aPnPEntity[$i][11] = $strHardwareID & @CRLF
            $aPnPEntity[$i][12] = WMIDateStringToDate($objItem.InstallDate) & @CRLF
            $aPnPEntity[$i][13] = $objItem.LastErrorCode & @CRLF
            $aPnPEntity[$i][14] = $objItem.Manufacturer & @CRLF
            $aPnPEntity[$i][15] = $objItem.Name & @CRLF
            $aPnPEntity[$i][16] = $objItem.PNPClass & @CRLF
            $aPnPEntity[$i][17] = $objItem.PNPDeviceID & @CRLF
            Local $strPowerManagementCapabilities = $objItem.PowerManagementCapabilities(0)
            $aPnPEntity[$i][18] = $strPowerManagementCapabilities & @CRLF
            $aPnPEntity[$i][19] = $objItem.PowerManagementSupported & @CRLF
            $aPnPEntity[$i][20] = $objItem.Present & @CRLF
            $aPnPEntity[$i][21] = $objItem.Service & @CRLF
            $aPnPEntity[$i][22] = $objItem.Status & @CRLF
            $aPnPEntity[$i][23] = $objItem.StatusInfo & @CRLF
            $aPnPEntity[$i][24] = $objItem.SystemCreationClassName & @CRLF
            $aPnPEntity[$i][25] = $objItem.SystemName & @CRLF
            $i += 1
        Next
        $aPnPEntity[0][0] = UBound($aPnPEntity) - 1
        If $aPnPEntity[0][0] < 1 Then
            SetError(1, 1, 0)
        EndIf
    Else
        SetError(1, 2, 0)
    EndIf
    Return $aPnPEntity
EndFunc   ;==>_GetPnPEntity

Func WMIDateStringToDate($dtmDate)
    Return (StringMid($dtmDate, 5, 2) & "/" & _
            StringMid($dtmDate, 7, 2) & "/" & StringLeft($dtmDate, 4) _
             & " " & StringMid($dtmDate, 9, 2) & ":" & StringMid($dtmDate, 11, 2) & ":" & StringMid($dtmDate, 13, 2))
EndFunc   ;==>WMIDateStringToDate

 

Always carry a towel.

Link to comment
Share on other sites

2 hours ago, ModemJunki said:

I'm bored.

Surely there must be a better way than my code, but - it seems to work. Just change the "$s_DeviceID" to yours... can be partial string or full path.

#include <winapi.au3>
#include <array.au3>
;~ #include <debug.au3>
;~ $s_DeviceID = "VID_0781&PID_5530" ; can be partial string
$s_DeviceID = "USB\VID_0781&PID_5530\20052443900EBFD165D2" ; can be full path of string

_MainFunc($s_DeviceID, 3000)

Func _MainFunc($s_ID, $s_Delay)
    $i = 1
    Do
        If _ArrayFindAll(_GetPnPEntity($s_ID), $s_ID) Then
            ConsoleWrite("Found device!" & @CRLF)
            ContinueLoop 1
        Else
            ConsoleWrite("No device found." & @CRLF)
            _WinAPI_LockWorkStation()
            ContinueLoop 1
        EndIf
        Sleep($s_Delay)
    Until $i = 0
EndFunc   ;==>_MainFunc

;~ ; You can play with the below to see all the datas retrieved from the PnPEntity WMI query
;~ $a_PnP = _GetPnPEntity($s_DeviceID)
;~ _ArraySort($a_PnP, "", "", "", 1)
;~ _ArrayDisplay($a_PnP, "PnPEntity", "", "", "", "Availability|Caption|ClassGuid|CompatibleID|ConfigManagerErrorCode|ConfigManagerUserConfig|CreationClassName|Description|DeviceID|ErrorCleared|ErrorDescription|HardwareID|InstallDate|LastErrorCode|Manufacturer|Name|PNPClass|PNPDeviceID|PowerManagementCapabilities|PowerManagementSupported|Present|Service|Status|StatusInfo|SystemCreationClassName|SystemName")
;~ _DebugArrayDisplay($a_PnP, "PnPEntity", "", "", "", "Availability|Caption|ClassGuid|CompatibleID|ConfigManagerErrorCode|ConfigManagerUserConfig|CreationClassName|Description|DeviceID|ErrorCleared|ErrorDescription|HardwareID|InstallDate|LastErrorCode|Manufacturer|Name|PNPClass|PNPDeviceID|PowerManagementCapabilities|PowerManagementSupported|Present|Service|Status|StatusInfo|SystemCreationClassName|SystemName")

Func _GetPnPEntity($s_DeviceID = "")
    If StringInStr($s_DeviceID, "\") Then $s_DeviceID = StringReplace($s_DeviceID, "\", "\\")
    Local $colItems, $objWMIService, $objItem
    Local $strComputer = "localhost"
    Dim $aPnPEntity[1][26], $i = 1
    Local $objWMIService = ObjGet("winmgmts:\\" & $strComputer & "\root\CIMV2")
    If $s_DeviceID = "" Then
        Local $colItems = $objWMIService.ExecQuery("SELECT * FROM Win32_PnPEntity", "WQL") ; , 0x10 + 0x20)
    Else
        Local $colItems = $objWMIService.ExecQuery("SELECT * FROM Win32_PnPEntity WHERE DeviceID LIKE '%" & $s_DeviceID & "%'", "WQL") ; , 0x10 + 0x20)
    EndIf

    If IsObj($colItems) Then
        For $objItem In $colItems
            ReDim $aPnPEntity[UBound($aPnPEntity) + 1][26]
            $aPnPEntity[$i][0] = $objItem.Availability & @CRLF
            $aPnPEntity[$i][1] = $objItem.Caption & @CRLF
            $aPnPEntity[$i][2] = $objItem.ClassGuid & @CRLF
            Local $strCompatibleID = $objItem.CompatibleID(0)
            $aPnPEntity[$i][3] = $strCompatibleID & @CRLF
            $aPnPEntity[$i][4] = $objItem.ConfigManagerErrorCode & @CRLF
            $aPnPEntity[$i][5] = $objItem.ConfigManagerUserConfig & @CRLF
            $aPnPEntity[$i][6] = $objItem.CreationClassName & @CRLF
            $aPnPEntity[$i][7] = $objItem.Description & @CRLF
            $aPnPEntity[$i][8] = $objItem.DeviceID & @CRLF
            $aPnPEntity[$i][9] = $objItem.ErrorCleared & @CRLF
            $aPnPEntity[$i][10] = $objItem.ErrorDescription & @CRLF
            Local $strHardwareID = $objItem.HardwareID(0)
            $aPnPEntity[$i][11] = $strHardwareID & @CRLF
            $aPnPEntity[$i][12] = WMIDateStringToDate($objItem.InstallDate) & @CRLF
            $aPnPEntity[$i][13] = $objItem.LastErrorCode & @CRLF
            $aPnPEntity[$i][14] = $objItem.Manufacturer & @CRLF
            $aPnPEntity[$i][15] = $objItem.Name & @CRLF
            $aPnPEntity[$i][16] = $objItem.PNPClass & @CRLF
            $aPnPEntity[$i][17] = $objItem.PNPDeviceID & @CRLF
            Local $strPowerManagementCapabilities = $objItem.PowerManagementCapabilities(0)
            $aPnPEntity[$i][18] = $strPowerManagementCapabilities & @CRLF
            $aPnPEntity[$i][19] = $objItem.PowerManagementSupported & @CRLF
            $aPnPEntity[$i][20] = $objItem.Present & @CRLF
            $aPnPEntity[$i][21] = $objItem.Service & @CRLF
            $aPnPEntity[$i][22] = $objItem.Status & @CRLF
            $aPnPEntity[$i][23] = $objItem.StatusInfo & @CRLF
            $aPnPEntity[$i][24] = $objItem.SystemCreationClassName & @CRLF
            $aPnPEntity[$i][25] = $objItem.SystemName & @CRLF
            $i += 1
        Next
        $aPnPEntity[0][0] = UBound($aPnPEntity) - 1
        If $aPnPEntity[0][0] < 1 Then
            SetError(1, 1, 0)
        EndIf
    Else
        SetError(1, 2, 0)
    EndIf
    Return $aPnPEntity
EndFunc   ;==>_GetPnPEntity

Func WMIDateStringToDate($dtmDate)
    Return (StringMid($dtmDate, 5, 2) & "/" & _
            StringMid($dtmDate, 7, 2) & "/" & StringLeft($dtmDate, 4) _
             & " " & StringMid($dtmDate, 9, 2) & ":" & StringMid($dtmDate, 11, 2) & ":" & StringMid($dtmDate, 13, 2))
EndFunc   ;==>WMIDateStringToDate

 

You are great!!! thank you for you time and effort!!

None the less i have a problem, when i use the Hardware ID it says device not found, so i think your script is using an other kind of ID.

How can i check if it uses the right ID of my yubikey?

Link to comment
Share on other sites

46 minutes ago, Iznogoud said:

You are great!!! thank you for you time and effort!!

None the less i have a problem, when i use the Hardware ID it says device not found, so i think your script is using an other kind of ID.

How can i check if it uses the right ID of my yubikey?

You are welcome.

Can you try with only "VID_1050&PID_0114" as the device string?

Otherwise you can use the _GetPnPEntity function with the parts I commented out as it's own script to get all of the PnP entities in a table you can look at.

Like so:

#include <winapi.au3>
#include <array.au3>
#include <debug.au3>

;~ ; You can play with the below to see all the datas retrieved from the PnPEntity WMI query
$a_PnP = _GetPnPEntity()
_ArraySort($a_PnP, "", "", "", 1)
_DebugArrayDisplay($a_PnP, "PnPEntity", "", "", "", "Availability|Caption|ClassGuid|CompatibleID|ConfigManagerErrorCode|ConfigManagerUserConfig|CreationClassName|Description|DeviceID|ErrorCleared|ErrorDescription|HardwareID|InstallDate|LastErrorCode|Manufacturer|Name|PNPClass|PNPDeviceID|PowerManagementCapabilities|PowerManagementSupported|Present|Service|Status|StatusInfo|SystemCreationClassName|SystemName")

Func _GetPnPEntity($s_DeviceID = "")
    If StringInStr($s_DeviceID, "\") Then $s_DeviceID = StringReplace($s_DeviceID, "\", "\\")
    Local $colItems, $objWMIService, $objItem
    Local $strComputer = "localhost"
    Dim $aPnPEntity[1][26], $i = 1
    Local $objWMIService = ObjGet("winmgmts:\\" & $strComputer & "\root\CIMV2")
    If $s_DeviceID = "" Then
        Local $colItems = $objWMIService.ExecQuery("SELECT * FROM Win32_PnPEntity", "WQL") ; , 0x10 + 0x20)
    Else
        Local $colItems = $objWMIService.ExecQuery("SELECT * FROM Win32_PnPEntity WHERE DeviceID LIKE '%" & $s_DeviceID & "%'", "WQL") ; , 0x10 + 0x20)
    EndIf

    If IsObj($colItems) Then
        For $objItem In $colItems
            ReDim $aPnPEntity[UBound($aPnPEntity) + 1][26]
            $aPnPEntity[$i][0] = $objItem.Availability & @CRLF
            $aPnPEntity[$i][1] = $objItem.Caption & @CRLF
            $aPnPEntity[$i][2] = $objItem.ClassGuid & @CRLF
            Local $strCompatibleID = $objItem.CompatibleID(0)
            $aPnPEntity[$i][3] = $strCompatibleID & @CRLF
            $aPnPEntity[$i][4] = $objItem.ConfigManagerErrorCode & @CRLF
            $aPnPEntity[$i][5] = $objItem.ConfigManagerUserConfig & @CRLF
            $aPnPEntity[$i][6] = $objItem.CreationClassName & @CRLF
            $aPnPEntity[$i][7] = $objItem.Description & @CRLF
            $aPnPEntity[$i][8] = $objItem.DeviceID & @CRLF
            $aPnPEntity[$i][9] = $objItem.ErrorCleared & @CRLF
            $aPnPEntity[$i][10] = $objItem.ErrorDescription & @CRLF
            Local $strHardwareID = $objItem.HardwareID(0)
            $aPnPEntity[$i][11] = $strHardwareID & @CRLF
            $aPnPEntity[$i][12] = WMIDateStringToDate($objItem.InstallDate) & @CRLF
            $aPnPEntity[$i][13] = $objItem.LastErrorCode & @CRLF
            $aPnPEntity[$i][14] = $objItem.Manufacturer & @CRLF
            $aPnPEntity[$i][15] = $objItem.Name & @CRLF
            $aPnPEntity[$i][16] = $objItem.PNPClass & @CRLF
            $aPnPEntity[$i][17] = $objItem.PNPDeviceID & @CRLF
            Local $strPowerManagementCapabilities = $objItem.PowerManagementCapabilities(0)
            $aPnPEntity[$i][18] = $strPowerManagementCapabilities & @CRLF
            $aPnPEntity[$i][19] = $objItem.PowerManagementSupported & @CRLF
            $aPnPEntity[$i][20] = $objItem.Present & @CRLF
            $aPnPEntity[$i][21] = $objItem.Service & @CRLF
            $aPnPEntity[$i][22] = $objItem.Status & @CRLF
            $aPnPEntity[$i][23] = $objItem.StatusInfo & @CRLF
            $aPnPEntity[$i][24] = $objItem.SystemCreationClassName & @CRLF
            $aPnPEntity[$i][25] = $objItem.SystemName & @CRLF
            $i += 1
        Next
        $aPnPEntity[0][0] = UBound($aPnPEntity) - 1
        If $aPnPEntity[0][0] < 1 Then
            SetError(1, 1, 0)
        EndIf
    Else
        SetError(1, 2, 0)
    EndIf
    Return $aPnPEntity
EndFunc   ;==>_GetPnPEntity

Func WMIDateStringToDate($dtmDate)
    Return (StringMid($dtmDate, 5, 2) & "/" & _
            StringMid($dtmDate, 7, 2) & "/" & StringLeft($dtmDate, 4) _
             & " " & StringMid($dtmDate, 9, 2) & ":" & StringMid($dtmDate, 11, 2) & ":" & StringMid($dtmDate, 13, 2))
EndFunc   ;==>WMIDateStringToDate

Produces output like in the attached image file, but since I put the script with _DebugArrayDisplay, you can highlight the device and click the "copy data" button (it copies all the entries so paste into Notepad or a new file in SciTE and grab the ID you need from there).

 

PnP_Entities.png

Always carry a towel.

Link to comment
Share on other sites

  • 1 month later...

Hi,

Sorry for my late response, but i want to say your script works great and fast!

Really good addition for my own security. But i do have one question, it now checks for 1 hardware ID, is it possible to add additional Hardware ID's ?
For an example a back-up yubikey?

I tried adding additional functions and renaming them, but i think i am creating a bigger mess then needed. Do you have suggestions?

Link to comment
Share on other sites

Something like it would work (untested).  Replace your main func with this along with the device id.  Rest should stay as is...

$s_DeviceID [3] = ["VID_0781&PID_5530","Device #2","Device #3"]

_MainFunc($s_DeviceID, 3000)

Func _MainFunc($s_ID, $s_Delay)

  While True
    For $i = 0 to Ubound($s_ID)-1
      If not _ArrayFindAll(_GetPnPEntity($s_ID[$i]), $s_ID[$i]) Then
         ConsoleWrite("At least one device not found." & @CRLF)
         _WinAPI_LockWorkStation()
         Exit
      endif
    Next
    ConsoleWrite("Found all devices! Sleep for awhile now" & @CRLF)
    Sleep($s_Delay)
  Wend

EndFunc   ;==>_MainFunc

I made it for 3 devices but you can extend it as you wish...

Edited by Nine
Link to comment
Share on other sites

  • 4 weeks later...

@Nine Sorry for my late reply, some issues i will not bother you with. But for some reason there is an error with this line

$s_DeviceID [3] = ["VID_0781&PID_5530","Device #2","Device #3"]

I can't get rid off it unless i use one DeviceID, but i was wondering, and trying now with one DeviceID, is it possible to secure a specific application with this script?

What i would like to accomplish is an executable which a user can start and then it shows a GUI with a list of buttons with every single name of the employees, when clicked on User1 it then checks if the correct DeviceID is present, if so it should start the application, otherwise it should close / stop the entire script. When the DeviceID is unplugged from the system, it should close the application. This can be done with a simple processkill.

Is this possible?

Link to comment
Share on other sites

5 hours ago, Iznogoud said:

What i would like to accomplish is an executable which a user can start and then it shows a GUI with a list of buttons with every single name of the employees, when clicked on User1 it then checks if the correct DeviceID is present, if so it should start the application, otherwise it should close / stop the entire script. When the DeviceID is unplugged from the system, it should close the application. This can be done with a simple processkill.

Is this possible?

Yes it is totally possible.  But instead of using buttons for employees, I would use a drop-down list or something similar since the number of employees can vary in time.  You must have a list somewhere that you can read and feed the drop-down list.  Just start Scite and go into Koda tool to design your GUI.  Basic code will be generated and you can add the above script once you are satisfied with the interface.

Happy Scripting !

Edited by Nine
Link to comment
Share on other sites

On 6-2-2019 at 2:03 PM, Nine said:

Yes it is totally possible.  But instead of using buttons for employees, I would use a drop-down list or something similar since the number of employees can vary in time.  You must have a list somewhere that you can read and feed the drop-down list.  Just start Scite and go into Koda tool to design your GUI.  Basic code will be generated and you can add the above script once you are satisfied with the interface.

Happy Scripting !

Hi, i don't want to be bold, but can't you help me with this?

I am even willing to pay for the services, because you probably can get this done alot quicker then i would.

I don't mind to change the GUI with buttons time to time, so buttons are quicker for the employees.

Link to comment
Share on other sites

Sorry I don't take contract.  I am retired and have no intention of going back to all that stuff relating to job.  But there is some ppl here that are very very good.  Maybe you could message them.  Or they will since you offering... :)

Edit. But really I am kind of flattered of your offer...

Edited by Nine
Link to comment
Share on other sites

On 2/6/2019 at 4:36 PM, Iznogoud said:

But for some reason there is an error with this line

$s_DeviceID [3] = ["VID_0781&PID_5530","Device #2","Device #3"]

You need to "instantiate" the array by putting either local or global in front of it as appropriate.

Local $s_DeviceID [3] = ["VID_0781&PID_5530","Device #2","Device #3"]

Look in the help file under the Keyword Reference at the Dim article if you are not familiar with variable scopes (global vs local).

Link to comment
Share on other sites

I tried contacting some people on the forum which offered their services before, but i still got no response.

Could someone help me with the last step the put a GUI in front of it with buttons and when User Y is selected it will try to detect the hardware ID and will loop itself like it does now. When the hardware ID is disconnected it needs to close the application instead of logging off.

Link to comment
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
 Share

×
×
  • Create New...