How to fix a Barcode scanner not working on CF-H2 Toughbook laptop

By | February 7, 2014
Share

H2BarcodeScanner

The Barcode module on the CF-H2 is hard-coded to use COM3. In some cases, this port is occupied by another device, which are soft assignment to COM3 (can be re-assigned to another port). In those cases, the Barcode scanner does not work.  Here is a way to address this issue via a script/batch.

Download Links:

Com3Fix-x64.zip: https://panaconsulting.egnyte.com/h-s/20140207/46IDZOYT7r
Com3Fix-x86.zip: https://panaconsulting.egnyte.com/h-s/20140207/DkjJJy8jSk

Source Code of Batch Script (GitHub Link):

@echo off
If "%PROCESSOR_ARCHITECTURE%" EQU "x86" (
If exist "%SystemRoot%\SysWOW64" (
"%SystemRoot%\sysnative\cmd.exe" /C "%~dpnx0" %1 %2 %3 %4 %5 %6 %7 %8 %9
exit
)
)

cd /d "%~dp0"

REM devcon.exe pulled from "GRMWDK_EN_7600_1.ISO" (WDK)
REM Perform Devcon Remove on AMT device.
"%~dp0devcon.exe" remove "PCI\VEN_8086&DEV_1C3D"

REM Perform Devcon Remove of Serial to USB device
"%~dp0devcon.exe" remove "USB\VID_10C4&PID_EA60*"
"%~dp0devcon.exe" remove "USB\VID_10C4&PID_EA70*"
REM "%~dp0devcon-x86.exe" remove "PCI\VEN_8086&DEV_1C3D"

REM Import Reg that forces Com3 to inUse state.
"%WinDir%\system32\reg.exe" import "%~dp0COM3-InUse.reg"

REM Timeout for 5 seconds to allow device to be fully removed.
timeout /T 5

REM Perform Device Scan to re-Discover AMT device.
"%~dp0devcon.exe" rescan

 

Steps taken by script to fix issue with Com3 conflict:

  1. Utilize devcon.exe to “remove” the device that is occupying Com3, the port hard tied to the barcode scanner.
  2. Import the provided COM3-InUse.REG to force Windows 7 to label Com3 as “InUse”.
  3. Delay the script to allow the system time to fully execute step 1(remove device).
  4. Lately, again utilize devcon.exe to perform a “RESCAN” to pull back any removed devices, which should now assign itself to a different ComPort.

 

/BG

How to set the 2D Barcode Emulator to “Always On” a FZ-G1 Toughpad via a script or batch

By | February 5, 2014
Share

By Default, the G1’s Barcode Emulator “Always On” setting is is set to disabled, this decision was made to save on battery power. When needed the user must turn it on, which in essence turning it on does so forever for the logged on user.

If you are baking this utility into your CORE image, you can easily turn on the emulator under the Administrator profile and set the “<CopyProfile>” setting to “True” in your unattend.xml to force the settings to take effect for all future produced accounts on the system.

However, if you are using a thin or hybrid image strategy, you would need to set this setting after the machine is detected as a FZ-G1A.

To forcibly instruct the emulator to start on start-up, the best method is to use the Panasonic Barcode Tools (Configuration Utility and Setting Utility).

  1. Download and install the Barcode Configuration Utility (Download Page) on any machine, could even be a virtual machine.
  2. Open the Configuration utility and select the top radio button “2D Barcode Reader..”.

  3. Click on the “Barcode Software Tool” tab.
  4. Check the “Connection to Barcode (Always-On)” checkbox and change the drop-down to “Enable”.

  5. Click on File and Save a .INI file.

  6. Download and Install the “2D Barcode Setting Utility” (Download Here) on the target machine (G1 Toughpad).
  7. Lastly, run the utility with the created .INI as the only argument.

/BG

PowerShell Script to Query Wireless Modem and pull Asset Information.

By | February 3, 2014
Share

Pulling a Wireless WAN Modem’s information while in the field is a daunting task. Here is a script to pull this information using AT commands with in a PowerShell script. The script was tested on a CF-53J Toughbook laptop with an embedded Sierra 7750 (Verizon LTE) modem. The script displays methods of capturing the information to a text file or writing the information to the registry.

QueryWANModem.ps1 – GitHub Link:

