Sign in to follow this  
Followers 0
Colyn1337

Automatic Firmware Updates - SQLite & WMI

1 post in this topic

#1 ·  Posted (edited)

#cs -----------------------------------------------------------------------------------------------------------------
Author:
Colyn Via
Script Function:
Query local device WMI info and perform a SQL lookup to check for firmware updates. The SQL database contains
device models, current firmware version, and the path to the update package. This script looks for the firmware
version based on the device model, and then copies the installer to the host drive. The script then performs a
silent install of the firmware update all the while preventing an accidental shutdown. This script has a verbose
log which gets copied to a network location if there's a problem. If it's successful the log writes a single
line to a master log in the same network location reporting it's success. Once the update is complete, the
installer file is deleted, as well as the local log file.
Version Notes:
1.0.03 - Adjusted final write to local log so that the $FirmwareDBResult is written in the log.
1.0.02 - Added processwait() to script to prevent premature script completion
1.0.01 - Added values to BIOSString dump in addition to names
1.0.00 - Initial complete version
#ce -----------------------------------------------------------------------------------------------------------------
#NoTrayIcon
#include 
#include 
; Unless directed otherwise, autoit will do an internet lookup for the driver to use. Later in the code
; the _SQLite_Startup UDF directs the program to get the driver locally. This is why it's important to
; include the driver in the package.
FileInstall("SQLite3.dll", @ScriptDir & "", 1)
Global $FWversion, $Product, $hDB, $hQuery, $aRow, $UpgradeDBResult, $FWversionDBResult, $CheckCurrent
Global $CheckDB, $UpgradeEXE, $SQLQuery1, $SQLQuery2, $PID
Global Const $Timestamp = @MON & "/" & @MDAY & "/" & @YEAR & " " & @HOUR & ":" & @MIN & ":" & @SEC & " "
Global Const $Log = "C:AMTFirmwareLog_" & @ComputerName & ".txt"
Global Const $GlobalLog = 'redactedvProFirmware ResponsesSuccessSucceeded.txt'
Global Const $FirmwareDB = 'redactedvProFirmware.db'
Global Const $GlobalResponse = 'redactedvProFirmware Responses'
; This script was designed to be verbose and log most events. This code creates the log and adds the first line.
FileWriteLine($Log, $Timestamp & "Hello! My name is " & @ComputerName & ". " & @OSVersion & " " & @OSArch & " is how I roll.")
FileWriteLine($Log, $Timestamp & "I'm running script 1.0.03.")
FWversion()
; This function runs a WMI query to get the current AMT firmware version on the device.
Func FWversion()
$objIntelME = ObjGet("winmgmts:" & "." & "rootIntel_ME")
; An error catch must be present here, as AutoIt does not mute COM errors naturally. Without this catch,
; an ugly sounding error will appear to the user. IsObj() is not enough, as it cannot handle a return.
If @error Then
FileWriteLine($Log, $Timestamp & "Intel_ME is not a valid NAMESPACE.")
FileCopy($Log, $GlobalResponse)
FileDelete($Log)
Exit
EndIf
$colIntelME = $objIntelME.ExecQuery("SELECT * FROM ME_System")
; The "Else" of this statement reports back which devices couldn't determine their firmware version.
If IsObj($colIntelME) Then
For $objMEsystem In $colIntelME
$FWversion = $objMEsystem.fwversion
Next
Else
FileWriteLine($Log, $Timestamp & "ME_System query failed.")
FileCopy($Log, $GlobalResponse)
FileDelete($Log)
Exit
EndIf
FileWriteLine($Log, $Timestamp & "Local host vPro firmware lookup result = " & $FWversion)
ConsoleWrite("Local host vPro firmware lookup result = " & $FWversion & @LF)
EndFunc ;==>FWversion
Product()
; This function runs a WMI query to get the current model information for the device.
Func Product()
; Since these variables are used often in general coding practice, they are Local'd instead of
; declared global. When the code finishes this function, it will drop these variables.
Local $x, $y, $prodArray, $aRefine
$objWMI = ObjGet("winmgmts:" & @ComputerName & "rootHPInstrumentedBIOS")
If @error Then
FileWriteLine($Log, $Timestamp & "rootHPInstrumentedBIOS is not a valid NAMESPACE.")
FileCopy($Log, $GlobalResponse)
FileDelete($Log)
Exit
EndIf
$colItems = $objWMI.ExecQuery("SELECT * FROM HPBIOS_BIOSString")
; The "Else" of this block accounts for the possibility that this code might run on a non HP device.
If IsObj($colItems) Then
FileWriteLine($Log, $Timestamp & "Attempting to grab hardware info.")
For $objItems In $colItems
If $objItems.Name = "Notebook Model" Then
$Product = $objItems.Value
FileWriteLine($Log, $Timestamp & "Raw value for " & $objItems.Name & " is " & $Product)
$prodArray = StringSplit($Product, " ")
; BIOS revisions change slightly how the information is presented by WMI. Sometimes it's
; simply the Model number, other times it can be a string of words. For simplicity and
; uniformity, this code strips out just the Model number from the string. This code is
; looking for a word that starts with a number. If HP begins using Model Numbers that
; start with letters, this code will need to be reworked.
For $x = 1 To $prodArray[0]
If StringIsAlpha($prodArray[$x]) Then
Else
; As it turns out, HP in its infinite wisdom decided to, in some cases, put both
; product identifiers in the SAME CIM component value. This confuses the scrip and
; it ends up recording the wrong value. To correct for this, and as the model
; number always starts with a number (currently), I've directed the script to check
; the first character in the string it's wanting to use to see if it's a number
; IsInt means "is it an integer", which in this case, the value is not. AutoIt
; sees it as a string, so Number() is used instead.
FileWriteLine($Log, $Timestamp & "I'm considering using " & $prodArray[$x] & ".")
$aRefine = StringSplit($prodArray[$x], "")
If Number($aRefine[1]) Then
FileWriteLine($Log, $Timestamp & "It turns out that " & $prodArray[$x] & " starts with " & $aRefine[1] & _
" and must therefore be what I'm looking for. Right?")
$Product = ($prodArray[$x])
EndIf
EndIf
Next
ExitLoop
ElseIf $objItems.Name = "Product Name" Then
$Product = $objItems.Value
FileWriteLine($Log, $Timestamp & "Raw value for " & $objItems.Name & " is " & $Product)
$prodArray = StringSplit($Product, " ")
For $x = 1 To $prodArray[0]
If StringIsAlpha($prodArray[$x]) Then
Else
FileWriteLine($Log, $Timestamp & "I'm considering using " & $prodArray[$x] & ".")
$aRefine = StringSplit($prodArray[$x], "")
If Number($aRefine[1]) Then
FileWriteLine($Log, $Timestamp & "It turns out that " & $prodArray[$x] & " starts with " & $aRefine[1] & _
" and must therefore be what I'm looking for. Right?")
$Product = ($prodArray[$x])
EndIf
EndIf
Next
ExitLoop
EndIf
Next
FileWriteLine($Log, $Timestamp & "Finished attempts to grab hardware info.")
; In the event that "Notebook Model" is not the value to read, it helps to see what should be added.
; The following code runs a dump of the contents of HPBIOS_BIOSstring and copies the log to the log directory.
; Later the results of the log can be used to determine what other $objItems.Name might exist.
If $Product = "" Then
FileWriteLine($Log, $Timestamp & "Query (SELECT * FROM HPBIOS_BIOSString) SUCCEEDED! However unable to " & _
"resolve object.name of known variables on " & @ComputerName & ".")
FileWriteLine($Log, "*************** Beginning Dump of HPBIOS_BIOSstring ***************")
For $objItems In $colItems
FileWriteLine($Log, "*** " & $objItems.name & " = " & $objItems.Value)
Next
FileWriteLine($Log, "*************** Done Exporting HPBIOS_BIOSstring ***************")
Sleep(5)
FileCopy($Log, $GlobalResponse)
FileDelete($Log)
Exit
EndIf
Else
FileWriteLine($Log, $Timestamp & "rootHPInstrumentedBIOS is not a valid NAMESPACE on " & @ComputerName & ".")
EndIf
ConsoleWrite("WMI query for Model produced " & $Product & @LF)
EndFunc ;==>Product
If $FWversion = "" Then Exit
If $Product = "" Then Exit
SQL()
; This function names the SQL queries and initializes the SQL engine.
Func SQL()
; SQL Queries
$SQLQuery1 = "SELECT " & '"' & "Update" & '"' & " FROM Lookup WHERE Product=" & '"' & $Product & '"' & ';'
$SQLQuery2 = "SELECT " & '"' & "FWVersion" & '"' & " FROM Lookup WHERE Product=" & '"' & $Product & '"' & ';'
; Check the DB and open it if the script can find it
FileWriteLine($Log, $Timestamp & "Checking to see if " & '"' & $FirmwareDB & '"' & " exists...")
If FileExists($FirmwareDB) Then
FileWriteLine($Log, $Timestamp & "Found it!")
Else
FileWriteLine($Log, $Timestamp & "I can't see it!")
FileCopy($Log, $GlobalResponse)
FileDelete($Log)
Exit
EndIf
_SQLite_Startup("", "", 0)
_SQLite_Open($FirmwareDB)
EndFunc ;==>SQL
Eligibility()
; This function determines the devices eligibility to upgrade, and figures out where to get the update from.
Func Eligibility()
; Since these variables are used often in general coding practice, they are Local'd instead of
; declared global. When the code finishes this function, it will drop these variables.
Local $x, $y, $z, $Proceed, $diff, $exe
_SQLite_Query(-1, $SQLQuery1, $hQuery)
If _SQLite_FetchData($hQuery, $aRow) = $SQLITE_OK Then
Else
ConsoleWrite("Query Failed")
FileWriteLine($Log, $Timestamp & $SQLQuery1 & " FAILED.")
FileCopy($Log, $GlobalResponse)
FileDelete($Log)
_SQLite_QueryFinalize($hQuery)
_SQLite_Close()
_SQLite_Shutdown()
Exit
EndIf
$UpgradeDBResult = $aRow[0]
FileWriteLine($Log, $Timestamp & $SQLQuery1 & " SUCCEEDED.")
_SQLite_QueryFinalize($hQuery)
ConsoleWrite($UpgradeDBResult & @LF)
; Need to get just the name of the update executable for use later.
$exe = StringSplit($UpgradeDBResult, "")
$UpgradeEXE = $exe[($exe[0])]
FileWriteLine($Log, $Timestamp & "The executable needed later is " & $UpgradeEXE & ".")
; Testing purposes - Making my host appear to be a 6550b
;~ $SQLQuery2 = "SELECT " & '"' & "FWVersion" & '"' & " FROM Lookup WHERE Product=" & '"' & "6550b" & '"' & ';'
_SQLite_Query(-1, $SQLQuery2, $hQuery)
If _SQLite_FetchData($hQuery, $aRow) = $SQLITE_OK Then
Else
ConsoleWrite("Query Failed")
FileWriteLine($Log, $Timestamp & $SQLQuery2 & " FAILED.")
FileCopy($Log, $GlobalResponse)
FileDelete($Log)
_SQLite_QueryFinalize($hQuery)
_SQLite_Close()
_SQLite_Shutdown()
Exit
EndIf
$FWversionDBResult = $aRow[0]
FileWriteLine($Log, $Timestamp & $SQLQuery2 & " SUCCEEDED.")
_SQLite_QueryFinalize($hQuery)
ConsoleWrite($FWversionDBResult & @LF)
FileWriteLine($Log, $Timestamp & "Query result was " & $FWversionDBResult)
; Be sure to close down SQL when it's not needed.
_SQLite_Close()
_SQLite_Shutdown()
; Testing purposes - Make my firmware appear older
;~ $FWversion = "6.2.0.1022"
FileWriteLine($Log, $Timestamp & "Comparing firmware versions.")
; So as not to run the risk of destroying the data, the data is copied to new
; variables before be begin to break it apart into arrays.
$CheckCurrent = StringSplit($FWversion, ".")
$CheckDB = StringSplit($FWversionDBResult, ".")
FileWriteLine($Log, $Timestamp & "Splitting firmware strings.")
; This code checks to make sure the two arrays are equal in terms of size.
; If they are not, the code will generate an error. This code also manually
; adjusts either array so that it always matches the larger of the two.
If $CheckDB[0] > $CheckCurrent[0] Then
$diff = ($CheckDB[0] - $CheckCurrent[0])
For $z = 1 To $diff
_ArrayAdd($CheckCurrent, 0)
Next
EndIf
If $CheckDB[0] < $CheckCurrent[0] Then
$diff = ($CheckCurrent[0] - $CheckDB[0])
For $z = 1 To $diff
_ArrayAdd($CheckDB, 0)
Next
EndIf
FileWriteLine($Log, $Timestamp & "Finished comparing stringsplit array sizes, continuing to determine if upgrade is needed.")
; This part is checking to see if the firmware update indicated by the SQL query
; is newer than the current version on the device. If the firmware is current or
; better, the program deletes the log file and closes.
Do
For $x = 1 To $CheckDB[0]
If $CheckDB[$x] > $CheckCurrent[$x] Then
$Proceed = "y"
ExitLoop
ElseIf $CheckDB[$x] < $CheckCurrent[$x] Then
$Proceed = "n"
ExitLoop
ElseIf $CheckDB[$x] = $CheckCurrent[$x] And $x = $CheckDB[0] Then
$Proceed = "n"
ExitLoop
EndIf
Next
Until $Proceed <> ""
If $Proceed = "n" Then
FileDelete($Log)
Exit
EndIf
FileWriteLine($Log, $Timestamp & "Finished comparing firmware versions. Proceeding to UpdateFirmware()")
EndFunc ;==>Eligibility
; $UpgradeDBResult is the path to the firmware update as retrieved by the Eligibility() function
UpdateFirmware()
; This function pulls down the update and executes it. It also writes to the $GlobalLog.
Func UpdateFirmware()
FileWriteLine($Log, $Timestamp & "Attempting to copy " & '"' & $UpgradeDBResult & '"' & " to local drive.")
If FileExists($UpgradeDBResult) Then
FileCopy($UpgradeDBResult, @HomeDrive & "")
Else
FileWriteLine($Log, $Timestamp & "FileExists() check failed. I quit!")
FileCopy($Log, $GlobalResponse)
FileDelete($Log)
Exit
EndIf
FileWriteLine($Log, $Timestamp & "Run command issued for " & @HomeDrive & "" & $UpgradeEXE)
; The -s switch is for silent install
Run(@HomeDrive & "" & $UpgradeEXE & " -s", "", @SW_HIDE)
; Prevent shutdown during firmware update process
ProcessWait($UpgradeEXE, 60)
Do
Run("shutdown /a", @SystemDir, @SW_HIDE)
Sleep(10)
$PID = ProcessExists($UpgradeEXE)
Until $PID = 0
FileWriteLine($GlobalLog, $Timestamp & @ComputerName & " launched " & $UpgradeEXE & " to achieve " & $FWversionDBResult & ".")
EndFunc ;==>UpdateFirmware
FileDelete(@HomeDrive & "" & $UpgradeEXE)
FileDelete($Log)
Exit

