For many IT folks, or folk, as they say in places I've never been, this may step into the murky, sticky muddy waters of borderline sacrilege, but give me a chance. I know a lot of scripters, script-kiddies, skittles-munching, bong-drinking coder geeks like to think of scripts as the holy grail to solving all IT challenges. And for many situations they can be very well-suited to that purpose indeed. But for me, I find it more interesting when script code plays the part of Mr. Glue (okay, Ms. Glue is fine too), and helps bind the forces of the technoverse into harmony. Kind of like magical fiber in the ethereal digestive tract of the processing world. Um, yeah.
Case in Point: Crapware needs a Crutch.
IT folks who get their fingers all sticky with repackaging and deployment should be well familiar with less-than-ideal packaging chores. One that comes to mind (and, NO, I'm not going to name the vendor or product. Mainly out of pants-wetting fear of law suits), is a software application that comes with a digital signature pad.
Those are the kinds of detachable devices where you whip out a plastic pen-like thing, often with an attached cable thing, which is then grasped by the authoritative human with firm, yet shaky hands to apply a soon-to-become-extinct thing called a "handwritten signature". I'm told people used to actually scribble words using their own hands to indicate who they are (or were). Amazing! I wonder how long it will be before it's commonplace to have a chip implanted at birth. Moving along...
Ok. I'll get to the point.
First Challenge: The software probes for the peripheral signature pad device connection and determines the COM port assignment. From that it writes a new .INI configuration file (yes, this is supposedly "Windows XP compliant, and they say,
Bigger challenge: The customer purchased roughly 400 of these things. They need to be handed out to the field-workers, who each have a laptop running on Windows 7 Enterprise SP1. They rarely connect directly to the organization network, and they need to be able to plug these things in, and use them, while in the field. That means they are most often NOT on a VPN connection or connected to the Active Directory domain environment. But, that's not all!
Bigger than Bigger challenge: The INI file is created in, and will only work from within the C:\WINDOWS folder (e.g. %WINDIR%). That means UAC is giving them the big face-smack of security each time. KaBlam!! Thwack! Kazowwy! sorry, no more of that...
What to do?
Well, here's ONE way that happens to work:
- Perform a "manual" installation of the crapware application, or as some might call it: crapplication.
- Plug the device in. Wait for the UAC bitch-slap.
- Provide the suitable credentials to allow the crap-device to talk to the crapplication and update the crappy INI setting.
- Save a copy of the INI file.
- Locate the line which stores the COM port setting. Replace the value (e.g. "CrappyComPort=COM3") with a unique string value (e.g. "CrappyComPort=ZZZZZ") and save the copy.
...Now, using (insert dramatic entrance music) script code, you pull on the chains of the old "DEVCON" command-line utility to probe for the device and COM port. Write the results to a text file (redirect or whatever you prefer). I'm sure you can probe it using WMI or crawling the Registry as well, but since I like old commands, because I'm also old, I go that route.
As for the specific DEVCON syntax (thanks to Chris for this by the way)...
devcon.exe" hwids *FTDIBUS* >>"%Windir%\CrapWare\devcon_dump.txt"
Next, using script code, open and parse the DEVCON output file to get the COM port number. Then open the copied INI file, read in the guts, replace the "ZZZZ" (or whatever you chose to use) with the "COMx" value, and write it back out to the C:\WINDOWS\crapplication.INI file, all under a suitable elevated user context (i.e. SYSTEM, would be fine), and let her rip!
Example of the DEVCON dump file...
Name: USB Serial Port (COM4)
1 matching device(s) found.
Special thanks to my colleague and coworker extraordinaire: Chris. Because, he is extraordinary. And as they say, the difference between ordinary, and extraordinary, is that extra bit.
The dastardly code...
[beginnen der codenhauzen]
'**************************************************************** ' Filename..: crapplication.vbs ' Author....: INSERT YOUR NAME HERE UNLESS IT BLOWS UP (then use another name) ' Date......: 01/05/2014 ' Purpose...: parse text file to obtain desired value, win the prize! '**************************************************************** Option Explicit Dim scriptPath, strTemplate, objFSO, objFile
Dim strLine, strPart, pos, strComPort, ts, t1 Dim objINIsource, strNew, strAll, objShell
t1 = Timer
scriptPath = Replace(wscript.ScriptFullName, "\" & wscript.ScriptName, "") strTemplate = scriptPath & "\crapware.ini" Const inputFile = "c:\windows\temp\devcon_dump.txt" Const outputfile = "c:\windows\crapware.ini" Const ForReading = 1 Const ForWriting = 2 Const TristateUseDefault = -2 Const TriStateTrue = -1 Const TriStateFalse = 0 wscript.echo "info: devcon file == " & inputfile wscript.echo "info: output file == " & outputfile wscript.echo "info: template == " & strTemplate strComPort = ""
' comment: read the COM port from the devcon output file...
Set objFSO = CreateObject("Scripting.FileSystemObject") On Error Resume Next Set objFile = objFSO.OpenTextFile(inputFile, ForReading) If err.Number = 0 Then Do Until objFile.AtEndOfStream strLine = Trim(objFile.Readline) pos = InStr(strLine, "(COM") If pos > 0 Then strPart = Trim(Mid(strLine, pos)) ' comment: should return "(COMx)" strPart = Replace(Replace(strPart, "(", ""), ")", "") ' comment: should be left with "COMx" strComPort = Replace(strPart, "COM", "") End If Loop objFile.Close Else wscript.echo "fail: error (" & err.Number & ") = " & err.Description End If wscript.echo "info: current COM port: " & strComPort
' comment: open and suck-in all text from the template file...
Set objINISource = objFSO.OpenTextFile(strTemplate, ForReading, False) strAll = objINIsource.ReadAll() strNew = Replace(strAll, "TabletComPort=ZZZZ", "TabletComPort=" & strComPort) ' comment: get the vendor's crappy ini or make a new one... On Error Resume Next Set objShell = CreateObject("Wscript.Shell") wscript.echo "info: searching for default ini file... " & outputfile Set objFile = objFSO.GetFile(outputFile) If err.number <> 0 Then err.Clear wscript.echo "info: ini file not found. creating new one..." wscript.echo "info: creating new file: " & outputfile Set ts = objFSO.CreateTextFile(outputfile) If err.Number <> 0 Then wscript.echo "error: " & err.number & ": " & err.Description Set objFSO = Nothing wscript.quit err.Number End If wscript.echo "info: waiting for a second. why rush things?..." objShell.Sleep 1000 Set objShell = Nothing ts.Write strNew ts.Close wscript.echo "info: file created successfully!" Else err.Clear wscript.echo "info: deleting old file... " & outputfile objFSO.DeleteFile outputfile, True wscript.echo "info: creating new file... " & outputfile Set ts = objFSO.CreateTextFile(outputfile) If err.Number <> 0 Then wscript.echo "error: " & err.number & ": " & err.Description Set objFSO = Nothing wscript.quit err.Number End If ts.Write strNew ts.Close wscript.echo "info: file updated successfully!" End If Set ts = Nothing Set objINISource = Nothing Set objFSO = Nothing Set ts = Nothing wscript.echo "info: completed." wscript.echo "info: runtime is " & Round(Timer - t1,2) & " seconds"
[terminaten der codenschnitzel]I know what you're thinking: My variable names suck and my error handling methods could use some improvement. I could also stand to cut back on some bad dietary habits, but ultimately, someone has to feed the worms. You're also probably upset that I didn't do this in PowerShell, which I could have, but I'm too lazy tonight and I have to be up early for work tomorrow.
So, assuming the devcon output file has the right output, and the scripts are run under an administrative context, it works pretty well. The users can plug the device in and life is good. If bolted together properly it can be deployed via System Center Configuration Manager as an advertisement, or posted in the Application Catalog for self-install.
Next time I might delve into a scenario for converting VBscript into ASP for interfacing with Active Directory, WMI/WBEM and Configuration Manager via a web browser.