Jump to content

Recommended Posts

Posted

Do I need to put an error check after each selection just like the one after the function _ComputerGetBIOS($BIOS)? and do I need a variable returned ($BIOS) in the example or ?

#comments-start

Description:
    This script reads a 3 column CSV, presents the user with a selection from 1st column,
        then subselections from second column that meet the criteria of the 1st colunmn.
        The third column is used as a final subdir for drive mapping.
        WMI is used to determine workstation serial# which is used as part of subdir
        creation for the Ghost backup image.
    Currently used with Ghost Solution Suite 2.5 (aka Ghost 11.5 Corporate) and has been successfully run from
       a Win7PE bootable USB (with WMI support).
 Kudos:
    WMI code and corresponding functions via Jarvis J. Stubblefield (JSThePatriot) http://www.vortexrevolutions.com/
    **Special thanks to BrewManNH from the forums on autoitscript.com and also to Melba23 for her prior posts of
    which I grabbed a code snippet for the combo selection and checking for closure of combos.

Data Format: Building, Lab, Network_Path_to_Ghost_Image_Storage

Example Data:
[indent=1]Building 2,Facilities,[none][/indent]
[indent=1]Building 5,PC Optimization Team,Labinstall_ghost[/indent]
[indent=1]Building 8,Containers Lab,B8_Containers_GHOST[/indent]
[indent=1]Building 8,Environmental Contamination Test Lab,B8_Char_GHOST[/indent]
[indent=1]Building 8,Intermediate Assembly Lab (IA),B8_IA_GHOST[/indent]
#comments-end

#include <buttonconstants.au3>
#include <comboconstants.au3>
#include <guiconstantsex.au3>
#include <guicombobox.au3>
#include <windowsconstants.au3>
#include <file.au3>
#include <array.au3>

#region WMI Global Variables and Constants
If Not(IsDeclared("$cI_CompName")) Then
Global    $cI_CompName = @ComputerName
EndIf
Global Const $cI_VersionInfo        = "00.03.08"
Global Const $cI_aName                = 0, _
             $cI_aDesc                = 4
Global    $wbemFlagReturnImmediately    = 0x10, _    ;DO NOT CHANGE
$wbemFlagForwardOnly        = 0x20                ;DO NOT CHANGE
Global    $ERR_NO_INFO                = "Array contains no information", _
        $ERR_NOT_OBJ                = "$colItems isnt an object"
Global $BIOS
#endregion WMI Global Variables and Constants

