8
\$\begingroup\$

I've put some code together that helps me search an internal ticket system using an HTA application with some TextBoxes and some embedded VBScript that runs PowerShell scripts. The PowerShell scripts are hard coded to a certain directory and I was wondering if there's a better way to accomplish this task/goal. I really do appreciate any assistance! I'm trying to provide this to co-workers who want things as simple as can be!

Here's the HTA code, as it can be seen, the VBScript has hard coded references to the various PowerShell scripts. (Huge thanks to this for the basic code I adapted to my specific needs).

<html>
<head>
<title>Search for IR</title>
<meta content="text/html; charset=utf-8" http-equiv="Content-Type" />
<hta:application applicationname="PowerShell HTA Example" version="1.0" />
<script language="vbscript">
 Sub Resize()
window.resizeTo 500,450
TextBox1.Focus
 End Sub
 Sub ExecutePowerShell()
Dim oShell, appCmd, sSvr, sLast, sDesc, sDate
'Collect value from input form
sSvr = document.getElementByID("TextBox1").Value
sLast = document.getElementByID("TextBox2").Value
sDesc = document.getElementByID("TextBox3").Value
sDate = document.getElementByID("choose").Value
'Check for empty server name input box.
'If sSvr = "" Then
'MsgBox "Please enter something in the input form"
'Exit Sub
'End If
Set oShell  = CreateObject("WScript.Shell")
appCmd      = "powershell.exe C:\Temp\SearchIR.ps1 " & Chr(39) & sSvr & Chr(39) & " " & Chr(39) & sLast & Chr(39) & " " & Chr(39) & sDesc & Chr(39) & " " & Chr(39) & sDate & Chr(39)
oShell.Run appCmd, 0, true
 End Sub
 Sub Clearer()
TextBox1.Value = ""
TextBox2.Value = ""
TextBox3.Value = ""
TextBox4.Value = ""
TextBox5.Value = ""
TextBox6.Value = ""
TextBox7.Value = ""
TextBox8.Value = ""
choose.Value = ""
ChooseStatus.Value = ""
TextBox1.Focus
 End Sub
 Sub SearchSR()
Dim sSr, sRequest, oSRSearch
sRequest = document.getElementByID("TextBox4").Value
If sRequest = "" Then
MsgBox "Please enter something in the input form"
Exit Sub
End If
Set oSRSearch  = CreateObject("WScript.Shell")
sSr      = "powershell.exe C:\Temp\SearchSR.ps1 " & Chr(39) & sRequest & Chr(39)
oSRSearch.Run sSr, 0, true
 End Sub
 Sub SearchCR()
Dim cCr, cRequest, oSearchCR, crDate
cRequest = document.getElementByID("TextBox5").Value
crDate = document.getElementByID("choose").Value
If cRequest = "" Then
MsgBox "Please enter something in the input form"
Exit Sub
End If
Set oSearchCR  = CreateObject("WScript.Shell")
cCr      = "powershell.exe C:\Temp\SearchCR.ps1 " & Chr(39) & cRequest & Chr(39) & " " & Chr(39) & crDate & Chr(39)
oSearchCR.Run cCr, 0, true
 End Sub
 Sub SearchCR_Note()
Dim cCrNote, CRNote, oSearchCR_Note
CRNote = document.getElementByID("TextBox7").Value
If CRNote = "" Then
MsgBox "Please enter something in the input form"
Exit Sub
End If
Set oSearchCR_Note  = CreateObject("WScript.Shell")
cCrNote      = "powershell.exe C:\Temp\SearchCR_Note.ps1 " & Chr(39) & CRNote & Chr(39)
oSearchCR_Note.Run cCrNote, 0, true
 End Sub
 Sub SearchSR_Note()
Dim cSRNote, SRNote, oSearchSR_Note
SRNote = document.getElementByID("TextBox6").Value
If SRNote = "" Then
MsgBox "Please enter something in the input form"
Exit Sub
End If
Set oSearchSR_Note  = CreateObject("WScript.Shell")
cSRNote      = "powershell.exe C:\Temp\SearchSR_Note.ps1 " & Chr(39) & SRNote & Chr(39)
oSearchSR_Note.Run cSRNote, 0, true
 End Sub
 Sub SearchSSL()
Dim cSSLSearch, strSSL, oSSLSearch
strSSL = document.getElementByID("TextBox8").Value
If strSSL = "" Then
MsgBox "Please enter something in the input form"
Exit Sub
End If
Set oSSLSearch  = CreateObject("WScript.Shell")
cSSLSearch      = "powershell.exe C:\Temp\Search_SSL.ps1 " & Chr(39) & strSSL & Chr(39)
oSSLSearch.Run cSSLSearch, 0, true
 End Sub