###################################################################
# ChangeLog -
# 2/2/14 BG - Added code to write information into the registry
# 4/9/13 BG - Added CGMR command to pull Firmware date.
###################################################################

$oInvocation = (Get-Variable MyInvocation).Value
$sCurrentDirectory = Split-Path $oInvocation.MyCommand.Path

Function fQueryModem($sQueryString, $sRegExp) {
    $oComPort = New-Object System.IO.Ports.SerialPort $sComPortNumber,$sComPortSpeed,None,8,1
    $oComPort.Open()
    $oComPort.Write("AT")
    $oComPort.Write($sQueryString + "`r")
    Start-Sleep -m 50
    $tVar = $oComPort.ReadExisting()
    $tVar = ($tVar -replace "OK","").trim()
    $oComPort.Close()

    If (!($sRegExp -eq "")) {$tVar -Match $sRegExp|Out-Null; $tVar = $Matches[0]}
    return $tVar
}

#AT Commands to pull information from Modems
#"MEID", "+CGSN"			#i.e. "990000780252708"
#"Modem Model", "+CGMM"		#i.e. "MC7750"
#"Phone Number", "+CNUM"	#i.e. "+CNUM: "Line 1","+15514972305",145"
#"SIM", "+ICCID"			#i.e. "ICCID: 89148000000148583496"
#"Firmware Date", "+GMR		#i.e. "33, SWI9600M_03.05.10.09ap r5700 carmd-en-10527 2013/03/12 10:37:48"
#*Commands pulled using AT+CLAC command...

#Grab COMPort number and max ComPort speed
$sComPortNumber = Get-WmiObject Win32_PotsModem | `
	Where-Object {$_.DeviceID -like "USB\VID*" -and $_.Status -like "OK"} | `
	foreach {$_.AttachedTo}
$sModemInfPath = Get-WmiObject Win32_PotsModem | `
	Where-Object {$_.DeviceID -like "USB\VID*" -and $_.Status -like "OK"} | `
	foreach {$_.ModemInfPath}
$sModemDriverVer = Get-WmiObject Win32_PnPSignedDriver | `
	Where-Object {$_.InfName -like $sModemInfPath} | `
	foreach {$_.DriverVersion}
$sComPortSpeed = Get-WMIObject Win32_PotsModem | `
	Where-Object {$_.DeviceID -like "USB\VID*" -and $_.Status -like "OK"} | `
	foreach {$_.MaxBaudRateToSerialPort}

#Populate Variables using fQueryModem Function Call
$sMEID = fQueryModem "+CGSN" "\d{15}"
$sModemModel = fQueryModem "+CGMM" "" #Match Everything
$sPhoneNumber = fQueryModem "+CNUM" "\d{11}"
$sSIM = fQueryModem "+ICCID" "\d{20}"
#$sFirmwareDate = fQueryModem "+GMR" "\d{4}/\d{2}/\d{2}"
$sFirmwareDate = fQueryModem "+GMR" ""

#Populate TXT file with captured variables
#$sDate = Get-Date -Format "MM/dd/yyyy"
#$sOutString = "Date: $sDate
#Username: $env:username
#MEID: $sMEID
#Modem Model: $sModemModel
#Phone Number: $sPhoneNumber
#SIM Number: $sSIM
#Firmware Date: $sFirmwareDate
#Modem Driver: $sModemDriverVer"
#$sOutString | Out-File -FilePath "$sCurrentDirectory\" + $sFirmwareDate + ".TXT" -Force

#Create Registry Key with Firmware Version
New-Item -Path HKLM:\Software -Name _BHN -Value "Default Value" -Force
New-ItemProperty -Path HKLM:\Software\_BHN -Name "WWANFirmware" -PropertyType "String" -Value $sFirmwareDate
New-ItemProperty -Path HKLM:\Software\_BHN -Name "WWANSIM" -PropertyType "String" -Value $sSIM
New-ItemProperty -Path HKLM:\Software\_BHN -Name "WWANPhoneNumber" -PropertyType "String" -Value $sPhoneNumber
New-ItemProperty -Path HKLM:\Software\_BHN -Name "WWANModel" -PropertyType "String" -Value $sModemModel
New-ItemProperty -Path HKLM:\Software\_BHN -Name "WWANMEID" -PropertyType "String" -Value $sMEID
New-ItemProperty -Path HKLM:\Software\_BHN -Name "WWANComPort" -PropertyType "String" -Value $sComPortNumber

 

 

