Jump to content
Sign in to follow this  
Chimp

issue reading "default key" from registry with WMI

Recommended Posts

Chimp

thanks to the template kindly provided by UEZ in >this post, I can read KeyValues from the registry using WMI.
In short, to read the value contained in a KeyValue of the registry you have to use the appropriate method according to the KeyType of the Key  that you have to read.
to know the KeyType, must be used the EnumValues method that returns 2 arrays, one  with KeyNames and the other with KeyTypes.

Here is the issue that I do not know how to solve:
according to what is written in the remarks provided about the EnumValues method of the StdRegProv class:
"This method returns a null value for the array when the default value is the only one present."
so, the problem is: how to read the value of a the default KeyValue when it's the only one present since you can not know the KeyType of that key?

the following listing can be used to arise the problem by changing the value of the $sKeyPath variable to a path in your registry that only contains the default KeyValue

Thanks for any help

#include <array.au3>

Global Const $oErrorHandler = ObjEvent("AutoIt.Error", "ObjErrorHandler")
Global $sHost = @ComputerName
Global $sHIVE = "HKEY_CURRENT_USER"
Global $sKeyPath = "SYSTEM\Software" ; <-- change this to a keypath that has only the default KeyValue
Global $sKeyValue = "" ; use a blank string to read the default keyValue
Global $sUser = ""
Global $sPass = ""

$result = WMI_GetRemoteRegVal($sHost, $sHIVE, $sKeyPath, $sKeyValue, $sUser, $sPass)
Local $error = @error
If Not $error Then
    If IsArray($result) Then
        _ArrayDisplay($result)
    Else
        MsgBox(0, "Test", "Value in the Key " & $sKeyValue & " is: " & $result)
    EndIf
Else
    MsgBox(0, "Error", "Error " & $error)
EndIf

Func WMI_GetRemoteRegVal($sHost, $sPrefix, $sRegKeyPath, $sSearchValue, $sUser, $sPass) ;coded by UEZ build 2014-07-06
    If $sHost = "." Then $sHost = "localhost"
    Local $iPing = Ping($sHost, 250)
    If @error Then Return SetError(1, 0, "")
    Local $objWMILocator = ObjCreate("WbemScripting.SWbemLocator")
    Local $objWMIService = $objWMILocator.ConnectServer($sHost, "\\.\root\default", $sUser, $sPass, "", "", 128)
    If @error Then Return SetError(2, @error, "")
    Local $objReg = $objWMIService.Get("StdRegProv") ;http://msdn.microsoft.com/en-us/library/aa393664(v=vs.85).aspx
    If @error Then Return SetError(3, @error, "")
    Local Const $wbemImpersonationLevelImpersonate = 3, $wbemAuthenticationLevelPktPrivacy = 6
    $objReg.Security_.ImpersonationLevel = $wbemImpersonationLevelImpersonate
    $objReg.Security_.AuthenticationLevel = $wbemAuthenticationLevelPktPrivacy

    ; transform Hive name in Hive Hex numeric code
    Local $nHKEY
    Select
        Case $sPrefix = "HKEY_CLASSES_ROOT" Or $sPrefix = "HKCR"
            $nHKEY = 0x80000000
        Case $sPrefix = "HKEY_CURRENT_USER" Or $sPrefix = "HKCU"
            $nHKEY = 0x80000001
        Case $sPrefix = "HKEY_LOCAL_MACHINE" Or $sPrefix = "HKLM"
            $nHKEY = 0x80000002
        Case $sPrefix = "HKEY_USERS" Or $sPrefix = "HKU"
            $nHKEY = 0x80000003
        Case $sPrefix = "HKEY_CURRENT_CONFIG" Or $sPrefix = "HKCC"
            $nHKEY = 0x80000005
        Case Else
            Return SetError(4, 0, "") ; specified Hive not found
    EndSelect

    Local $aSubKeys, $aTypes
    $objReg.EnumValues($nHKEY, $sRegKeyPath, $aSubKeys, $aTypes)
;   the above methos should return 2 arrays ($aSubKeys and $aTypes)
;   but when the KeyPath to read contains only the default KeyValue
;   then it returns an empty string intead of the 2 arrays
;   so HOW TO KNOW THE KEYTYPE OF THE DEFAULT KEYVALUE

    If @error Then Return SetError(6, @error, "")
    Local Enum $iREG_SZ = 1, $iREG_EXPAND_SZ, $iREG_BINARY, $iREG_DWORD, $iREG_DWORD_BIG_ENDIAN, $iREG_LINK, $iREG_MULTI_SZ, $iREG_RESOURCE_LIST, $iREG_FULL_RESOURCE_DESCRIPTOR, $iREG_RESOURCE_REQUIREMENTS_LIST, $iREG_QWORD
    Local $i, $return

    For $i = 0 To UBound($aSubKeys) - 1
        If $aSubKeys[$i] = $sSearchValue Then
            Switch $aTypes[$i]
                Case $iREG_SZ
                    $objReg.GetStringValue($nHKEY, $sRegKeyPath, $sSearchValue, $return)
                    Return  $return
                Case $iREG_EXPAND_SZ
                    $objReg.GetExpandedStringValue($nHKEY, $sRegKeyPath, $sSearchValue, $return)
                    Return  $return
                Case $iREG_BINARY
                    $objReg.GetBinaryValue($nHKEY, $sRegKeyPath, $sSearchValue, $return)
                    Return  $return
                Case $iREG_DWORD
                    $objReg.GetDWORDValue($nHKEY, $sRegKeyPath, $sSearchValue, $return)
                    Return  $return
                Case $iREG_MULTI_SZ
                    $objReg.GetMultiStringValue($nHKEY, $sRegKeyPath, $sSearchValue, $return)
                    Return  $return
                Case $iREG_QWORD
                    $objReg.GetQWORDValue($nHKEY, $sRegKeyPath, $sSearchValue, $return)
                    Return  $return
            EndSwitch
        EndIf
    Next
    Return SetError(7, 0, "")