Do ; loop around the whole pgm so user can 'restart'
    $fName = @ScriptDir & "\" & "data.csv" ; data file name
    Global $numCols = 3
    Global $numRows = UBound(StringRegExp(FileRead($fName), ".+(?=\v+|$)", 3))
    Global $array[$numRows][$numCols]
    Global $sNetPath
    Global $defPCName="NoName"
    Global $priorbld = ""
    Global $sDrive = "G:"
    Global $Numlabs = 0
    Global $basedir = "\\site-it-fs\root\cv-labsfs\ghost\"
    Global $sLab_Old = "Select Lab", $sBldg_Old = "Select Building"
    Global $today = @YEAR & @MON & @MDAY
    Global $RequestExit = 0

    _ComputerGetBIOS($BIOS)
    If @error Then
        $error = @error
        $extended = @extended
        Switch $extended
            Case 1
                _ErrorMsg($ERR_NO_INFO)
            Case 2
                _ErrorMsg($ERR_NOT_OBJ)
        EndSwitch
    EndIf
    Global $serial = $BIOS[1][16]
    ConsoleWrite("numRows= " & $numRows & ", NumCols= " & $numCols & @CRLF)

    _ReadCSV()

    $frmMain = GUICreate("Lab Ghost", 525, 200)
    $cboBldg = GUICtrlCreateCombo("", 15, 30, 145, 25, BitOR($GUI_SS_DEFAULT_COMBO, $CBS_SIMPLE, $WS_HSCROLL))
    $cboLab = GUICtrlCreateCombo("", 15, 60, 145, 25, BitOR($GUI_SS_DEFAULT_COMBO, $CBS_SIMPLE, $WS_HSCROLL))
    GUICtrlSetState(-1, $GUI_HIDE)
    $cboNetPath = GUICtrlCreateCombo("", 180, 80, 145, 25, BitOR($GUI_SS_DEFAULT_COMBO, $CBS_SIMPLE, $WS_HSCROLL))
    GUICtrlSetState(-1, $GUI_HIDE)
    GUICtrlCreateLabel ("PC Name:", 15, 100, 150, 20)
    Global $iPcName = GUICtrlCreateInput ($defPCName, 15, 120, 150, 20)
    GUICtrlSetState(-1, $GUI_SHOW)
    $btnNextLabel = "OK"
    $btnNext = GUICtrlCreateButton($btnNextLabel, 380, 100, 75, 25)
    GUICtrlSetState(-1, $GUI_HIDE)
    $btnAbort = GUICtrlCreateButton("Exit", 460, 100, 60)
    $Group1 = GUICtrlCreateGroup("          Selected Settings           ", 175, 8, 177, 177, -1, BitOR($WS_EX_TRANSPARENT, $WS_EX_CLIENTEDGE))
    GUICtrlCreateLabel("____________________________",175,15)
    GUICtrlCreateLabel("Building: ", 180, 40, 145, 25)
    GUICtrlCreateLabel("Lab: ", 180, 70, 145, 25)
    GUICtrlCreateLabel("Serial:  " & $serial, 180, 150, 145, 25)
    GUICtrlCreateLabel("Date:    " & $today, 180, 170, 145, 25)
    GUICtrlSetState(-1, $GUI_SHOW)
    GUISetState()

    _PopulateBuilding()
    While 1
        $sLab = GUICtrlRead($cboLab)
        If $sLab <> $sLab_Old And _GUICtrlComboBox_GetDroppedState($cboLab) = False Then
            $sLab_Old = $sLab
        EndIf
        $sBldg = GUICtrlRead($cboBldg)
    
        If $sBldg <> $sBldg_Old And _GUICtrlComboBox_GetDroppedState($cboBldg) = False Then ; ; If combo has changed AND closed.  If you don't check for closure, the code processes as the mouse highlights the options in the dropdown.
         $sBldg_Old = $sBldg ;Reset the current text to prevent flicker from constant redrawing
            _PopulateLab()
        EndIf

        $nMsg = GUIGetMsg()
        Switch $nMsg
            Case $GUI_EVENT_CLOSE
                ExitLoop
            Case $btnAbort
                $RequestExit=1
                ExitLoop
            Case $cboBldg    ; Building selected so enable/change to next combo which is $cboLab
             GUICtrlSetState($cboBldg, $GUI_HIDE)
                GUICtrlCreateLabel($sBldg, 225, 40, 145, 25)
                GUICtrlSetState($cboLab, $GUI_SHOW)
            Case $btnNext
                ;_FinalInputChecks - function could be created for final checks
                $sPcName=GUICtrlRead ($iPcName)
                If $sNetPath = "[None]" Then
                    MsgBox(262144+16,"Error", "We do not have a CURRENT Ghost share documented. " & @CRLF & @CRLF & "Please Advise your lab manager to contact the " & @CRLF & "PC Installs Team for updates")
                    $RequestExit=1
                    ExitLoop
                ElseIf $sPcName=$defPCName Then
                    MsgBox(262144+48,"Error","Missing PC Name (ie: pwax008)" & @CRLF)
                    ExitLoop
                EndIf
                $qVerify = msgbox(68,"Verify","Is This Correct?" & @CRLF & @CRLF & "Ghost Share: " & $sNetPath & @CRLF & $sBldg & @CRLF & $sLab & @CRLF & "Serial: " & $serial & @CRLF & "PC Name: " & $sPcName)
                if $qVerify<>6 Then Exitloop
                DriveMapAdd("G:", $basedir & $sNetPath, 8)
                ConsoleWrite("Map should be: G:\" & $basedir & $sNetPath & @CRLF)
             _CreateFolders()
                _GhostIt()
                ConsoleWrite("Error (0=none): " & @error & @CRLF & "Done for now")
            Case $cboLab
                ; Both Selections are made so get network share, and show button to continue
                _GetNetPath()
                GUICtrlCreateLabel("Ghost Share: " & $sNetPath, 180, 100, 145, 25)
                GUICtrlSetState(-1, $GUI_SHOW)
                GUICtrlSetState($cboLab, $GUI_HIDE)
                GUICtrlCreateLabel($sLab, 225, 70, 145, 25)
                GUICtrlSetState(-1, $GUI_SHOW)
                GUICtrlSetState($btnNext, $GUI_SHOW)
        EndSwitch
    WEnd
GUIDelete() ; avoid duplicate gui's
Until $RequestExit = 1 ; restart

; ***************
; ** FUNCTIONS **
; ***************
Func _ReadCSV()
    ConsoleWrite("Reading CSV: " & $fName & @CRLF)
    For $j = 1 To $numCols
        For $i = 1 To $numRows
            $lineRead = FileReadLine($fName, $i)
            $splitLineRead = StringSplit($lineRead, ",", 2)
            $array[$i - 1][$j - 1] = $splitLineRead[$j - 1]
        Next
    Next
EndFunc   ;==>_ReadCSV
Func _PopulateBuilding()
    ConsoleWrite("*********Populating Building ComboBox" & @CRLF)
    For $i = 1 To $numRows
        If $priorbld <> $array[$i - 1][0] Then
            GUICtrlSetData($cboBldg, $array[$i - 1][0] & "|")
            $priorbld = $array[$i - 1][0]
        EndIf
    Next
EndFunc   ;==>_PopulateBuilding
Func _PopulateLab()
    ConsoleWrite("*********Populating Lab ComboBox" & @CRLF) ; how can this be fixed to not show this more than once in the console?
    For $i = 1 To $numRows
        If $array[$i - 1][0] = $sBldg Then
            GUICtrlSetData($cboLab, $array[$i - 1][1] & "|")
            GUICtrlSetData($cboNetPath, $array[$i - 1][2] & "|")
            ConsoleWrite("$cboNetPath - $array[" & $i - 1 & "] [1] =" & $array[$i - 1][1] & " -- $array[" & $i - 1 & "][2]=" & $array[$i - 1][2] & @CRLF)
            $Numlabs = $Numlabs + 1
        EndIf
    Next
EndFunc   ;==>_PopulateLab

Func _GetNetPath()
    ConsoleWrite("*********Getting Network Path" & @CRLF)
    For $i = 1 To $numRows
        ConsoleWrite("Chceking " & $sBldg & "," & $sLab & "=>  " & $array[$i - 1][0] & "," & $array[$i - 1][1] & "," & $array[$i - 1][2] & "  ")
        If ($array[$i - 1][0] = $sBldg) And ($array[$i - 1][1] = $sLab) Then
            $sNetPath = $array[$i - 1][2]
            ConsoleWrite(" << == MATCH")
            ExitLoop
        EndIf
        ConsoleWrite(@CRLF)
    Next
    ConsoleWrite(" - Selected Networkpath for Lab: " & $array[$i - 1][1] & " is -> " & $array[$i - 1][2] & @CRLF)
EndFunc   ;==>_GetNetPath

Func _CreateFolders()
    ;Local $sFldr = "G:\" & $today & "-" & $serial & "\" & $serial
    Global $sFldr = "G:\" & $today & "-" & $serial
    If DirGetSize($sFldr, 2) = -1 And DirGetSize($sDrive, 2) >= 0 Then ; successful map
        DirCreate($sFldr)
        Else
        MsgBox(48, "Error", "Unable to Map the drive. Exiting...")
        Exit
    EndIf
EndFunc   ;==>_CreateFolders

Func _GhostIt()
    Local $val = RunWait(@ComSpec & " /c " & "ghost32.exe -clone,mode=create,src=1,dst=" & $sDrive & "\" & $today & "-" & $serial & "\" & $sPcName & ".gho -split=2048 -batch -sure", "y:\programs\ghost32\", @SW_MAXIMIZE)
    If $val <> 0 Then
        MsgBox(0, "Error", "Exit Code:", $val)
    Else
        Local $explorer = RunWait("explorer /root, " & $sFldr)
        Local $handle = WinGetHandle($explorer)
        MsgBox(262144, "Completed.", "Windows Explorer has been opened to view " & $sFldr & @CRLF & "Click ok to close window and exit")
        WinClose($handle)
    EndIf
EndFunc   ;==>_GhostIt

Func _ComputerGetBIOS(ByRef $aBIOSInfo)
    Local $colItems, $objWMIService, $objItem
    Dim $aBIOSInfo[1][25], $i = 1

    $objWMIService = ObjGet("winmgmts:\\" & $cI_CompName & "\root\CIMV2")
    $colItems = $objWMIService.ExecQuery("SELECT * FROM Win32_BIOS", "WQL", $wbemFlagReturnImmediately + $wbemFlagForwardOnly)

    If IsObj($colItems) Then
        For $objItem In $colItems
            ReDim $aBIOSInfo[UBound($aBIOSInfo) + 1][25]
            $aBIOSInfo[$i][0] = $objItem.Name
            $aBIOSInfo[$i][1] = $objItem.Status
            $aBIOSInfo[$i][2] = $objItem.BiosCharacteristics(0)
            $aBIOSInfo[$i][3] = $objItem.BIOSVersion(0)
            $aBIOSInfo[$i][4] = $objItem.Description
            $aBIOSInfo[$i][5] = $objItem.BuildNumber
            $aBIOSInfo[$i][6] = $objItem.CodeSet
            $aBIOSInfo[$i][7] = $objItem.CurrentLanguage
            $aBIOSInfo[$i][8] = $objItem.IdentificationCode
            $aBIOSInfo[$i][9] = $objItem.InstallableLanguages
            $aBIOSInfo[$i][10] = $objItem.LanguageEdition
            $aBIOSInfo[$i][11] = $objItem.ListOfLanguages(0)
            $aBIOSInfo[$i][12] = $objItem.Manufacturer
            $aBIOSInfo[$i][13] = $objItem.OtherTargetOS
            $aBIOSInfo[$i][14] = $objItem.PrimaryBIOS
            $aBIOSInfo[$i][15] = __StringToDate($objItem.ReleaseDate)
            $aBIOSInfo[$i][16] = $objItem.SerialNumber
            $aBIOSInfo[$i][17] = $objItem.SMBIOSBIOSVersion
            $aBIOSInfo[$i][18] = $objItem.SMBIOSMajorVersion
            $aBIOSInfo[$i][19] = $objItem.SMBIOSMinorVersion
            $aBIOSInfo[$i][20] = $objItem.SMBIOSPresent
            $aBIOSInfo[$i][21] = $objItem.SoftwareElementID
            $aBIOSInfo[$i][22] = $objItem.SoftwareElementState
            $aBIOSInfo[$i][23] = $objItem.TargetOperatingSystem
            $aBIOSInfo[$i][24] = $objItem.Version
            $i += 1
        Next
        $aBIOSInfo[0][0] = UBound($aBIOSInfo) - 1
        If $aBIOSInfo[0][0] < 1 Then
            SetError(1, 1, 0)
        EndIf
    Else
        SetError(1, 2, 0)
    EndIf
EndFunc   ;==>_ComputerGetBIOS

Func _ErrorMsg($message, $time = 0)
    MsgBox(48 + 262144, "Error!", $message, $time)
EndFunc   ;==>_ErrorMsg

#region Internal Functions
; **********************************************************************************
; Internal Functions with names starting with two underscores will not be documented
; as user functions.
; **********************************************************************************
Func __StringVersion()
    Return $cI_VersionInfo
EndFunc   ;==>__StringVersion

Func __StringToDate($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   ;==>__StringToDate
#endregion Internal Functions

Posted

If the variable is global or passed with byref it doesn't need to be returned. It is best practice to use @error, but if it works, is it necessary? In your function, @error resets at the beginning of a function, so it would always return false.

Messing with @error is best practice, and is usually most useful for exiting loops, ie Do something until you can no longer do it.

"If a function can set the @error flag, you should always check it before using a return value - if @error indicates an error then the function return value is generally undefined...

@error is always set to 0 when entering in a function."

autoit help>function reference>function notes

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
×
×
  • Create New...