/BG

A Custom vbScript to Restore and Capture User Data using USMT 4.

By | January 31, 2014
Share

The reason for a custom script, is that the customer wanted to see a prompt displaying how large the backup .MIG file would be before initiating the backup.

The script was used in an SCCM 2012/MDT 2012U1 UDI Task Sequence.  I kicked off the script using a “Run a Command Line” step and used the “ServiceUI.exe” application, because the script displays a prompt that needs to be visible to the user.  The prompt displays an estimate on how large the .MIG file will be, if the file is too large, the deployment technician can skip the User Capture.

The process is split in 2 scripts (CaptureUserState.vbs and RestoreUserState.vbs):
 CaptureUserState.vbs:

'==========================================================================
' NAME: CaptureUserState.vbs
'
' AUTHOR: Brian Gonzalez
' DATE  : 12.11.2013
'
' Changlog:
' 12.11.13 - First revision
'
' PURPOSE: User State Capture Script.
'==========================================================================
'On Error Resume Next
'Setup Objects, Constants and Variables.
Set oFSO = CreateObject("Scripting.FileSystemObject")
Set oShell = WScript.CreateObject("WScript.Shell")
Set oNetwork = WScript.CreateObject("WScript.Network")
Const ForReading = 1, ForWriting = 2, ForAppending = 8
sScriptFolder = oFSO.GetParentFolderName(Wscript.ScriptFullName) 'NoTrailingBS
sScriptVerNumber = "1.3"

'Network Share Variables
sDriveLetter = "U:"
sShare = "\\<ServerShare>\<ShareFolder>"
sUser = "<UserName>"
sPass = "<Password>"

'Close SCCM Progress UI
Set oTSProgressUI = CreateObject("Microsoft.SMS.TSProgressUI")
Set oEnvironment = CreateObject("Microsoft.SMS.TSEnvironment")
oTSProgressUI.CloseProgressDialog()

sCompName = oEnvironment("OSDComputerName")
Set oLogFile = oFSO.CreateTextFile("X:\Windows\Temp\SMSTSLog\CaptureUserState.log", ForWriting, True)
oLogFile.WriteLine Time & ": Kicked Off Script(CaptureUserState.vbs v" & sScriptVerNumber & ")"

If oFSO.FolderExists("C:\Program Files\Internet Explorer") Then
	sOfflineWinDir = "C:\Windows"
ElseIf oFSO.FolderExists("D:\Program Files\Internet Explorer") Then
	sOfflineWinDir = "D:\Windows"
ElseIf oFSO.FolderExists("E:\Program Files\Internet Explorer") Then
	sOfflineWinDir = "E:\Windows"
ElseIf oFSO.FolderExists("F:\Program Files\Internet Explorer") Then
	sOfflineWinDir = "F:\Windows"
Else
	sOfflineWinDir = "Not Found"
	oLogFile.WriteLine Time & ": No Windows Directory Found, exiting script(10)."
	Wscript.Quit(10)
End If

oLogFile.WriteLine Time & ": Windows Directory Found:" & sOfflineWinDir

oLogFile.WriteLine Time & ": Attempt to map network drive."
sCmd = "CMD /C NET USE " & sDriveLetter & " /DELETE"
oLogFile.WriteLine Time & ": About to run(" & sCmd & ")."
sRet = oShell.Run(sCmd, 1, True)
sCmd = "CMD /C NET USE " & sDriveLetter & " """ & sShare & """ /USER:" & sUser & " " & sPass
'oLogFile.WriteLine Time & ": About to run(" & sCmd & ")."
sRet = oShell.Run(sCmd, 0, True)
If NOT oFSO.FolderExists("U:\") Then
	oLogFile.WriteLine Time & ": Failed to map network drive(" & sShare & "). Exiting Script(1)."
	Wscript.Quit(1)
End If

oLogFile.WriteLine Time & ": Mapped U: Successfully."
sStorePath = "U:\" & sCompName & "\StateStore"

oLogFile.WriteLine Time & ": Begin to pull estimate of USMT file size."
sCmd = """" & sScriptFolder & "\scanstate.exe"" """ & sStorePath & _
	""" /c /i:""" & sScriptFolder & "\MigDocs.xml"" /i:""" & sScriptFolder & _
	"\ManateeCaptureUSMT.XML"" /config:""" & sScriptFolder  & _
	"\config.xml"" /offline:""" &  sScriptFolder & _
	"\Offline.xml"" /l:""X:\Windows\Temp\SMSTSLog\USMTCapture.log"" /o /uel:30 /p:""X:\Windows\Temp\SMSTSLog\USMTEstimate.log"" /v:13"