Edited by Colyn1337

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  
Followers 0

  • Similar Content

    • nikink
      By nikink
      Hi all,
      I have a bit of code that works on my old Win10 PC, that fails on my new Win10 PC, and I think the only significant difference is the version of Autoit - old PC has 3.3.12, new has 3.3.14.
      I couldn't find anything mentioned in the change logs though, so perhaps I'm wrong.
      Anyway, the code to replicate my issue is:
      Test('username', 'DOMAIN') ; THIS ERRORS: ;Test('localun', 'DOMAIN') ; THIS ERRORS: ;Test(' ', ' ') ; THIS ERRORS: ;Test('', '') ; THIS ERRORS: ;Test('localun', '') ; THIS ERRORS: ;Test('', 'DOMAIN') Func Test($un, $dom) $compName = 'PCNAME' $FullName = '.' $Description = '.' ; get the WIM object $objWMIService = ObjGet("winmgmts:\\" & $compName & "\root\cimv2") ; get default user full name and description $objAccount = $objWMIService.Get("Win32_UserAccount.Name='" & $un & "',Domain='" & $dom & "'") If IsObj($objAccount) Then $FullName = $objAccount.FullName $Description = $objAccount.Description EndIf ConsoleWrite($FullName & @CRLF) ConsoleWrite($Description & @CRLF) Return EndFunc  
      On my old PC this code will output just . and . for each of those line currently commented out. Which is fine.
      On my new PC any of those commented out lines of code cause an error, and the script won't even compile.
      $objAccount = $objWMIService.Get("Win32_UserAccount.Name='" & $un & "',Domain='" & $dom & "'") $objAccount = $objWMIService^ ERROR I'm very much a newb with the WMI stuff and objects, but it looks like the .Get property is failing when either $un or $dom aren't valid in v3.3.14, whereas in 3.3.12 the .Get would fail to return an object, which is then caught by the If statement.
      Am I on track with this? Is there some new/better way to code the example so that 3.3.14 will compile it?
    • Eli_jahbot
      By Eli_jahbot
      My esteemed Autoits I need your help once again.
      I'm trying to figure out how to create a loop that gets 1 value from an array and repeats until each value from the array has been used. I have never used arrays before and I know once I learn more things should get easier for me. 
      Here is what Im trying to do:
      -Have an array of values that determine what application i log into. ex: app1, app2, app3, app4 etc.
      -Have a loop that repeats a process sequentially using each value in the array to finish the process for each app1, app2, app 3 and so forth. I have 30 apps that I need to update on a regular basis and getting this sorted out is what I perceive to be the best way to do it.
      Here is my feeble attempt that obviously fails:
      #include <msgboxconstants.au3>
      #include <Constants.au3>
      #include <array.au3>
      Login()
      Func Login()
          local $array[30] = ["10", "11", "12",etc etc]
          ;;Local $site = InputBox("ERx Site","What site do you want to login as?","","")
          Local $userid = InputBox("ERx Login", "What is your username?", "", "")
          Local $Passwd = InputBox("Security Check", "Enter your UAT password.", "", "*")
      for $1 = 1 to 30(I need to do the same steps in 30 different apps)
      run("Z:launch.exe")
      WinWaitActive("Input")
      Send (Sequential ARRAY VALUE HERE)
      Send("{ENTER}")
      WinWaitActive("window")
      Send($userid)
      Send("{TAB}")
      send($Passwd)
      Send("{ENTER}")
      WinWaitActive("[CLASS:SunAwtDialog]")
      Sleep(500)
      WinClose("Home Page")
      Next
      EndFunc
       
      your help is greatly appreciated.
      Thanks for your time
    • ModemJunki
      By ModemJunki
      Edit: I found out from looking into the post from coffeeturtle that not all motherboards support WMI temperature reading. You have to explore the WMI namespaces for your system!
      I (stupidly) fried a computer. It was an old Zotac small form factor device that was junked at work, so I turned it into a home theater PC.
      But I had put it in my "audio rack", which has glass doors and not very good ventilation. Normally I would open the doors while it was running and I use a media remote which would hibernate the system. At some point, it woke up by itself (probably Windows Update) and did not go to sleep again. Unfortunately this happened during the summer months while I was away on a small holiday and of course the glass doors were closed.
      When I finally noticed the system was on, it was super hot and the fan was at full blast. Dead. No POST, no green light on the mainboard even with a new power supply, old mechanical laptop hard drive gives errors when connected to another device. My next home project will be to make some appropriate ventilation in the audio cabinet.
      For the replacement I bought a used HP ultra small form factor machine and decided to start working on an app to monitor the ambient temperature sensor on the motherboard and shutdown the system if needed. I used some code for smooth label updates from here (needed updating to work with latest AutoIT) and temperature conversion from here (not really needed, only if you want temperatures in something other than C).
      Maybe I will work on this some more and make it configurable with an .INI file or even storing the settings in registry, but since I probably won't I thought I'd put it up as an example of what a non-expert can do with an afternoon of coding and ideas from the community here.
      This uses an ambient temperature sensor populated on HP machines in HP-specific WMI extensions but the WMI query can easily be changed to any available sensor including CPU or GPU.
      The watchdog monitors temperature, warns with S.O.S beeping if the set point is exceeded, and either shuts down if a timeout is reached while the temperatures are high or goes back to monitoring if the temperature goes lower then the set point, and logs events to the Windows application event logs.
      The GUI it puts up is very small at the top center of the screen (very small on a 4k display anyway).
      #requireadmin because of the WMI query.
      A timer for the WMI query because of prior experience using similar functions in WinPE to get model infos from HP WMI bios extensions.
      If you play around with this, please post your fixes/improvements/changes back to this thread.
      Have fun!
      Edit: Updated to show "Unable to query temperature" if the WMI query returns a null
      #AutoIt3Wrapper_Icon=temperature-2-multi-size.ico #RequireAdmin #NoTrayIcon #include <Temperature.au3> #include <FFLabels.au3> #include <GUIConstantsEx.au3> #include <StaticConstants.au3> #include <WindowsConstants.au3> Global $winLogger = "C:\WINDOWS\system32\eventcreate.exe" ; application to use for event logging Global $MessageSource = "HP TempMon" Global $width = 185 Global $height = 15 Global $FontSize = 8 Global $FontFamily = 'Microsoft Sans Serif' Global $normClr = 0xFF000000 Global $warnClr = 0xFF0000 Global $WMInameSpace = "HP_BIOSNumericSensor" ;~ Global $WMIReadSensor = "Chassis Thermal Index" ; HP 8300 Global $WMIReadSensor = "System Ambient Temperature" ; HP Z400 Global $warnTmp = 46.1111111111 ; degrees C ;~ Global $warnTmp = 24 ; degrees C for testing Global $ovrtmpTime = 5 ; in minutes Global $hGUI = GUICreate("Board Temperature", $width, $height, -1, 0, BitOR($WS_SYSMENU, $WS_POPUP), BitOR($WS_EX_TOPMOST, $WS_EX_WINDOWEDGE, $WS_EX_TOOLWINDOW)) Global $lb1 = _GUICtrlFFLabel_Create($hGUI, "", -1, -1, $width, $height, 8, -1, 0, 1, $normClr) GUISetState(@SW_SHOW) _TempSenseLoop() Func _TempSenseLoop() While 1 Sleep(250) $nMsg = GUIGetMsg() Switch $nMsg Case $GUI_EVENT_CLOSE GUIDelete($hGUI) Return Case Else $s_ambTempC = _doQueryHPNumSens(5, $WMInameSpace, $WMIReadSensor, "100") ; + 100 Select Case $s_ambTempC = "" _GUICtrlFFLabel_SetTextColor($lb1, $normClr) _GUICtrlFFLabel_SetData($lb1, "Unable to query temperature") Case $s_ambTempC < $warnTmp _GUICtrlFFLabel_SetTextColor($lb1, $normClr) _GUICtrlFFLabel_SetData($lb1, "Board temperature: " & $s_ambTempC & "C" & "/" & Round(_CelsiusToFahrenheit($s_ambTempC), 0) & "F") Case Else _GUICtrlFFLabel_SetTextColor($lb1, $warnClr) _GUICtrlFFLabel_SetData($lb1, "Board temperature: " & $s_ambTempC & "C" & "/" & Round(_CelsiusToFahrenheit($s_ambTempC), 0) & "F") _doLog("System ambient temperature has exceeded " & $warnTmp & "C.", "WARN", $MessageSource) _AlarmMonitor($ovrtmpTime, $warnTmp) EndSelect EndSwitch WEnd EndFunc ;==>_TempSenseLoop Func _AlarmMonitor($min, $tmp) Local $Shutdown = 1 Local $s_ambTemp Local $freq = 3500 Local $shrt = 200 Local $long = 500 Local $timer = TimerInit() Local $wait = 1000 * ($min * 60) While TimerDiff($timer) < $wait $s_ambTemp = _doQueryHPNumSens(5, $WMInameSpace, $WMIReadSensor, "100") ; + 100 If $s_ambTemp >= $tmp Then _GUICtrlFFLabel_SetData($lb1, "WARNING! OVERTEMP!") Beep($freq, $shrt) Beep($freq, $shrt) Beep($freq, $shrt) Sleep(250) Beep($freq, $long) Beep($freq, $long) Beep($freq, $long) Sleep(250) Beep($freq, $shrt) Beep($freq, $shrt) Beep($freq, $shrt) _GUICtrlFFLabel_SetData($lb1, "Board temperature: " & $s_ambTemp & "C" & "/" & _CelsiusToFahrenheit($s_ambTemp) & "F") Sleep(2000) ElseIf $s_ambTemp < $tmp Then $Shutdown = 0 ExitLoop EndIf WEnd If $Shutdown = 1 Then _doLog("The system is shutting down due to overtemperature conditions. The temperature at the time of shutdown was " & $s_ambTemp & "C" & "/" & _CelsiusToFahrenheit($s_ambTemp) & "F", "ERRR", $MessageSource) Shutdown(24) ElseIf $Shutdown = 0 Then _doLog("System ambient temperature has been reduced below " & $warnTmp & "C.", "INFO", $MessageSource) EndIf EndFunc ;==>_AlarmMonitor Func _doQueryHPNumSens($min, $class, $name, $sleep) ; $sleep = milliseconds Local $s_tempReading = "" Local $s_HPBiosWMIService = "winmgmts:\\" & @ComputerName & "\Root\HP\InstrumentedBIOS" Local $objHPBiosWMIService = ObjGet($s_HPBiosWMIService) Local $s_biosQuery = $objHPBiosWMIService.ExecQuery("select * from " & $class & " where Name='" & $name & "'") $timer = TimerInit() ; we may need to wait for the HP WMI extensions to enumerate in WMI, in WinPE this takes some minutes. $wait = 1000 * ($min * 60) If Not IsObj($s_biosQuery) Then ; we do need to wait, put up a splash screen $s_WMISplash = 1 SplashTextOn("WMI", "Probing WMI (up to 10 minutes)...", 300, 50, -1, -1, 1) Sleep(1000) While TimerDiff($timer) < $wait Sleep(500) $objHPBiosWMIService = ObjGet($s_HPBiosWMIService) If IsObj($objHPBiosWMIService) Then Sleep(500) $colProdName = $s_biosQuery If IsObj($colProdName) Then For $oItem In $colProdName $s_tempReading = $oItem.CurrentReading Next EndIf EndIf WEnd ElseIf IsObj($s_biosQuery) Then ConsoleWrite($s_biosQuery & @CRLF) For $oItem In $s_biosQuery $s_tempReading = $oItem.CurrentReading Next Else $s_tempReading = 0 EndIf Sleep($sleep) Return $s_tempReading EndFunc ;==>_doQueryHPNumSens Func _doLog($message, $type, $msgsrc) Select Case $type = "INFO" $logTyp = "INFORMATION" Case $type = "WARN" $logTyp = "WARNING" Case $type = "ERRR" $logTyp = "ERROR" EndSelect If FileExists($winLogger) Then RunWait(@ComSpec & " /c " & $winLogger & " /L Application /T " & $logTyp & " /SO " & Chr(34) & $msgsrc & Chr(34) & " /ID 1000 /D " & Chr(34) & $message & Chr(34), "", @SW_HIDE) EndIf EndFunc ;==>_doLog  
       
       
      Temperature.au3
      FFLabels.au3
      HP_Temp.au3
    • 9252Survive
      By 9252Survive
      Hi All, 
       
      I am fairly new to AutoIT and I am still trying to learn, I have been using _FileListToArray to list all the files with a particular extension in an array and then loop through it for operation  (   For $i = 1 To UBound($FileArray) - 1).
      So far this has been working fine. But I am not able to figure out a problem that I have; what if I have 50 files but I only want to loop through first 10 files and then next ten and so on?  Or rather I should say, how I can I only feed max 10 files to the array at a time when I do _FileListToArray regardless of the total number of files in the folder?
      Any insight/help will be much appreciated 
    • ModemJunki
      By ModemJunki
      Hello,
      In Windows 10 PowerShell, one can do this to change the metric for a NIC in Windows 10:
      Get-NetAdapter | Where-Object -FilterScript {$_.InterfaceAlias -Eq "Ethernet 2"} | Set-NetIPInterface -InterfaceMetric 2 I know I can script the above PowerShell line (and it works!), but I wanted to try something I hadn't done before after looking into jguinch's most excellent Network configuration UDF. I wanted to make use of the SetIPConnectionMetric method in the WMI classes. There is an example VBscript here but this is not for Windows 10. Using AutoIT would also give better control over capturing error return codes than with PowerShell.
      But I cannot get my script to work! The return from SetIPConnectionMetric() is 0, which would indicate success. Yet the change does not happen. I also tried WMI methods using .put_ but this fails.
      Anyone more experienced than I have ideas to make this work?
      #RequireAdmin _SetNicInterfaceMetric2("Ethernet 2", "2") Func _SetNicInterfaceMetric2($NIC_NAME, $METRIC) Local $s_setIndx = 0 $objWMIService = ObjGet("winmgmts:{impersonationLevel = impersonate}!\\" & "." & "\root\cimv2") $colNICItems = $objWMIService.ExecQuery("SELECT * FROM Win32_NetworkAdapter WHERE NetConnectionID = '" & $NIC_NAME & "'", "WQL") If IsObj($colNICItems) Then For $objItem In $colNICItems $s_nicIndex = $objItem.Index Next ConsoleWrite("SELECT * FROM Win32_NetworkAdapterConfiguration WHERE Index = '" & $s_nicIndex & "'" & @CRLF) $colNAC = $objWMIService.ExecQuery("SELECT * FROM Win32_NetworkAdapterConfiguration WHERE Index = '" & $s_nicIndex & "'", "WQL") If IsObj($colNAC) Then For $objNetCard In $colNAC If $METRIC <> $objNetCard.IPConnectionMetric Then ConsoleWrite("Metric was set to " & $objNetCard.IPConnectionMetric & ". Setting to " & $METRIC & "." & @CRLF) $s_isSet = $objNetCard.SetIPConnectionMetric($METRIC) ConsoleWrite("SetIPConnectionMetric Result = " & $s_isSet & @CRLF) Else ConsoleWrite("Metric is already set to " & $METRIC & @CRLF) EndIf Next EndIf EndIf EndFunc ;==>_SetNicInterfaceMetric2