EndFunc   ;==>WMI_GetRemoteRegVal

Func ObjErrorHandler()
    ConsoleWrite("A COM Error has occured!" & @CRLF & @CRLF & _
            "err.description is: " & @TAB & $oErrorHandler.description & @CRLF & _
            "err.windescription:" & @TAB & $oErrorHandler & @CRLF & _
            "err.number is: " & @TAB & Hex($oErrorHandler.number, 8) & @CRLF & _
            "err.lastdllerror is: " & @TAB & $oErrorHandler.lastdllerror & @CRLF & _
            "err.scriptline is: " & @TAB & $oErrorHandler.scriptline & @CRLF & _
            "err.source is: " & @TAB & $oErrorHandler.source & @CRLF & _
            "err.helpfile is: " & @TAB & $oErrorHandler.helpfile & @CRLF & _
            "err.helpcontext is: " & @TAB & $oErrorHandler.helpcontext & @CRLF _
            )
EndFunc   ;==>ObjErrorHandler
Edited by Chimp

small minds discuss people average minds discuss events great minds discuss ideas.... and use AutoIt....

Share this post


Link to post
Share on other sites
j0kky

Switch $aTypes[$i]
    Case Null

You can:

1 Add a dummy subkey, repeat EnumValues method (in this case the Default Type isn't NULL) and then delete the dummy subkey

Return RegRead($sPrefix & "\" & $sRegKeyPath, "")
Edited by j0kky

Share this post


Link to post
Share on other sites
Chimp

Switch $aTypes[$i]
    Case Null

You can:

1 Add a dummy subkey, repeat EnumValues method (in this case the Default Type isn't NULL) and then delete the dummy subkey

Return RegRead($sPrefix & "\" & $sRegKeyPath, "")

 

Hi j0kky, thanks for your replies

 

Switch $aTypes[$i]
    Case Null
  •  this doesn't because the returned var $aTypes is not an array in that problematic case (this is my problem)

You can:

1 Add a dummy subkey, repeat EnumValues method (in this case the Default Type isn't NULL) and then delete the dummy subkey

  • this could be a workaround, but I would prefer a more "direct" method  (way) to get the data, also because if the "reader" of the registry has only read permissions and not write permission, then this way will fail.
Return RegRead($sPrefix & "\" & $sRegKeyPath, "")
  • this is the native AutoIt function, I have already used in other time,  but I can not use it in this case but I must use WMI way because it allows access to remote registry with different credentials in the way as shown here by >this nice template provided by UEZ

 

...anyway, appreciated yours three solutions proposed :)

thanks again


small minds discuss people average minds discuss events great minds discuss ideas.... and use AutoIt....

Share this post


Link to post
Share on other sites
j0kky

• this doesn't because the returned var $aTypes is not an array in that problematic case (this is my problem)

Are you sure? Documentation says: "Returns null if only the default value is available" just referring to Types parameter...

Unfortunately I don't see other simple solutions that uses only WMI

Edited by j0kky

Share this post


Link to post
Share on other sites
Chimp

Are you sure? Documentation says: "Returns null if only the default value is available" just referring to Types parameter...

Unfortunately I don't see other simple solutions that uses only WMI

 

Already checked with VarGetType()

normally it returns an Array, In the "problem" case it returns a blank string instead.


small minds discuss people average minds discuss events great minds discuss ideas.... and use AutoIt....

Share this post


Link to post
Share on other sites
j0kky

 This method returns a null value for the array when the default value is the only one present. When writing scripts, be sure to check for the null value (using IsNull); this is a good practice before accessing any VBScript variant

You're right! I didn't read this part... So, you can check if the variable is Null before listing all the array cases... But I don't know hot to get its value only with WMI...

Edited by j0kky

Share this post


Link to post
Share on other sites
trancexx

this is the native AutoIt function, I have already used in other time,  but I can not use it in this case but I must use WMI way because it allows access to remote registry with different credentials in the way as shown here by >this nice template provided by UEZ

In that case call LogonUser and ImpersonateLoggedOnUser before using built-in function.


♡♡♡

.

eMyvnE

Share this post


Link to post
Share on other sites
ripdad

Line 56

$i is automatically declared at the For Loop.

Line 58

If $aSubKeys[$i] == $sSearchValue Then

If blank = blank then blank = 0

If blank == blank then blank = blank

blankity blank blank...


"The mediocre teacher tells. The Good teacher explains. The superior teacher demonstrates. The great teacher inspires." -William Arthur Ward

Share this post


Link to post
Share on other sites
Chimp

In that case call LogonUser and ImpersonateLoggedOnUser before using built-in function.

 

Hi trancexx, thanks for your post

it sounds interesting.

Looks not difficult, (but it's not easy.... :unsure:)

I will try and look into the matter and will report here results....

Thanks again


small minds discuss people average minds discuss events great minds discuss ideas.... and use AutoIt....

Share this post


Link to post
Share on other sites
BrewManNH

Line 56

$i is automatically declared at the For Loop.

Line 58

If $aSubKeys[$i] == $sSearchValue Then
If blank = blank then blank = 0

If blank == blank then blank = blank

blankity blank blank...

 

That's wrong, "" is only converted if comparing it to a number, if compared against "" they'd be equivalent.

== is used to do a case sensitive comparison of strings.


If I posted any code, assume that code was written using the latest release version unless stated otherwise. Also, if it doesn't work on XP I can't help with that because I don't have access to XP, and I'm not going to.
Give a programmer the correct code and he can do his work for a day. Teach a programmer to debug and he can do his work for a lifetime - by Chirag Gude
How to ask questions the smart way!

I hereby grant any person the right to use any code I post, that I am the original author of, on the autoitscript.com forums, unless I've specifically stated otherwise in the code or the thread post. If you do use my code all I ask, as a courtesy, is to make note of where you got it from.

Back up and restore Windows user files _Array.au3 - Modified array functions that include support for 2D arrays.  -  ColorChooser - An add-on for SciTE that pops up a color dialog so you can select and paste a color code into a script.  -  Customizable Splashscreen GUI w/Progress Bar - Create a custom "splash screen" GUI with a progress bar and custom label.  -  _FileGetProperty - Retrieve the properties of a file  -  SciTE Toolbar - A toolbar demo for use with the SciTE editor  -  GUIRegisterMsg demo - Demo script to show how to use the Windows messages to interact with controls and your GUI.  -   Latin Square password generator

Share this post


Link to post
Share on other sites
ripdad

That's wrong, "" is only converted if comparing it to a number, if compared against "" they'd be equivalent.

== is used to do a case sensitive comparison of strings.

Thats assuming that default is blank and not something else.


"The mediocre teacher tells. The Good teacher explains. The superior teacher demonstrates. The great teacher inspires." -William Arthur Ward

Share this post


Link to post
Share on other sites
ripdad

If Not IsArray($aSubKeys) Then Return ''

If Default is the only Valuename in the key, then no array is given. (most of the time)

If you write another Valuename in the key, then it will return the value of Default.

A bug in WMI for sure.


"The mediocre teacher tells. The Good teacher explains. The superior teacher demonstrates. The great teacher inspires." -William Arthur Ward

Share this post


Link to post
Share on other sites
ripdad

@ripdad: Before returning, Chimp needs to know Default value, this is the issue.

Yes, I gave a dirty work-around for it.

1. Write another Valuename.

2. Get the value of (Default).

3. Delete the Valuename that was written.

4. Return the value of (Default).


"The mediocre teacher tells. The Good teacher explains. The superior teacher demonstrates. The great teacher inspires." -William Arthur Ward

Share this post


Link to post
Share on other sites
BrewManNH

Thats assuming that default is blank and not something else.

That makes no sense, if it's empty then comparing it to and empty string is equal no matter which comparator you use. Which is what I said above, I'm not assuming anything, I'm just telling you that an empty string compared to an empty string is equal.

If it's not an empty string and a number is returned instead,  then the empty string will get converted to a number.You'd be better off just forcing everything to strings if you want to compare strings.


If I posted any code, assume that code was written using the latest release version unless stated otherwise. Also, if it doesn't work on XP I can't help with that because I don't have access to XP, and I'm not going to.
Give a programmer the correct code and he can do his work for a day. Teach a programmer to debug and he can do his work for a lifetime - by Chirag Gude
How to ask questions the smart way!

I hereby grant any person the right to use any code I post, that I am the original author of, on the autoitscript.com forums, unless I've specifically stated otherwise in the code or the thread post. If you do use my code all I ask, as a courtesy, is to make note of where you got it from.

Back up and restore Windows user files _Array.au3 - Modified array functions that include support for 2D arrays.  -  ColorChooser - An add-on for SciTE that pops up a color dialog so you can select and paste a color code into a script.  -  Customizable Splashscreen GUI w/Progress Bar - Create a custom "splash screen" GUI with a progress bar and custom label.  -  _FileGetProperty - Retrieve the properties of a file  -  SciTE Toolbar - A toolbar demo for use with the SciTE editor  -  GUIRegisterMsg demo - Demo script to show how to use the Windows messages to interact with controls and your GUI.  -   Latin Square password generator

Share this post


Link to post
Share on other sites
ripdad

As far as I'm concerned, no conversion is necessary nor wanted.

Others have a different opinion -- though the logic escapes me.

Thats okay, I will adapt.


"The mediocre teacher tells. The Good teacher explains. The superior teacher demonstrates. The great teacher inspires." -William Arthur Ward

Share this post


Link to post
Share on other sites
ripdad

$objReg.SetStringValue($nHKEY, $sRegKeyPath, 'TEST001', '0')
Local $aSubKeys, $aTypes
$objReg.EnumValues($nHKEY, $sRegKeyPath, $aSubKeys,$aTypes)
$objReg.DeleteValue($nHKEY, $sRegKeyPath, 'TEST001')

Assume @error -7 is no value, if no value is present in (Default).

Another bug -- or perhaps part of the same one.

It should return blank, no matter what.

It doesn't show up in the array.

In any case, if there is a value in (Default), then the

above code should work.

-edit-

That is, assuming you have write privilege.

Edited by ripdad

"The mediocre teacher tells. The Good teacher explains. The superior teacher demonstrates. The great teacher inspires." -William Arthur Ward

Share this post


Link to post
Share on other sites
ripdad

BrewManNH,

The last one is kinda cool. It looks like a "conversion" bug.

MsgBox(0, '', '' = '')
MsgBox(0, '', '' = 0)
MsgBox(0, '', '' < 1)
MsgBox(0, '', '' > -1)
MsgBox(0, '', '' / 0)

"The mediocre teacher tells. The Good teacher explains. The superior teacher demonstrates. The great teacher inspires." -William Arthur Ward

Share this post


Link to post
Share on other sites
BrewManNH

Not a bug that I can see, it's converting the string to a number and trying to divide by 0. Whenever AutoIt does math, it assumes that what you're doing the math on is numeric, so it converts it to a number.


If I posted any code, assume that code was written using the latest release version unless stated otherwise. Also, if it doesn't work on XP I can't help with that because I don't have access to XP, and I'm not going to.
Give a programmer the correct code and he can do his work for a day. Teach a programmer to debug and he can do his work for a lifetime - by Chirag Gude
How to ask questions the smart way!

I hereby grant any person the right to use any code I post, that I am the original author of, on the autoitscript.com forums, unless I've specifically stated otherwise in the code or the thread post. If you do use my code all I ask, as a courtesy, is to make note of where you got it from.

Back up and restore Windows user files _Array.au3 - Modified array functions that include support for 2D arrays.  -  ColorChooser - An add-on for SciTE that pops up a color dialog so you can select and paste a color code into a script.  -  Customizable Splashscreen GUI w/Progress Bar - Create a custom "splash screen" GUI with a progress bar and custom label.  -  _FileGetProperty - Retrieve the properties of a file  -  SciTE Toolbar - A toolbar demo for use with the SciTE editor  -  GUIRegisterMsg demo - Demo script to show how to use the Windows messages to interact with controls and your GUI.  -   Latin Square password generator

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
Sign in to follow this  

  • Similar Content

    • colombeen
      By colombeen
      Hi everyone, I created a function to gather bitlocker information. It can tell you whether or not a drive is protected, which encryption method is being used, ...
      I tried to cover all the details in the function description
       
      The function (and 3 "internal" functions) :
      ; #FUNCTION# ==================================================================================================================== ; Name...........: _BitlockerDriveInfo ; Description ...: Get Bitlocker information for one or multiple drives ; Syntax.........: _BitlockerDriveInfo([$sDrive[, $sComputer = @ComputerName[, $bDebug = False]]]) ; Parameters ....: $sDrive - Optional: The drive. Allowed values are: ; |"" - Get the info for all available drives ; |Letter: - Get the info for the specific drive ; $sComputer - Optional: The computer from which the info should be requested ; $bDebug - Optional: Shows the hex ReturnValue from the WMI methods if set to True ; Return values .: Success - Returns a 2D array with the following information ; |[string] Drive Letter ; |[string] Drive Label ; |[string] Volume Type ; |[bool] Initialized For Protection ; |[string] Protection Status ; |[string] Lock Status ; |[bool] Auto Unlock Enabled ; |[bool] Auto Unlock Key Stored ; |[string] Conversion Status ; |[string] Encryption Method ; |[int] Encryption Percentage ; |[string] Wiping Status ; |[int] Wiping Percentage ; |[array] Key Protectors (Or [string] "None" if the drive isn't protected) ; Failure - 0, sets @error to: ; |1 - There was an issue retrieving the COM object. @extended returns error code from ObjGet ; |2 - The specified drive in $Drive doesn't exist ; |3 - There was an issue running the WMI query ; Author ........: colombeen ; Modified.......: ; Remarks .......: Requires to be run with admin elevation. Windows Vista or newer! ; A BIG THANKS to everyone from the community who contributed! ; Related .......: ; Link ..........: ; Example .......: #include <Array.au3> ; $Header = "Drive Letter|Drive Label|Volume Type|Initialized For Protection|Protection Status|" & _ ; "Lock Status|Auto Unlock Enabled|Auto Unlock Key Stored|Conversion Status|Encryption " & _ ; "Method|Encryption Percentage|Wiping Status|Wiping Percentage|Key Protectors" ; _ArrayDisplay(_BitlockerDriveInfo(), "Bitlocker Drive Info", "", 64, Default, $Header) ; =============================================================================================================================== Func _BitlockerDriveInfo($sDrive = "", $sComputer = @ComputerName, $bDebug = False) Local $aConversionStatusMsg[7] = ["Unknown", "Fully Decrypted", "Fully Encrypted", "Encryption In Progress", "Decryption In Progress", "Encryption Paused", "Decryption Paused"] Local $aEncryptionMethodMsg[9] = ["Unknown", "None", "AES_128_WITH_DIFFUSER", "AES_256_WITH_DIFFUSER", "AES_128", "AES_256", "HARDWARE_ENCRYPTION", "XTS_AES_128", "XTS_AES_256"] Local $aKeyProtectorTypeMsg[11] = ["Unknown or other protector type", "Trusted Platform Module (TPM)", "External key", "Numerical password", "TPM And PIN", "TPM And Startup Key", "TPM And PIN And Startup Key", "Public Key", "Passphrase", "TPM Certificate", "CryptoAPI Next Generation (CNG) Protector"] Local $aLockStatusMsg[3] = ["Unknown", "Unlocked", "Locked"] Local $aProtectionStatusMsg[3] = ["Unprotected", "Protected", "Unknown"] Local $aVolumeTypeMsg[3] = ["Operating System Volume", "Fixed Data Volume", "Portable Data Volume"] Local $aWipingStatusMsg[5] = ["Unknown", "Free Space Not Wiped", "Free Space Wiped", "Free Space Wiping In Progress", "Free Space Wiping Paused"] Local $iRow = 0 Local $sRunMethod, $objWMIService, $objWMIQuery, $sDriveFilter, $iProtectionStatus, $iLockStatus, $bIsAutoUnlockEnabled, $bIsAutoUnlockKeyStored, $iConversionStatus, $iEncryptionPercentage, $iEncryptionFlags, $iWipingStatus, $iWipingPercentage, $iEncryptionMethod, $aVolumeKeyProtectorID, $aVolumeKeyProtectors, $iKeyProtectorType $objWMIService = ObjGet("winmgmts:{impersonationLevel=impersonate,authenticationLevel=pktPrivacy}!\\" & $sComputer & "\root\CIMV2\Security\MicrosoftVolumeEncryption") If @error Then Return SetError(1, @error, 0) If $sDrive <> "" Then Local $iDriveType = _WMIPropertyValue("DriveType", "Win32_LogicalDisk", "WHERE DeviceID='" & $sDrive & "'", Default, $sComputer) If @error Or ($iDriveType <> 2 And $iDriveType <> 3) Then Return SetError(2, 0, 0) $sDriveFilter = " WHERE DriveLetter='" & $sDrive & "'" EndIf $objWMIQuery = $objWMIService.ExecQuery("SELECT * FROM Win32_EncryptableVolume" & $sDriveFilter, "WQL", 0) If Not IsObj($objWMIQuery) Then Return SetError(3, 0, 0) Local $aResult[$objWMIQuery.count][14] For $objDrive In $objWMIQuery If $bDebug Then ConsoleWrite(@CRLF & "+> " & $objDrive.DriveLetter & @CRLF) If _WMIMethodExists($objDrive, "GetConversionStatus") Then $sRunMethod = $objDrive.GetConversionStatus($iConversionStatus, $iEncryptionPercentage, $iEncryptionFlags, $iWipingStatus, $iWipingPercentage) If $bDebug Then ConsoleWrite("!> GetConversionStatus 0x" & Hex($sRunMethod) & @CRLF) Else $iConversionStatus = -1 $iWipingStatus = -1 $iEncryptionPercentage = 0 $iWipingPercentage = 0 EndIf If _WMIMethodExists($objDrive, "GetEncryptionMethod") Then $sRunMethod = $objDrive.GetEncryptionMethod($iEncryptionMethod) If $bDebug Then ConsoleWrite("!> GetEncryptionMethod 0x" & Hex($sRunMethod) & @CRLF) Else $iEncryptionMethod = 0 EndIf If _WMIMethodExists($objDrive, "GetKeyProtectors") Then $sRunMethod = $objDrive.GetKeyProtectors("0", $aVolumeKeyProtectorID) If $bDebug Then ConsoleWrite("!> GetKeyProtectors 0x" & Hex($sRunMethod) & @CRLF) Else $aVolumeKeyProtectorID = 0 EndIf If _WMIMethodExists($objDrive, "GetLockStatus") Then $sRunMethod = $objDrive.GetLockStatus($iLockStatus) If $bDebug Then ConsoleWrite("!> GetLockStatus 0x" & Hex($sRunMethod) & @CRLF) Else $iLockStatus = -1 EndIf If _WMIMethodExists($objDrive, "GetProtectionStatus") Then $sRunMethod = $objDrive.GetProtectionStatus($iProtectionStatus) If $bDebug Then ConsoleWrite("!> GetProtectionStatus 0x" & Hex($sRunMethod) & @CRLF) Else $iProtectionStatus = 2 EndIf If _WMIMethodExists($objDrive, "IsAutoUnlockEnabled") Then $sRunMethod = $objDrive.IsAutoUnlockEnabled($bIsAutoUnlockEnabled) If $bDebug Then ConsoleWrite("!> IsAutoUnlockEnabled 0x" & Hex($sRunMethod) & @CRLF) Else $bIsAutoUnlockEnabled = "Unknown" EndIf If _WMIMethodExists($objDrive, "IsAutoUnlockKeyStored") Then $sRunMethod = $objDrive.IsAutoUnlockKeyStored($bIsAutoUnlockKeyStored) If $bDebug Then ConsoleWrite("!> IsAutoUnlockKeyStored 0x" & Hex($sRunMethod) & @CRLF) Else $bIsAutoUnlockKeyStored = "Unknown" EndIf If IsArray($aVolumeKeyProtectorID) And UBound($aVolumeKeyProtectorID) > 0 Then Dim $aVolumeKeyProtectors[UBound($aVolumeKeyProtectorID)][2] For $i = 0 To UBound($aVolumeKeyProtectorID) - 1 $aVolumeKeyProtectors[$i][0] = $aVolumeKeyProtectorID[$i] If _WMIMethodExists($objDrive, "GetKeyProtectorType") Then If $objDrive.GetKeyProtectorType($aVolumeKeyProtectorID[$i], $iKeyProtectorType) = 0 Then $aVolumeKeyProtectors[$i][1]= $aKeyProtectorTypeMsg[$iKeyProtectorType] Else $aVolumeKeyProtectors[$i][1]= "Unknown" EndIf Else $aVolumeKeyProtectors[$i][1] = "Unknown" EndIf Next Else $aVolumeKeyProtectors = "None" EndIf ; DriveLetter $aResult[$iRow][0] = $objDrive.DriveLetter ; DriveLabel $aResult[$iRow][1] = _WMIPropertyValue("VolumeName", "Win32_LogicalDisk", "WHERE DeviceID='" & $objDrive.DriveLetter & "'", Default, $sComputer) ; VolumeType If _WMIPropertyExists($objDrive, "VolumeType") Then $aResult[$iRow][2] = $aVolumeTypeMsg[$objDrive.VolumeType] Else If $objDrive.DriveLetter = _WMIPropertyValue("SystemDrive", "Win32_OperatingSystem", "", Default, $sComputer) Then $aResult[$iRow][2]= $aVolumeTypeMsg[0] ElseIf _WMIPropertyValue("DriveType", "Win32_LogicalDisk", "WHERE DeviceID='" & $objDrive.DriveLetter & "'", Default, $sComputer) = 3 Then $aResult[$iRow][2]= $aVolumeTypeMsg[1] ElseIf _WMIPropertyValue("DriveType", "Win32_LogicalDisk", "WHERE DeviceID='" & $objDrive.DriveLetter & "'", Default, $sComputer) = 2 Then $aResult[$iRow][2]= $aVolumeTypeMsg[2] Else $aResult[$iRow][2]= "Unknown" EndIf EndIf ; IsVolumeInitializedForProtection If _WMIPropertyExists($objDrive, "IsVolumeInitializedForProtection") Then $aResult[$iRow][3] = $objDrive.IsVolumeInitializedForProtection Else $aResult[$iRow][3] = "Unkown" EndIf ; ProtectionStatus $aResult[$iRow][4] = $aProtectionStatusMsg[$iProtectionStatus] ; LockStatus $aResult[$iRow][5] = $aLockStatusMsg[$iLockStatus + 1] ; IsAutoUnlockEnabled $aResult[$iRow][6] = $bIsAutoUnlockEnabled ; IsAutoUnlockEnabled $aResult[$iRow][7] = $bIsAutoUnlockKeyStored ; ConversionStatus $aResult[$iRow][8] = $aConversionStatusMsg[$iConversionStatus + 1] ; EncryptionMethod $aResult[$iRow][9] = $aEncryptionMethodMsg[$iEncryptionMethod + 1] ; EncryptionPercentage $aResult[$iRow][10] = $iEncryptionPercentage ; WipingStatus $aResult[$iRow][11] = $aWipingStatusMsg[$iWipingStatus + 1] ; WipingPercentage $aResult[$iRow][12] = $iWipingPercentage ; KeyProtectors $aResult[$iRow][13] = $aVolumeKeyProtectors $iRow += 1 Next _ArraySort($aResult) Return $aResult EndFunc ;==>_BitlockerDriveInfo Func _WMIPropertyExists($Object, $Property) If Not IsObj($Object) Then Return False For $sProperty In $Object.Properties_ If $sProperty.Name = $Property Then Return True Next Return False EndFunc ;==>_WMIPropertyExists Func _WMIMethodExists($Object, $Method) If Not IsObj($Object) Then Return False For $sMethod In $Object.Methods_ If $sMethod.Name = $Method Then Return True Next Return False EndFunc ;==>_WMIMethodExists Func _WMIPropertyValue($sProperty = "", $sClass = "", $sFilter = "", $sNamespace = Default, $sComputer = @ComputerName) Local $objWMIService, $objWMIQuery If $sClass = "" Or $sProperty = "" Then Return SetError(1, 0, 0) If $sFilter <> "" Then $sFilter = " " & $sFilter If $sNamespace = Default Then $sNamespace = "\root\CIMV2" $objWMIService = ObjGet("winmgmts:{impersonationLevel=impersonate,authenticationLevel=pktPrivacy}!\\" & $sComputer & $sNamespace) If @error Then Return SetError(2, @error, 0) $objWMIQuery = $objWMIService.ExecQuery("SELECT * FROM " & $sClass & $sFilter, "WQL", 0x30) If Not IsObj($objWMIQuery) Then Return SetError(3, 0, 0) For $objItem In $objWMIQuery For $Property In $objItem.Properties_ If $Property.Name = $sProperty Then Return $Property.Value EndIf Next Next Return SetError(4, 0, 0) EndFunc ;==>_WMIPropertyValue  
      Example 1:
      #RequireAdmin #include <array.au3> ; Get information on all available drives Global $test = _BitlockerDriveInfo() If @error Then ConsoleWrite("!> _BitlockerDriveInfo() error: " & @error & ". extended: " & @extended & @CRLF) ElseIf IsArray($test) Then _ArrayDisplay($test, "Bitlocker Drive Info", "", 64, Default, "Drive Letter|Drive Label|Volume Type|Initialized For Protection|Protection Status|Lock Status|Auto Unlock Enabled|Auto Unlock Key Stored|Conversion Status|Encryption Method|Encryption Percentage|Wiping Status|Wiping Percentage|Key Protectors") ; Display the Key Protectors for the first record If IsArray($test[0][13]) Then _ArrayDisplay($test[0][13]) EndIf Example 2:
      #RequireAdmin #include <array.au3> ; Get information on the C-drive of the current computer + show extra information in the console Global $test = _BitlockerDriveInfo("C:", @ComputerName, True) If @error Then ConsoleWrite("!> _BitlockerDriveInfo() error: " & @error & ". extended: " & @extended & @CRLF) ElseIf IsArray($test) Then ConsoleWrite("Bitlocker information on the " & $test[0][0] & " drive" & @CRLF) ConsoleWrite("Protection Status: " & $test[0][4] & @CRLF) EndIf  
      Screenshot for the first example:

       
      Suggestions? Bugs?
      Just let me know
       
      TODO:
      ???  
      Version 1.0:
      Initial release Version 1.1:
      Fixed: Drive Label will not work when you request the information from a remote system (currently using DriveGetLabel) Fixed: The current fix for the missing VolumeType property in some Windows versions will only work locally Added: New internal function (_WMIPropertyValue()) Version 1.2:
      Fixed: The drive exists & drive type check only worked locally when a drive was specified in $sDrive
    • colombeen
      By colombeen
      Hi guys,
      I'm trying to get some information using WMI, from the Win32_EncryptableVolume class.
      I exec my query, filter out the C-drive, but when I need more info using the objects methods, I only get 1 value back and I can't seem to retrieve the other out params that should be there.
      A very minimal version of what I'm trying to do (no error checking etc, very basic). You need to start SciTE as admin or you won't see any results in the console!
      #RequireAdmin $strComputer = @ComputerName $objWMIService = ObjGet("winmgmts:{impersonationLevel=impersonate}!\\" & $strComputer & "\root\CIMV2\Security\MicrosoftVolumeEncryption") $objWMIQuery = $objWMIService.ExecQuery("SELECT * FROM Win32_EncryptableVolume WHERE DriveLetter='C:'", "WQL", 0) For $objDrive In $objWMIQuery ConsoleWrite("> " & $objDrive.GetConversionStatus() & @CRLF) ConsoleWrite("> " & $objDrive.GetConversionStatus().ConversionStatus & @CRLF) ConsoleWrite("> " & $objDrive.GetConversionStatus().EncryptionPercentage & @CRLF) Next The result from the console is : 
      > 0 > > What I'm expecting to get back is : 
      > 0 > 0 > 0 When using powershell I get this (run as admin is required!!!) : 
      PS C:\WINDOWS\system32> (Get-WmiObject -namespace "Root\cimv2\security\MicrosoftVolumeEncryption" -ClassName "Win32_Encryptablevolume" -Filter "DriveLetter='C:'").GetConversionStatus() ... ConversionStatus : 0 EncryptionFlags : 0 EncryptionPercentage : 0 ReturnValue : 0 ... All I seem to be getting is the ReturnValue when I use the method.
      I've tried this on multiple methods, always ending up with the same result
      Anyone here who has experience with this type of thing?
       
      Greetz
      colombeen
    • FrancescoDiMuro
      By FrancescoDiMuro
      Good evening everyone
      I'm working on a little project of mines, and I was trying to use WMI Object.
      The question which I don't find an answer is: 
      Once I do the query with WMI Object, something like "SELECT * FROM Win32_LogonSession", instead of specify the field of the collection returned, ( i.e. $colItems.Caption ), can I loop though each property and each value of the property, writing so one row of code only?
      Hope my question was clear enough.
      Thanks in advance.

      Best Regards.
    • ahmet
      By ahmet
      Hello,
      I am trying to make a program that will uninstall some software, provided by some form of a list. I have this
      ; Generated by AutoIt Scriptomatic June 08, 2010 ;#RequireAdmin $sPartialName="java" $wbemFlagReturnImmediately = 0x10 $wbemFlagForwardOnly = 0x20 $colItems = "" $strComputer = "localhost" ;$objWMIService = ObjGet("winmgmts:\\" & $strComputer & "\root\CIMV2") ;$objWMIService=ObjGet("winmgmts:{impersonationLevel=impersonate}!\\" & @ComputerName & "\root\cimv2") $objWMIService=ObjGet("winmgmts:{impersonationLevel=impersonate}!\\" & @ComputerName & "\root\cimv2") $colItems = $objWMIService.ExecQuery("SELECT * FROM Win32_Product", "WQL", $wbemFlagReturnImmediately + $wbemFlagForwardOnly) If IsObj($colItems) then For $objItem In $colItems If StringInStr($objItem.Name,$sPartialName)=1 Then ConsoleWrite("Full name:" & $objItem.Name & @CRLF) RunAs("USERNAME",@ComputerName,"PASSWORD",0,@ComSpec & " /c" & ' wmic product where name="Java 9.0.4 (64-bit)" call uninstall /nointeractive',"C:\WINDOWS\system32\wbem",@SW_MAXIMIZE) ;Run('wmic product where name="Java 9.0.4 (64-bit)" call uninstall /nointeractive',"",@SW_MAXIMIZE) ExitLoop EndIf Next Else Msgbox(0,"WMI Output","No WMI Objects Found for class: " & "Win32_Product" ) Endif The script above fails uninstalling software despite providing username and password for admin account. If I run script with admin rights then the software gets uninstalled.
      At the following link there is a script by JLogan3o13 but it does not either uninstall software, unless run as admin..
      Is there some way to uninstall software using wim or wimc by providing user name and password?
       
    • Bilgus
      By Bilgus
      #include <Array.Au3> ;WMI EXAMPLE Local $strComputer = "localhost" Local $sClass = "" Local $objClass Local $objWMIService = ObjGet("winmgmts:\\" & $strComputer & "\root\cimv2") ; Display all available Classes in this object _ArrayDisplay(Get_Classes($objWMIService), "AVAILABLE WMI CLASSES", "", 0, Default, "NAME") ;Split string at \n(@LF) place each into an array $sClass = "Win32_BIOS" ;<-The Class I've choosen ;Lets Try out one of the classes Local $objClass = ObjGet("winmgmts:\\" & $strComputer & "\root\cimv2:" & $sClass) ConsoleWrite($sClass & @CRLF & "------------------------------------------" & @CRLF) _ArrayDisplay(Split_Properties(Get_Properties($objClass)), $sClass & " Properties", "", 0, Default, "NAME|VALUE") ;No methods available for this one but... ConsoleWrite("Methods:" & @CRLF & @CRLF) Get_Methods($objClass) ;Lets Do it again for the network adapter Class $sProperties = "" $sClass = "Win32_NetworkAdapterConfiguration" ;<-The Class I've choosen ;Lets Try out one of the classes $objClass = ObjGet("winmgmts:\\" & $strComputer & "\root\cimv2:" & $sClass) ConsoleWrite($sClass & @CRLF & "------------------------------------------" & @CRLF) _ArrayDisplay(Split_Properties(Get_Properties($objClass)), $sClass & " Properties", "", 0, Default, "NAME|VALUE") ConsoleWrite("Methods:" & @CRLF & @CRLF) Get_Methods($objClass) Func Get_Classes($obj) ; Display all available Classes in this object If IsObj($obj) Then Local $sClasses = "" For $objClass In $obj.SubclassesOf() ;<--WMI Method $sClasses &= ($objClass.Path_.Class) & @LF ;Build a string seperated by \n(@LF) Next EndIf Return StringSplit($sClasses, @LF) EndFunc ;==>Get_Classes Func Get_Methods($objClass) Local $sResults = "" If IsObj($objClass) Then For $objMethods In $objClass.Methods_ ConsoleWrite(@TAB & $objMethods.Name & @CRLF) $sResults &= $objMethods.Name & @LF Next EndIf Return $sResults EndFunc ;==>Get_Methods Func Get_Properties($objClass) Local $sProperties = "" If IsObj($objClass) Then For $objClassProp In $objClass.Properties_() ;<-Another WMI Method For $obj In $objWMIService.ExecQuery("Select * from " & $sClass) ;<-Another WMI Method $sProperties &= $objClassProp.Name & @CR $sProperties &= Parse_Value($obj.Properties_($objClassProp.Name).Value) ;Use the Properties_ Method to call our desired property Next Next EndIf Return $sProperties EndFunc ;==>Get_Properties Func Parse_Value($vValue) Local $sRet = "" Switch StringLower(VarGetType($vValue)) Case "keyword" ; Not really sure what this one is probably NULL $sRet = Number($vValue) = 0 ? "" : Number($vValue) Case "array" $sRet = _ArrayToString($vValue, ", ") Case "string", "bool", "int32", "int64", "double", "binary" $sRet = $vValue Case "pointer" $sRet = "[PTR]:" & $vValue Case Else $sRet = "[" & VarGetType($vValue) & "]: " & $vValue EndSwitch $sRet &= @LF Return $sRet EndFunc ;==>Parse_Value Func Split_Properties($sProperties) Local $aDisp = StringSplit($sProperties, @LF) ;Split string at \n(@LF) place each into an array Local $aTmp If IsArray($aDisp) Then _ArrayColInsert($aDisp, 1) For $i = 1 To $aDisp[0][0] ; String Split stores Count in the first element by default $aTmp = StringSplit($aDisp[$i][0], @CR) ;Split string at \r(@CR) place each into an array If IsArray($aTmp) Then $aDisp[$i][0] = $aTmp[0] > 0 ? $aTmp[1] : "?" ;Check if this element exists if not make it "?" $aDisp[$i][1] = $aTmp[0] > 1 ? $aTmp[2] : " " ;Check if this element exists if not make it " " EndIf Next EndIf Return $aDisp EndFunc ;==>Split_Properties  
×