oLogFile.WriteLine Time & ": About to run(" & sCmd & ")."
sRet = oShell.Run(sCmd, 1, True)
If sRet <> 0 Then
	oLogFile.WriteLine Time & ": Failed to pull USMT Estimate(" & sShare & "). Exiting Script(1)."
	Wscript.Quit(1)
End If

Set oEstimateFile = oFSO.OpenTextFile("X:\Windows\Temp\SMSTSLog\USMTEstimate.log")
sEstimateFileContents = oEstimateFile.ReadAll
sSizeEstimate = (Round((RegExpTest("[0-9]{1,}(?=</size)", sEstimateFileContents) / 1048000),1))
oLogFile.WriteLine Time & ": Successfully pulled USMT Estimate of: " & sSizeEstimate
sAnswer = oShell.Popup("Would you like to continue the user state capture routine? " & vbCrlf & _
	"(Estimated .MIG Size: " & sSizeEstimate & " MB)",, "USMT Prompt", 4)
If sAnswer = "7" Then 'Answered NO
	oLogFile.WriteLine Time & ": User specified to not copy data. Exiting Script(10)."
	'CopyLogFile
	Wscript.Quit(10)
End If

sCmd = """" & sScriptFolder & "\scanstate.exe"" """ & sStorePath & """" & _
	" /c /i:""" & sScriptFolder & "\MigDocs.xml"" /i:""" & sScriptFolder & _
	"\ManateeCaptureUSMT.XML"" /config:""" & sScriptFolder & _
	"\config.xml"" /offline:""" & sScriptFolder & "\Offline.xml"" /l:""X:\Windows\Temp\SMSTSLog\USMTCapture.log"" /o /uel:30 /v:13"
oLogFile.WriteLine Time & ": About to run(" & sCmd & ")."
sRet = oShell.Run(sCmd, 1, True)