</script>
</head>
<body onload="Resize()">
Enter Server Name &nbsp &nbsp &nbsp &nbsp &nbsp Last Name <br />
<input type="text" name="TextBox1" id="ServerName" onKeydown="javascript: if (event.keyCode==13) ExecutePowerShell();" />
<input type="text" name="TextBox2" id="LastName" onKeydown="javascript: if (event.keyCode==13) ExecutePowerShell();" />
<input type="button" id="btn_execute" value="Execute" onclick="ExecutePowerShell()" /><input type="button" id="button_clear" value="Clear" style="background-color:#FF3333" onclick="Clearer()" />
<br>
Select Date:<br><select name="choose" size="1">
<option value=" " selected="selected"></option>
<option value="Today">Today</option>
<option value="Yesterday">Yesterday</option>
<option value="Week Old">Week Old</option>
</select><br>
Select Status:<br><select name="ChooseStatus" size="1">
<option value=" " selected="selected"></option>
<option value="Acknowledged">Acknowledged</option>
<option value="Case Assigned">Case Assigned</option>
<option value="Closed">Closed</option>
<option value="Fixed-Monitoring">Fixed-Monitoring</option>
<option value="Open">Open</option>
<option value="Resolved">Resolved</option>
<option value="Working">Working</option>
</select>
&nbsp &nbsp &nbsp &nbsp &nbsp &nbsp &nbsp &nbsp &nbsp SSL Search <br>
&nbsp &nbsp &nbsp &nbsp &nbsp &nbsp &nbsp &nbsp &nbsp &nbsp &nbsp &nbsp &nbsp &nbsp &nbsp &nbsp &nbsp &nbsp &nbsp &nbsp <input type="text" name="TextBox8" id="SSLSearch" onKeydown="javascript: if (event.keyCode==13) SearchSSL();" />
<input type="button" id="btn_execute5" value="GO" onclick="SearchSSL" /><br /><br />Symptom/Description<br /><input type="text" name="TextBox3" id="Description" onKeydown="javascript: if (event.keyCode==13) ExecutePowerShell();" />
<br /><br />SR Search &nbsp &nbsp &nbsp &nbsp &nbsp &nbsp &nbsp &nbsp &nbsp &nbsp &nbsp &nbsp &nbsp &nbsp &nbsp &nbsp &nbsp &nbsp &nbsp &nbsp &nbsp
SR Note<br /><input type="text" name="TextBox4" id="SRSearch" onKeydown="javascript: if (event.keyCode==13) SearchSR();" />
<input type="button" id="btn_execute2" value="Execute" onclick="SearchSR()" /> <input type="text" name="TextBox6" id="CR_Note" onKeydown="javascript: if (event.keyCode==13) SearchSR_Note();" />
<input type="button" id="btn_execute4" value="GO" onclick="SearchSR_Note" />
<br /><br />CR Search &nbsp &nbsp &nbsp &nbsp &nbsp &nbsp &nbsp &nbsp &nbsp &nbsp &nbsp &nbsp &nbsp &nbsp &nbsp &nbsp &nbsp &nbsp &nbsp &nbsp &nbsp CR Note<br /><input type="text" name="TextBox5" id="CRSearch" onKeydown="javascript: if (event.keyCode==13) SearchCR();" />
<input type="button" id="btn_execute3" value="Execute" onclick="SearchCR()" />
<input type="text" name="TextBox7" id="CR_Note" onKeydown="javascript: if (event.keyCode==13) SearchCR_Note();" />
<input type="button" id="btn_execute4" value="GO" onclick="SearchCR_Note" />
<!--<div style="margin-top:10px; margin-bottom:30px;">-->
</body>
</html>

Here is one PowerShell script, used frequently:

