Jump to content

StdoutRead weirdness: question


Recommended Posts

OK, the odd stuff seems to happen to me. Not sure if this belongs here or in the deployment forum.

The Question: Why would the console output results from a command-line tool need to know the working dir on one system but not the other?

Though in the end I solved the issue I still am not understanding why StdoutRead seems to behave differently as I describe below.

Preamble: Windows 10 image deployment to two different HP workstation hardware platforms. After deployment set up some disk space using Intel RAID. I script the Intel RSTe client (Intel® Rapid Storage Technology enterprise). Same version of the RSTe client and same storage controller hardware (Intel C600+/C220+ series chipset SATA RAID controller). The only difference is in the driver - one system has 4.2.0.1136 and the other has 5.2.0.1194, but even after I update the older driver the anomaly persists. There are of course other differences - the older system has different CPUs (Xeon E5-2620 vs Xeon Silver 4108), different chipsets, different SMBIOS, etc..). Both have Nvidia Quadro cards with driver 385.90, but the older has 3x P2000 cards and the newer has 3x Quadro M4000 and a Quadro K1200.

To script RAID creation and maintenance I have a function that uses StdoutRead with Intels command line client tool "rstcli64.exe".

On the older system, the below call to StdoutRead fails. On the newer system, it works. This only started happening on the older hardware when I updated the Windows version 1607 image to build 14393.2189 (but the Windows image used is the same for both hardware targets).

$s_DoRST = Run(@ComSpec & " /c " & $s_RSTcmd, "", @SW_HIDE, $STDERR_CHILD + $STDOUT_CHILD)

But if I change it to use @ScriptDir as the working dir, it works for both systems.

$s_DoRST = Run(@ComSpec & " /c " & $s_RSTcmd, @ScriptDir, @SW_HIDE, $STDERR_CHILD + $STDOUT_CHILD)

 The code below is the one that works on both systems (hint: the comment " ; this only deals with one device" is because I've no hardware with more than one ATAPI device to test with).

$s_RSTExe = ".\rstcli64.exe" ; for production (compiled executable)
; #FUNCTION# ====================================================================================================================
; Name ..........: GetDiskInfoFromRSTE()
; Description ...: Queries for hard disks attached to the controller
; Syntax ........: GetDiskInfoFromRSTE()
; Parameters ....: None
; Return value...: An array of attached hard disk datas from the RST command line tool without ATAPI devices such as optical drives
; ===============================================================================================================================
Func _GetDiskInfoFromRSTE()
    Local $s_RSTcmd = $s_RSTExe & " -I -d"
    Local $s_DoRST, $a_RSTDisksTemp, $s_rawdata, $numDISK = 0
    If $Debug <> 0 Then ConsoleWrite("Get disk info: " & $s_RSTcmd & @CRLF) ; useful during dev but cannot be used if #requireadmin
    $s_DoRST = Run(@ComSpec & " /c " & $s_RSTcmd, @ScriptDir, @SW_HIDE, $STDERR_CHILD + $STDOUT_CHILD)

    ProcessWaitClose($s_DoRST)
    $s_rawdata = StdoutRead($s_DoRST)
    $a_RSTDisksTemp = StringSplit($s_rawdata, @CRLF)

    For $i = $a_RSTDisksTemp[0] To 1 Step -1 ; since we are deleting items, we have to go backwards through the array
        If $a_RSTDisksTemp[$i] = "" Or $a_RSTDisksTemp[$i] = "--DISK INFORMATION--" Then
            _ArrayDelete($a_RSTDisksTemp, $i)
        EndIf
    Next
    $a_RSTDisksTemp[0] = UBound($a_RSTDisksTemp)

    If IsArray($a_RSTDisksTemp) Then
        For $j = $a_RSTDisksTemp[0] - 1 To 1 Step -1 ; we need to remove the ATAPI device(s), since we delete we have to step through in reverse
            If StringInStr($a_RSTDisksTemp[$j], "Disk Type:         SATA") Then
                $numDISK = $numDISK + 1
            EndIf
        Next
        For $j = $a_RSTDisksTemp[0] - 1 To 1 Step -1 ; we need to remove the ATAPI device(s), since we delete we have to step through in reverse
            If StringInStr($a_RSTDisksTemp[$j], "ATAPI") Then ; we have to delete the ID entry BEFORE and AFTER the ATAPI entry to remove the ATAPI device (always delete from the bottom up!).
                _ArrayDelete($a_RSTDisksTemp, $j + 1) ; delete entry below
                _ArrayDelete($a_RSTDisksTemp, $j) ; delete entry
                _ArrayDelete($a_RSTDisksTemp, $j - 1) ; delete entry above
                ExitLoop ; this only deals with one device. If there were more we would need to capture all ATAPI device ID locations into another array then delete the original array entries based on the index numbers in the new array.
            EndIf
        Next
        $a_RSTDisksTemp[0] = UBound($a_RSTDisksTemp)
        If $a_RSTDisksTemp[0] <> 1 Then
            If $Debug <> 0 Then ConsoleWrite("Found " & $numDISK & " disk(s) attached to controller." & @CRLF)
            _infoLog("_GetDiskInfoFromRSTE() found " & $numDISK & " disk(s) attached to controller.", $msgSource)
        Else
            If $Debug <> 0 Then ConsoleWrite("No disks found to be attached to controller." & @CRLF)
            _infoLog("No disks found to be attached to controller.", $msgSource)
        EndIf
    Else
        If $Debug <> 0 Then ConsoleWrite("Unable to query RAID controller. Check hardware and version of RST client software." & @CRLF)
        _errorLog("Unable to query RAID controller. Check hardware.", $msgSource)
        Exit
    EndIf
    Return $a_RSTDisksTemp
EndFunc   ;==>_GetDiskInfoFromRSTE

 

Always carry a towel.

Link to comment
Share on other sites

Haven't read through your script but off the top of my head:

Using "" for working directory will make the default working directory: C:\Windows\System32 (normally where cmd.exe exists")

$s_DoRST = Run(@ComSpec & " /c " & $s_RSTcmd, "", @SW_HIDE, $STDERR_CHILD + $STDOUT_CHILD)

Using @ScriptDir will of course point to your script directory where the executable is.

 

Link to comment
Share on other sites

On 6/8/2018 at 8:07 PM, Subz said:

Haven't read through your script but off the top of my head:

Using "" for working directory will make the default working directory: C:\Windows\System32 (normally where cmd.exe exists")

$s_DoRST = Run(@ComSpec & " /c " & $s_RSTcmd, "", @SW_HIDE, $STDERR_CHILD + $STDOUT_CHILD)

Using @ScriptDir will of course point to your script directory where the executable is.

 

Hmm - ok. That means my old script was sloppy coding. :sweating:

Still a mystery why it only stopped working when I updated Windows to the new version though. :blink:

Always carry a towel.

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...