sMIGFilePath = sStorePath & "\USMT\USMT.mig"
If oFSO.FileExists(sMIGFilePath) Then
	oLogFile.WriteLine Time & ": Successfully ran USMT Capture Routine to """ & sMIGFilePath & """"
	sCmd = "CMD /C NET USE " & sDriveLetter & " /DELETE"
	oLogFile.WriteLine Time & ": About to run(" & sCmd & ")."
	Wscript.Quit(0)
Else
	oLogFile.WriteLine Time & ": Failed to run USMT Capture Routine to """ & sMIGFilePath & """.  Check the ""X:\Windows\Temp\SMSTSLog\USMTCapture.log""(1)."
	sCmd = "CMD /C NET USE " & sDriveLetter & " /DELETE"
	oLogFile.WriteLine Time & ": About to run(" & sCmd & ")."
	Wscript.Quit(1)
End If

Function RegExpTest(strMatchPattern, strPhrase) 
	Set objRegEx = New RegExp
	objRegEx.Global = True 
	objRegEx.IgnoreCase = True 
	objRegEx.Pattern = strMatchPattern 

	Set Matches = objRegEx.Execute(strPhrase) 
	RegExpTest = Matches(0).Value
End Function

 RestoreUserState.vbs:

'==========================================================================
' NAME: RestoreUserState.vbs
'
' AUTHOR: Brian Gonzalez
' DATE  : 12.11.2013
'
' Changlog:
' 12.11.13 - First revision
'
' PURPOSE: User State Capture Script.
'==========================================================================
On Error Resume Next
'Setup Objects, Constants and Variables.
Set oFSO = CreateObject("Scripting.FileSystemObject")
Set oShell = WScript.CreateObject("WScript.Shell")
Set oNetwork = WScript.CreateObject("WScript.Network")
sSystemDriveLetter = oShell.ExpandEnvironmentStrings("%SystemDrive%")
sCompName = oShell.ExpandEnvironmentStrings("%ComputerName%")
Const ForReading = 1, ForWriting = 2, ForAppending = 8
sScriptFolder = oFSO.GetParentFolderName(Wscript.ScriptFullName) 'NoTrailingBS
sScriptVerNumber = "1.0"

'Network Share Variables
sDriveLetter = "R:"
sShare = "\\<ServerShare>\<ShareFolder>"
sUser = "<UserName>"
sPass = "<Password>"

'Close SCCM Progress UI
Set oTSProgressUI = CreateObject("Microsoft.SMS.TSProgressUI")
Set oEnvironment = CreateObject("Microsoft.SMS.TSEnvironment")
oTSProgressUI.CloseProgressDialog()

If oFSO.FolderExists(sSystemDriveLetter & "\_SMSTaskSequence\Logs") Then
	sLogFilePath = sSystemDriveLetter & "\_SMSTaskSequence\Logs\RestoreUserState.log"
	sLogFolder = sSystemDriveLetter & "\_SMSTaskSequence\Logs"
ElseIf oFSO.FolderExists(sSystemDriveLetter & "\Windows\CCM\Logs\SMSTSLogs") Then
	sLogFilePath = sSystemDriveLetter & "\Windows\CCM\Logs\SMSTSLogs\RestoreUserState.log"
	sLogFolder = sSystemDriveLetter & "\Windows\CCM\Logs\SMSTSLogs"
ElseIf oFSO.FolderExists(sSystemDriveLetter & "\Windows\CCM\Logs") Then
	sLogFilePath = sSystemDriveLetter & "\Windows\CCM\Logs\RestoreUserState.log"
	sLogFolder = sSystemDriveLetter & "\Windows\CCM\Logs"
Else
	sLogFilePath = sSystemDriveLetter & "\Windows\Temp\RestoreUserState.log"
	sLogFolder = sSystemDriveLetter & "\Windows\Temp"	
End If

Set oLogFile = oFSO.CreateTextFile(sLogFilePath, ForWriting, True)
oLogFile.WriteLine Time & ": Kicked Off Script(RestoreUserState.vbs v" & sScriptVerNumber & ")"

If oFSO.FolderExists("X:\Windows") Then
	oLogFile.WriteLine Time & ": Running in WinPE OS, script must be run in Windows 7. Exiting Script(1)."
	Wscript.Quit(1)
End If

If oFSO.FolderExists("C:\Program Files\Internet Explorer") Then
	sWinDir = "C:\Windows"
ElseIf oFSO.FolderExists("D:\Program Files\Internet Explorer") Then
	sWinDir = "D:\Windows"
ElseIf oFSO.FolderExists("E:\Program Files\Internet Explorer") Then
	sWinDir = "E:\Windows"
ElseIf oFSO.FolderExists("F:\Program Files\Internet Explorer") Then
	sWinDir = "F:\Windows"
Else
	oLogFile.WriteLine Time & ": No Windows Directory Found, exiting script(10)."
	Wscript.Quit(10)
End If

oLogFile.WriteLine Time & ": Windows Directory Found:" & sWinDir

oLogFile.WriteLine Time & ": Attempt to map network drive."
sCmd = "CMD /C NET USE """ & sDriveLetter & """ /DELETE"
oLogFile.WriteLine Time & ": About to run(" & sCmd & ")."
sRet = oShell.Run(sCmd, 1, True)
sCmd = "CMD /C NET USE " & sDriveLetter & " """ & sShare & """ /USER:" & sUser & _
	" " & sPass
'oLogFile.WriteLine Time & ": About to run(" & sCmd & ")."
sRet = oShell.Run(sCmd, 1, True)
If NOT oFSO.FolderExists(sDriveLetter & "\") Then
	oLogFile.WriteLine Time & ": Failed to map network drive(" & sShare & "). Exiting Script(1)."
	Wscript.Quit(1)
End If

oLogFile.WriteLine Time & ": Mapped " & sDriveLetter & " Successfully."
sMIGFilePath = sDriveLetter & "\" & sCompName & "\StateStore\USMT\USMT.mig"
sStorePath = sDriveLetter & "\" & sCompName & "\StateStore"

If oFSO.FileExists(sMIGFilePath) Then
	oLogFile.WriteLine Time & ": MIG file for Computer was located """ & sMIGFilePath & """."
Else
	oLogFile.WriteLine Time & ": MIG file for Computer was not located """ & sMIGFilePath & """.(10)"
	Wscript.Quit(10)
End If

oLogFile.WriteLine Time & ": Begin to run loadstate using USMT file size:" & sMIGFilePath
sCmd = """" & sScriptFolder & "\loadstate.exe"" """ & sStorePath & _
	""" /i:""" & sScriptFolder & "\MigDocs.xml"" /i:""" & sScriptFolder & _
	"\ManateeCaptureUSMT.XML"" /config:""" & sScriptFolder  & _
	"\config.xml"" /l:""" & sLogFolder & "\USMTRestore.log"" /v:13"