Param(
[Parameter(Mandatory=$false)]
[string]$svr,
[Parameter(Mandatory=$false)]
[string]$last,
[Parameter(Mandatory=$false)]
[string]$desc,
[Parameter(Mandatory=$false)]
[string]$date)
# Create the IE com object
$ie = new-object -comobject InternetExplorer.Application
$ie.navigate("http://yourURL.net")
# Wait for the page to finish loading
do {sleep 1} until (-not ($ie.Busy))
$doc = $ie.document
$link = $doc.getElementById("Sym_Msg").Value = "$svr"
$link = $doc.getElementById("Lname").Value = "$last"
$link = $doc.getElementById("Desc").Value = "$desc"
$link = $doc.getElementById("Date_Ent").Value = "$date"
$button = $doc.getElementById("submit1")
$ie.Visible = $true
#Load DLL
#$pinvoke = '[DllImport("user32.dll")] public static extern bool ShowWindowAsync(IntPtr hWnd, int nCmdShow)'
#Add-Type -MemberDefinition $pinvoke -name NativeMethods -namespace Win32
Add-Type -Namespace PInvoke -Name SWP '[DllImport("user32.dll", SetLastError=true)] |
public static extern bool SetWindowPos(IntPtr hWnd, IntPtr hWndInsertAfter, int X, int Y, int cx, int cy, int uFlags);'
#Code below is an attempt to bring the opened IE window to front.
#Get WindowHandle of the COM Object
$hwnd = $ie.HWND
# Restore window
[PInvoke.SWP]::SetWindowPos($hWnd, -1, 0, 0, 0, 0, 3)
#[Win32.NativeMethods]::ShowWindowAsync($hwnd, -1, 4)
$button.click();
[System.Runtime.Interopservices.Marshal]::ReleaseComObject($ie) | Out-Null
\$\endgroup\$
  • \$\begingroup\$ Nobody has anything to offer? Specifically, is there a method to make running the PowerShell scripts from the HTA more fault-tolerant? \$\endgroup\$ – user4317867 Feb 24 '15 at 7:58
  • 1
    \$\begingroup\$ The mix of technologies in this post is quite impressive. I've bookmarked this for a closer review when time allows. It would be helpful to know what requirements define this project and which environments (browser/OS) are targeted. \$\endgroup\$ – psaxton Mar 9 '15 at 5:08
  • \$\begingroup\$ Just to follow up here, I'm now working on wrapping the PowerShell code in VBScript so the HTA can create the PS1 script files as needed and delete them once they run. In this way the HTA is fully self-contained. \$\endgroup\$ – user4317867 Apr 1 '15 at 6:00
  • \$\begingroup\$ I cannot take the credit here @psaxton since I adapted the code from the link in the question. The requirements are simply an extension to an internal web based ticket system targeting the IE browser. But my aim for posting here was to illustrate how HTML, HTA, PowerShell and VBScript can all play nice! \$\endgroup\$ – user4317867 Apr 1 '15 at 6:02
2
\$\begingroup\$

The lack of indentation may make slightly smaller HTML files, but this isn't 1997 anymore, a few spaces isn't going to make a significant difference in download times. Readability wins over micro-optimization - assuming the non-indentation is not merely the result of a paste glitch.

<script language="vbscript">

    Sub Resize()
        window.resizeTo 500,450
        TextBox1.Focus
    End Sub

    Sub ExecutePowerShell()

        'Collect value from input form
        Dim oShell, appCmd, sSvr, sLast, sDesc, sDate
        sSvr = document.getElementByID("TextBox1").Value
        sLast = document.getElementByID("TextBox2").Value
        sDesc = document.getElementByID("TextBox3").Value
        sDate = document.getElementByID("choose").Value

        'Check for empty server name input box.
        'If sSvr = "" Then
        '    MsgBox "Please enter something in the input form"
        '    Exit Sub
        'End If

        Set oShell  = CreateObject("WScript.Shell")
        appCmd = "powershell.exe C:\Temp\SearchIR.ps1 " & Chr(39) & sSvr & Chr(39) & " " & Chr(39) & sLast & Chr(39) & " " & Chr(39) & sDesc & Chr(39) & " " & Chr(39) & sDate & Chr(39)
        oShell.Run appCmd, 0, true

    End Sub

    ...

Isn't it much easier to read? If it's easier to read, it's easier to maintain... and to review.

Why is there commented-out code there? If the [lack of] indentation was meant to save bytes, then that's defeating the purpose!


Clearer is a class name - method/procedure names should start with a verb. A better name might be ClearFields or something similar.

Other than that, I see 6 places where you declare a powershell.exe command string. You need to have a dedicated procedure for this!

\$\endgroup\$
  • \$\begingroup\$ Thank you for replying! You could call this lazy code, examples I've copied from web pages and pasted into notepad++ so when I hit upon something that worked; I just left it that way. I commented the code as I tested adding features then decided to remove it but leave it there as an example. Now the powershell.exe command is why I posted here. I wasn't sure how I'd go about getting VBS to create the powershell scripts to make this fully self-contained. \$\endgroup\$ – user4317867 Mar 19 '15 at 23:01
  • \$\begingroup\$ Just an update, I've done away with depending on PowerShell scripts statically called out in the HTA. I'm now using VBScript to create these scripts so there's no dependancy. Other than expanding the HTML/code blocks for readibility, I'm calling this v0.9 RC! \$\endgroup\$ – user4317867 Apr 8 '15 at 21:49

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.