Hi,
found a powershell script, see attached(PS works), to query Dell BIOS settings but cannot seem to translate to WBT query.
The 'Type' result is EMPTY... I'm missing something, Any suggestions?
...here is my try, copied from tech board: Win32_BIOS
objLocator = ObjectCreate("WbemScripting.SWbemLocator")
;'Namespace' = 'ROOT\dcim\sysman\biosattributes' - FROM Attached Powershell
objService = objLocator.ConnectServer(".","ROOT\dcim\sysman\biosattributes","","")
objSecurity = objService.Security_
objSecurity.ImpersonationLevel = 3
;'Class' = 'EnumerationAttribute' - FROM Attached Powershell
class = "EnumerationAttribute"
; query instances
query = "SELECT * FROM biosattributes"
colInstances = objService.ExecQuery(query)
; loop once for each instance
ForEach objInstance in colInstances
;Check if Object is EMPTY
type = ObjectTypeGet(objInstance)
pause("test type", type)
if type=="EMPTY" then break
propWakeOnLan = objInstance.WakeOnLan ;fails
Next
Maybe not helpful, but only thing I would think was additional parameters to ExecQuery i.e. colInstances = objService.ExecQuery(query,,48).... as you seem to be connecting to remote server.
I don't have the Dell namespace so I can't test this but maybe you need something like "Instance = Service.InstancesOf(Class)" to access the enumeration. Stan's suggestion should be investigated too.
Yes, you need to have a Dell machine to test...
I'm a novice w/WMI so not sure how to apply the suggestions...
Here is an example using a standard MSFT WMI provider. It may or may not be helpful.
Locator = ObjectOpen("WbemScripting.SWbemLocator")
Service = Locator.ConnectServer(".","root/cimv2" )
Service.Security_.ImpersonationLevel = 3
Class = "Win32_ComputerSystem" ; Holds total memory info
Enum = Service.InstancesOf(Class)
Ram = 0
foreach Obj in Enum
Ram+=Obj.TotalPhysicalMemory ;this is the total ram
next
Gb = 1024.0**3
GigRam = ram / Gb
exit
ok, another try is now getting a object type of 'DISPATCH' . . .hmmm
objLocator = ObjectCreate("WbemScripting.SWbemLocator")
objService = objLocator.ConnectServer(".","ROOT\dcim\sysman\biosattributes","","")
objSecurity = objService.Security_
objSecurity.ImpersonationLevel = 3
class = "EnumerationAttribute"
; query instances
query = "SELECT * FROM EnumerationAttribute"
colInstances = objService.ExecQuery(query)
Instance = objService.InstancesOf(class)
ForEach objInstance in Instance
;Check if Object is EMPTY
type = ObjectTypeGet(objInstance)
pause("test type", type) ; getting 'DISPATCH' here
;if type=="EMPTY" then break
Next
Maybe you can iterate instance values, [just guessing]
ForEach objInstance in Instance
A = objInstance.AttributeName
C = objInstance.CurrentValue
P = objInstance.PossibleValue
Display(2,"Enumeration",A:",":C:",":P)
Next
Thanks All,
thanks Stan!...
that worked!!! with one data type mismatch, see below
.....................................................
delimiter = @tab
objLocator = ObjectCreate("WbemScripting.SWbemLocator")
objService = objLocator.ConnectServer(".","ROOT\dcim\sysman\biosattributes","","")
objSecurity = objService.Security_
objSecurity.ImpersonationLevel = 3
class = "EnumerationAttribute"
; query instances
query = "SELECT * FROM EnumerationAttribute"
colInstances = objService.ExecQuery(query)
Instance = objService.InstancesOf(class)
ForEach objInstance in Instance
A = objInstance.AttributeName
;pause("test A", A)
C = objInstance.CurrentValue
;pause("test C", C)
vals = objInstance.PossibleValue ; keep getting Data MisMatch with this one
pause("test vals", vals) ; WMI says should be an 'array of string'
ForEach val in vals ; see below for data types
next
pause("Enumeration", A:@lf:C)
Next
*********************************************
Enumeration Attribute (EnumerationAttribute)
*********************************************
Property name Type Read/Write Value
---------------------------------------------------------------------------------
__GENUS Read Only 1
__CLASS Read Only EnumerationAttribute
__SUPERCLASS Read Only
__DYNASTY Read Only EnumerationAttribute
__RELPATH Read Only EnumerationAttribute
__PROPERTY_COUNT Read Only 12
__DERIVATION Read Only
__SERVER Read Only MV-IT-6T149R3
__NAMESPACE Read Only ROOT\dcim\sysman\biosattributes
__PATH Read Only \\MV-IT-6T149R3\ROOT\dcim\sysman\biosattributes:EnumerationAttribute
AttributeName string Read Only
CurrentValue string Read Only
DefaultValue string Read Only
DisplayName string Read Only
DisplayNameLangCode string Read Only
InstanceName string Read Only
Modifiers string Read Only
PossibleValue array of string Read Only
PossibleValueCount uint32 Read Only
ReadOnly boolean Read Only
ValueModifierCount uint32 Read Only
ValueModifiers array of string Read Only
Oh ok, so this 'array of string' looks like this:
;Possible Value : {Disabled, Basic, Enhanced, Full}
Quote from: domvalle@comcast.net on August 21, 2024, 08:21:24 AMOh ok, so this 'array of string' looks like this:
;Possible Value : {Disabled, Basic, Enhanced, Full}
Not sure the ultimate focus. But script seems it would work w/out PosibleValues iteration. If your intention is for a script to change values based on what is possible,,, that might be another interesting next step, otherwise a basic WMI query for Win32_Bios would suffice for most users interpreting BIOS.
Yes, ultimately need to be able to update/change Bios settings on entire network.
WMI would be the first choice...
thanks Stan...
OK, finally some useful results below...
...able to return all objects now, next to see if we can update,
;***************************************************************************
;** Test Dell Bios Objects w/WMI
;***************************************************************************
;*********************************************
;Enumeration Attribute (EnumerationAttribute)
;*********************************************
;
;Property name Type Read/Write Value Description
;------------------------------------------------------------------------------------------------------------
;__GENUS Read Only 1
;__CLASS Read Only EnumerationAttribute
;__SUPERCLASS Read Only
;__DYNASTY Read Only EnumerationAttribute
;__RELPATH Read Only EnumerationAttribute
;__PROPERTY_COUNT Read Only 12
;__DERIVATION Read Only
;__SERVER Read Only MV-IT-6T149R3
;__NAMESPACE Read Only ROOT\dcim\sysman\biosattributes
;__PATH Read Only \\MV-IT-6T149R3\ROOT\dcim\sysman\biosattributes:EnumerationAttribute
;AttributeName string Read Only
;CurrentValue string Read Only
;DefaultValue string Read Only
;DisplayName string Read Only
;DisplayNameLangCode string Read Only
;InstanceName string Read Only
;Modifiers string Read Only
;PossibleValue array of string Read Only
;PossibleValueCount uint32 Read Only
;ReadOnly boolean Read Only
;ValueModifierCount uint32 Read Only
;ValueModifiers array of string Read Only
;
delimiter = @tab
objLocator = ObjectCreate("WbemScripting.SWbemLocator")
objService = objLocator.ConnectServer(".","ROOT\dcim\sysman\biosattributes","","")
objSecurity = objService.Security_
objSecurity.ImpersonationLevel = 3
class = "EnumerationAttribute"
; query instances
query = "SELECT * FROM EnumerationAttribute"
colInstances = objService.ExecQuery(query)
Instance = objService.InstancesOf(class)
ForEach objInstance in Instance
A = objInstance.AttributeName
;pause("test A", A)
C = objInstance.CurrentValue
;pause("test C", C)
Vcnt = objInstance.PossibleValueCount
;pause("test cnt", cnt)
vals = objInstance.PossibleValue
;type = ObjectTypeGet(vals) ;this is a SAFEARRAY | ARRAY in VARIANT
;pause("test type", type)
strList = ArrayItemize( vals, "," )
;pause("test strList", strList)
pause("Enumeration", "NAME: " : A : @lf : "CurrentValue: " : C : @lf : "PossibleValues: " : "%strList%" )
;will display results:
; NAME: RemoteWipeInternalDrives
; CurrentValue: Unarmed
;PossibleValues: Unarmed,Armed,Complete,Error
Next
; close object handles
ObjectClose(colInstances)
ObjectClose(objSecurity)
ObjectClose(objService)
ObjectClose(objLocator)
Quote from: domvalle@comcast.net on August 21, 2024, 08:48:52 PMOK, finally some useful results below...
...able to return all objects now, next to see if we can update,
I assume you reviewed the Dell Bios article https://www.configjon.com/dell-bios-settings-management-wmi/ which covers the BIOSAttributeInterface class and the SetAttribute method. Looks like the PS code can be converted to WB w/out much difficulty.
Yes, but looked too complicated at first... but I will review again, thanks Stan!
here is another version for the SetAttribute...
as per: https://dl.dell.com/manuals/common/dell-agentless-client-manageability.pdf
$BAI = Get-WmiObject -Namespace root/dcim/sysman/biosattributes -Class
BIOSAttributeInterface
Note that you are storing the instance in a PowerShell environment variable called $BAI. This will allow you to use the same instance for future configuration settings. Once you have the class instance, executing a Set operation becomes simple.
$BAI.SetAttribute(0,0,0,"UefiNwStack","Disabled")
Note that the first three arguments are set to zero if BIOS administrator password is not set on the system.
however I get an error when I tried this:
if A == "NumLockLed" ;(objInstance)
; as per: https://dl.dell.com/manuals/common/dell-agentless-client-manageability.pdf
objInstance.SetAttribute(0,0,0,"NumLockLed","Disabled") ;getting UnKnown Name <---
y = objInstance.CurrentValue
pause("test y", y)
else
endif
Not sure how to help. Only experience I had was circa 2008 when I managed a SQL Server network for DISH installations where they set up 12-16 workstations for sales promotions. So persons were hired for promotion calls usually ending at 10-11 PM. My boss was suspicious that many might be using the network to browse porn sites or other nefarious subjects and wanted proof. So I set up WakeOnLan and from home after midnight could investigate their IE cache even if they had supposedly deleted their browsing history and closed down. The PC's were ACER but BIOS is BIOS [I think].
Long story short. Maybe you can investigate a specific attribute like WakeOnLan, script a GetAttribute and attempt a set attribute. My 2008 code was pure WB, and if I can dig it up might be useful.
thanks Stan... I will update if I get something to work...
Quote from: domvalle@comcast.net on August 23, 2024, 04:49:52 AMhere is another version for the SetAttribute...
as per: https://dl.dell.com/manuals/common/dell-agentless-client-manageability.pdf
$BAI = Get-WmiObject -Namespace root/dcim/sysman/biosattributes -Class
BIOSAttributeInterface
Note that you are storing the instance in a PowerShell environment variable called $BAI. This will allow you to use the same instance for future configuration settings. Once you have the class instance, executing a Set operation becomes simple.
$BAI.SetAttribute(0,0,0,"UefiNwStack","Disabled")
Note that the first three arguments are set to zero if BIOS administrator password is not set on the system.
however I get an error when I tried this:
if A == "NumLockLed" ;(objInstance)
; as per: https://dl.dell.com/manuals/common/dell-agentless-client-manageability.pdf
objInstance.SetAttribute(0,0,0,"NumLockLed","Disabled") ;getting UnKnown Name <---
y = objInstance.CurrentValue
pause("test y", y)
else
endif
Is it possible that you need to use "SetAttribute
s" instead of "SetAttribute" as the object method name?
...same result COM: UnKnown Name
Then how are you populating the "objInstance" variable?
Quote from: td on August 23, 2024, 01:18:40 PMThen how are you populating the "objInstance" variable?
Perhaps, following same logic for a class
objLocator = ObjectCreate("WbemScripting.SWbemLocator")
objService = objLocator.ConnectServer(".","ROOT\dcim\sysman\biosattributes","","")
objSecurity = objService.Security_
objSecurity.ImpersonationLevel = 3
class = "BIOSAttributeInterface"
query = "SELECT * FROM BIOSAttributeInterface"
colInstances = objService.ExecQuery(query)
Instance = objService.InstancesOf(class)
Instance.SetAttribute(0,0,0,"NumLockLed","Disabled")
...I see, you have a point re the instance of BIOSAttributeInterface,
it did not work either so I tried powershell from the Dell doc and that did not work either.
here is the txt from the powershell screen, also attached a screen shot
PS C:\Windows\System32> $BAI = Get-WmiObject -Namespace root/dcim/sysman/biosattributes -Class BIOSAttributeInterface
PS C:\Windows\System32> $BAI ...to show the response
RunspaceId : 8a6bffd0-b09d-49ee-8637-64116023bb70
__GENUS : 2
__CLASS : BIOSAttributeInterface
__SUPERCLASS :
__DYNASTY : BIOSAttributeInterface
__RELPATH : BIOSAttributeInterface.InstanceName="ACPI\\PNP0C14\\WBAT_0"
__PROPERTY_COUNT : 2
__DERIVATION : {}
__SERVER : MV-IT-6T149R3
__NAMESPACE : root\dcim\sysman\biosattributes
__PATH : \\MV-IT-6T149R3\root\dcim\sysman\biosattributes:BIOSAttributeInterface.InstanceName="ACPI\\PNP0C14\\
WBAT_0"
Active : True
InstanceName : ACPI\PNP0C14\WBAT_0
PS C:\Windows\System32> $BAI.SetAttribute(0,0,0,"NumLockLed","Disabled")
>>
InvalidOperation: Method invocation failed because [Deserialized.System.Management.ManagementObject#root\dcim\sysman\biosattributes\BIOSAttributeInterface] does not contain a method named 'SetAttribute'.
PS C:\Windows\System32> $BAI.SetAttribute(0,0,0,"UefiNwStack","Disabled")
InvalidOperation: Method invocation failed because [Deserialized.System.Management.ManagementObject#root\dcim\sysman\biosattributes\BIOSAttributeInterface] does not contain a method named 'SetAttribute'.
PS C:\Windows\System32>
Again, just guessing, but looks like the first parameter of SetAttribute() is either 0 [BIOS PW not set] or 1 [PW is set] although not related to the error(s).
Have you looked at https://www.dell.com/support/kbdoc/en-us/000177240/dell-command-powershell-provider
[EDIT]
Gonna have to look at what PS means by Serialization... I've had several scripts where that was the initial error but meant having to address the 'type' for variables or parameters. But, if you cannot come up with PS code to set attributes no use any PS=>WB conversion attempts. Bummer, since the first attempt seemed to work for you.
Figured I'd throw this out. Supposedly DELL includes PS module with install, but it can be installed manually. There is also PS modules for BIOS get/set. Below is my StdOut WB script adapted. I ran it for my HP with arguments for the more general module, but included commented arguments for the Dell specific provider. While WMI may well be the way to go for your project, at least seeing if PS can get/set attributes.
;Windows BIOS Status
;save as ..\StdOut_BIOS.wbt
;Stan Littlefield 8/26/2024
;==========================================================
Gosub udfs
module = "GetBIOS"
;NOTE: there is also a SetBIOS module available
command = "Get-BIOS -ShowDescription"
;comment above and uncomment next 2 lines for DELL specific Provider
;module = "DellBIOSProvider"
;command = "Get-Item -Path DellSmbios:\Security\IsAdminPasswordSet"
args = $"if (!(Get-Module -ListAvailable -Name |module|)) { Install-Module -Name |module| -Scope CurrentUser -allowclobber -force }
Import-Module |module|
|command|
$"
args = StrReplace(args,"|module|",module)
args = StrReplace(args,"|command|",command)
cmd="Powershell"
msg='BIOS Attributes'
BoxOpen("Running...",cmd:" ":args:@LF:"PLEASE WAIT...MAY TAKE SOME TIME")
TimeDelay(2)
vals = Get_stdout()
vals = StrReplace(vals,'"','')
Message(msg,vals) ;output may look messy
;optional - create output file with links, for further scraping
;FilePut("c:\temp\Defender.txt",vals)
Exit
;==========================================================
:udfs
#DefineSubroutine Get_stdout()
ObjectClrOption("useany","System")
objInfo = ObjectClrNew("System.Diagnostics.ProcessStartInfo")
Output=""
objInfo.FileName = cmd
objInfo.RedirectStandardError = ObjectType("BOOL",@TRUE)
objInfo.RedirectStandardOutput = ObjectType("BOOL",@TRUE)
objInfo.UseShellExecute = ObjectType("BOOL",@FALSE)
objInfo.CreateNoWindow = ObjectType("BOOL",@TRUE)
objInfo.Arguments = args
oProcess = ObjectClrNew("System.Diagnostics.Process")
oProcess.StartInfo = objInfo
BoxShut()
oProcess.Start()
oProcess.WaitForExit()
STDOUT = oProcess.StandardOutput.ReadToEnd()
STDERR = oProcess.StandardError.ReadToEnd()
Output = Output:STDOUT:@CRLF
If STDERR<>""
Output = Output:"STDERR:":STDERR:@CRLF
Endif
oProcess = 0
objInfo = 0
Return (Output)
#EndSubroutine
Return
;==========================================================