oLogFile.WriteLine Time & ": About to run(" & sCmd & ")."
sRet = oShell.Run(sCmd, 1, True)
If sRet <> 0 Then
	oLogFile.WriteLine Time & ": Failed to restore User Data. Exiting Script(1). Review the: " & sLogFolder & "\USMTRestore.log"
	sCmd = "CMD /C NET USE """ & sDriveLetter & """ /DELETE"
	oLogFile.WriteLine Time & ": About to run(" & sCmd & ")."
	sRet = oShell.Run(sCmd, 1, True)
	Wscript.Quit(1)
Else
	oLogFile.WriteLine Time & ": Restore of data was successful."
	sCmd = "CMD /C NET USE """ & sDriveLetter & """ /DELETE"
	oLogFile.WriteLine Time & ": About to run(" & sCmd & ")."
	sRet = oShell.Run(sCmd, 1, True)
	Wscript.Quit(0)
End If

/BG

Script to Force Intel Graphics Card to Maintain Aspect Ratio When Switching Display Resolutions.

By | January 30, 2014
Share

Some people despise the “stretch”.  This stretching occurs on newer screens that normally have an aspect ratio of 16:9 or 16:10 and are set to a 4:3 aspect ratio display resolution (i.e. 1024 x 768).  In some cases setting the 4:3 ratio resolution is required for an antiquated application’s view ability.  Setting this via a script is not a simple task, because by Default the Intel Graphic’s driver stretches the screen to fit the panel.  If you are the type that hates stretching and want to maintain the aspect ratio, then this script is for you:

ForceAspectRatio.vbs contents:

Script was tested in Win 7 x64, with the Intel Graphics 4000, Driver version 10.18.10.3308.

Const cHKLM = &H80000002
Set oReg=GetObject("winmgmts:{impersonationLevel=impersonate}!\\.\root\default:StdRegProv")
Set oShell = CreateObject("WScript.Shell")

sKeyPath = "SYSTEM\CurrentControlSet\Control\GraphicsDrivers\Configuration"
oReg.EnumKey cHKLM, sKeyPath, aSubKeys

If Not (isnull(aSubKeys)) Then
	For Each sSubkey In aSubKeys
		sTmpValueName = "HKLM\SYSTEM\CurrentControlSet\Control\GraphicsDrivers\Configuration\" & sSubKey & "\00\00\Scaling"
		Wscript.Echo "Attempting to write 4 value to: """ & sTmpValueName & """"
		oShell.RegWrite sTmpValueName, 4, "REG_DWORD"
	    If Err.Number <> 0 Then
			WScript.Echo "Write failed with errors: " & Err.Number
	    Else
			WScript.Echo "Write succedded."
	    End If	 
	Next
End If

This block of code enumerates through all of the GraphicsDrivers configurations updating the “Scaling” DWORD value to “4”, which translates to “Maintain Aspect Ratio”.  Once set, I can change the resolution via the “qres.exe” command line utility to what ever resolution I want and the aspect ratio will be maintained.

cscript "%~dp0ForceAspectRatio.vbs"
start /w "" "%~dp0QRes.exe" /X 1024 /Y 768 /c 32

Full download can be grabbed here, which includes the qres.exe, the script, and the batch to call the script.

In case your interested, I found this registry key and value by changing the setting in the Intel Graphics GUI (comes with Driver Installation), and monitoring the “RegSetValue” operation in Process Monitor using a filter (see below).

ProcessMonitorRegSetFilter

 

/BG