HTA/VBS Noob question

Batch, ASP, JScript, Kixtart, etc.
Forum rules
Do not post any licensing information in this forum.

Any code longer than three lines should be added as code using the 'Select Code' dropdown menu or attached as a file.
User avatar
thenoob74
Posts: 17
Joined: Tue Aug 10, 2010 1:55 am

HTA/VBS Noob question

Post by thenoob74 » Wed Aug 11, 2010 5:00 am

So I'm hearing it's not possible to do this on one script and that I'll need to call a separate script. correct? Make something like this code as part of one of the options to run when that option is selected and ran from the button? Example: I select IT as the option, hit the start script button and it will then run the following and call my vbs script for IT? I'm just curious how that would look? Set objFSO = CreateObject("Scripting.FileSystem­ Object")Set File = objFSO.OpenTextFile("C:TempIT.vbs")ScriptContent = File.ReadAllExecuteGlobal ScriptContent

User avatar
jvierra
Posts: 13506
Joined: Tue May 22, 2007 9:57 am
Contact:

HTA/VBS Noob question

Post by jvierra » Wed Aug 11, 2010 7:05 am

Her eis what I mean by using a function or subroutine. It is the same as you aer doing without all of the extra vaiable management which is entirely unnecessary.

Code: Select all

Function ProcessUser( strUserIn )    
    ' Add (str)User to (str)Group
    strUserDN = Replace("LDAP://CN=XXXXX,OU=Standard,OU=Managed Users,DC=MFI,DC=domain,DC=PVT","XXXXX", strUserIn )
    Set objUser = GetObject(strUserDN)
    Set objGroup = GetObject("LDAP://CN=TSM_BackupUsers,OU=Application Rights, OU=Groups, OU=Managed Users,DC=MFI,DC=domain,DC=PVT")
    objGroup.add objUser.ADsPath
    Set oGrp = GetObject("WinNT://./Power Users")
    set oGrp1 = GetObject("WinNT://./Backup Operators")
    Set oUsr = GetObject("WinNT://MFI.domain.pvt/Domain Users")
    oGrp.Add oUsr.ADsPath
    oGrp1.Add oUsr.ADsPath
    
    ProcessUser = true
    
End Function


Collect the user name from input boxes on your form and format it as needed. If you need first last an initial then ask for three boxes with first last and initial and pu them together in code then pass that to the function.

If you need to work on multiple OUs then pass teh full Group and OU strings into teh function as stored in the "value" property of a listbox. This way yu need only one function, one button, one listbox and three text controls. This might justify doing this with an HTA.

Here is a sample of the HTA:

http://www.sapien.com/forums/uploads/2491/Demo1.hta.txt

User avatar
rasimmer
Posts: 182
Joined: Fri Jan 30, 2009 12:37 am

HTA/VBS Noob question

Post by rasimmer » Wed Aug 11, 2010 7:38 am

You can do it all in the HTA. The whole point of using a HTA over vbScript is that you can use HTML form controls to gatherdisplay information to be used in the script (like InputBox). The script below is something I wrote a couple years ago to update the "ManagedBy" attribute on computer accounts. It will show how to do a basic user search:

<html>
<head> <META http-equiv="Content-Style-Type" content="text/css"> <title>Managed_By_Audit</title></head>
<style> body { font-family:Verdana; font-size: 12px; color: black; background: #FFFFFF;
} button { font-family:Verdana; font-size: 14px; filter:progid:DXImageTransform.Microsoft.Gradient(GradientType=0, StartColorStr=#99FF33, EndColorStr=#ffffff); height: 30px; width: 150px; font-weight: bold; } table { border-width: thin; border-color: black; border-style: groove; font-size: 10px; }
td { border-width: 1px; padding: 1px; border-style: solid; border-color: black; }</style>
<script language="vbscript">
Sub Window_Onload() Center_HTA 650,550 Get_Managed_By_AD() Find_User()End Sub
Sub Center_HTA( widthX, heightY ) self.ResizeTo widthX, heightY self.MoveTo (screen.Width - widthX)/2, (screen.Height - heightY)/2End Sub
Sub Get_Managed_By_AD() Dim objSysInfo : Set objSysInfo = CreateObject("ADSystemInfo") Dim objComputer : Set objComputer = GetObject("LDAP://" & objSysInfo.ComputerName) spn_Computer.InnerHTML = Ucase(objComputer.CN) If objComputer.managedBy = "" Then spn_User.InnerHTML = "<font style='color:red;text-weight:bold>This system has no owner</font>" Else Call Get_User_Detail(objComputer.managedBy, spn_User) End IfEnd Sub
Sub Find_User() document.getElementById("txt_LName").style.background="#FFFFBB" If Len(txt_LName.Value) > 1 Then ClearListbox() Call Search_AD("user", txt_LName.Value & "*") spn_User_Detail.InnerHTML = "< NO USER SELECTED >" Call Get_User_Detail(drp_User_Results.Value, spn_User_Detail) Else ClearListbox() spn_User_Detail.InnerHTML = "< NO USER SELECTED >" Set objOption = Document.createElement("OPTION") objOption.Text = "Type a Last Name to Search" objOption.Value = "NULL" drp_User_Results.Add(objOption) End If End Sub
Sub VerifyAlphaChar() Dim objRegEx : Set objRegEx = CreateObject("VBScript.RegExp") objRegEx.Global = True objRegEx.Pattern = "[^A-Za-zb]"
Dim colMatches : Set colMatches = objRegEx.Execute(Chr(Window.Event.KeyCode))
If colMatches.Count > 0 Then Select Case Window.Event.KeyCode Case 46, 37, 39, 16 'Ignore these events Case Else spn_Status.InnerHTML = "<font style='color:red;font-weight:bold;'>Only letters can be entered!!</font>" txt_LName.Focus Window.Event.returnValue = False End Select Else spn_Status.InnerHTML = "Please enter a name to begin searching..." End IfEnd Sub
Sub Get_User_Detail(obj_DN, obj_Element) Set objUser = GetObject("LDAP://" & obj_DN) Dim strDispName : strDispName = objUser.displayName Dim strSAM : strSAM = objUser.samAccountName Dim strMail : strMail = objUser.physicalDeliveryOfficeName Dim strCity : strCity = objUser.l Dim strPhone : strPhone = objUser.telephoneNumber Dim strAdsPath : strAdsPath = objUser.adsPath obj_Element.InnerHTML = "<b>" & strDispName & " (" & strSAM & ")<b>" & " | " & strCity & " | " & strMail & " | " & strPhone End Sub
Sub Search_AD(OBJ_CATEGORY, SEARCH_STRING) Dim objCommand : Set objCommand = CreateObject("ADODB.Command") Dim objConnection : Set objConnection = CreateObject("ADODB.Connection") objConnection.Provider = "ADsDSOObject" objConnection.Open "Active Directory Provider" objCommand.ActiveConnection = objConnection Dim objRootDSE : Set objRootDSE = GetObject("LDAP://RootDSE") Dim strDNSDomain : strDNSDomain = objRootDSE.Get("defaultNamingContext") Dim strBase : strBase = "<LDAP://" & strDNSDomain & ">" Dim strFilter : strFilter = "(&(objectCategory=" & OBJ_CATEGORY & ")(!userAccountControl:1.2.840.113556.1.4.803:=2)(sn="& SEARCH_STRING & "))" Dim strAttributes : strAttributes = "distinguishedName,displayName" Dim strQuery : strQuery = strBase & ";" & strFilter & ";" & strAttributes & ";subtree"
objCommand.CommandText = strQuery objCommand.Properties("Page Size") = 100 objCommand.Properties("Timeout") = 30 objCommand.Properties("Cache Results") = False Dim objRecordSet : Set objRecordset = objCommand.Execute intCount = objRecordSet.RecordCount
Set objRecordset = objCommand.Execute If objRecordset.EOF Then ClearListbox() Set objOption = Document.createElement("OPTION") objOption.Text = "No Name Found" objOption.Value = "NULL" drp_User_Results.Add(objOption) spn_User_Detail.InnerHTML = "<font style='color:red;font-weight:bold;'>No user with this name could be found!!</font>" document.getElementById("txt_LName").style.background="#FF6633" Else Do Until objRecordSet.EOF Set objOption = Document.createElement("OPTION") objOption.Text = objRecordSet.Fields("displayName").value objOption.Value = objRecordSet.Fields("distinguishedName").value drp_User_Results.Add(objOption) spn_RecordCount.InnerHTML = intCount & " records found" objRecordSet.MoveNext Loop End IfEnd Sub
Sub ClearListbox() For Each objOption in drp_User_Results.Options objOption.RemoveNode Next End Sub
Sub btn_Update_onClick() MsgBox "You selected user " & drp_User_Results.ValueEnd Sub
</script><hta:application applicationname="hta" border="dialog" borderstyle="normal" caption="yes" contextmenu="yes" icon="no.ico" maximizebutton="yes" minimizebutton="yes" navigable="yes" scroll="yes" selection="yes" showintaskbar="no" singleinstance="yes" sysmenu="yes" version="1.0" windowstate="normal"></head> <body> <h2>Workstation Owner Audit</h2> <p>Please take one moment to verify the information below to assist IT in identifying who manages or is primarily responsible for the system you are logging on to. By keeping these records current, we can expedite:</p> <ul> <li>PC BreakFix Issues</li> <li>PC Replacement or Refresh</li> <li>Correction of Security Issues (i.e. viruses, patching, etc.)</li> </ul> <br> This PC <b>(<span id="spn_Computer"></span>)</b> is being audited against our records to validate the managed by responsible person. <br> <br> The current person listed as responsible for this system is: <br> <br> <center><span id="spn_User" style="color: green;"></span></center> <br> <br> If this information is incorrect, please enter the correct user below: <br> <br> <center>Last Name Search:&nbsp&nbsp<input type="text" name="txt_LName" size="25" onkeydown="VerifyAlphaChar" onkeyup="Find_User" style="background-color:#FFFFBB;"> <br> <br> <span id="spn_Status"></span> <br> <br> <select size="1" name="drp_User_Results" onchange="Get_User_Detail" checked> <option value="NULL">Type a Last Name to Search</option> </select> &nbsp&nbsp<span id="spn_RecordCount" style="color: gray;"></span> <br> <br> Detail:&nbsp&nbsp<span id="spn_User_Detail" style="color: blue;"></span> <br> <br> <button class="button" id="btn_Update" title="Update my information...">Update</button> </center> </body></html>rasimmer2010-08-13 10:56:02

User avatar
jvierra
Posts: 13506
Joined: Tue May 22, 2007 9:57 am
Contact:

HTA/VBS Noob question

Post by jvierra » Wed Aug 11, 2010 8:17 am

Ras -

Put the following in a file on your desktop and name it something like test.hta.

Code: Select all

<form> 
<input type=submit /> 
</form>

This is a minimalist form which is completely legal as all browsers will provide a default html/body wrapper for any file that does not have one.

Run the file and click the button. YOu will see why forms won't work.

User avatar
thenoob74
Posts: 17
Joined: Tue Aug 10, 2010 1:55 am

HTA/VBS Noob question

Post by thenoob74 » Fri Aug 13, 2010 4:33 am

OK, the HTA looks great! I've added a couple quick edits and have tested but doesn't appear anything is happening. What initiates the function? I tried to edit the strUserDN where you had CN=xxxxx I changed it to sUserName, thinking it would plug in the users name that was typed. But I need to go back and re-read your reply to make sure I didn't miss a line of instruction. Wanted to post what I have to see if there is something obvious. uploads/34385/revised1.txt

User avatar
thenoob74
Posts: 17
Joined: Tue Aug 10, 2010 1:55 am

HTA/VBS Noob question

Post by thenoob74 » Fri Aug 13, 2010 6:17 am

Ahh yes I didn't catch the apostrophe. Now that the name is being passed to the function, it prompted an error on line 49. This line: strUserDN = Replace("LDAP://CN=sUserName,OU=Standard,OU=Managed Users,DC=MFI,DC=domain,DC=PVT", strUser )I assumed it has something to do with how I called the variable sUserName, is that the correct way of calling out that variable in this instance. I checked a couple of sites but the examples of calling variables are different than what I think I need.

User avatar
jvierra
Posts: 13506
Joined: Tue May 22, 2007 9:57 am
Contact:

HTA/VBS Noob question

Post by jvierra » Mon Aug 16, 2010 12:27 am

Run the code as a vbscxript and put in the exact name you are using as part of teh code. Then tell me what won't work.

SLasshes and commas are not allowed in account names. They can be used in display names. Are you using the display name to locate the account. This is unreliable because it is not unique.

Just because you had a piece of code that worked once does not meant that it is written correctly., It just may be that your odd, non-stanard, approach was able to work for one case.

In orfer to retrieve a user object directly we need to use the accouynt name. This is the name that is the 'CN=" portion of the aDSPath. If there is a copmma in the name then the query will likely have issues.


If you insist on using a non-legal account name then all of you queries will have to look like the following:
Set objOU = GetObject("LDAP://CN=""smit, joe"",OU=sbSUsers,OU=USERS,OU=MyBusiness,DC=sec,DC=local")

Notice teh account name (red) has to be enclosed in quotes. In this case double quotes are used to escape the quote inside of the string. This is a pain going forward and will cause all kinds of grief for AD and other tools. It may make migration of the account impossible. Commas an equal signs will always break the query string.

CN=bahblah, lastblah, CD=nnnn

If the string breaks at commas then the first comma will split the account name.

N AD query (LDAP) finds bits by looking for comma then an equal sign. The comma separates what we call name/value pairs. The equal sign separate the name and teh value. The left side of the pair is always the name and the right side is always the value. Putting a comma or an equal sign in the value field breaks the convention and requires that quotes be used. LDAP does not guarantee that this will always work. It just happens to work for the COM implementation of Microsoft's version of LDAP (an industry standard).

If you insist on using these characters in you account names then you are forced to always use quotes inLDAP and other subsystems such as the ADO provider for ADSI/LDAP. Other tools may not allow you to specifiy names with thes characters and remote systems such as WS2008 may not allow accounts with this kind of name to be used or trusted.

Try the code in a VBS file to see what I mean.

Code: Select all

' uncomment an runeach independently with a user name you know
' the first will fail if there is a comma in teh name
' the second will succeed if name is otherwise legal.
sUser = "blah, blah"
'ProcessUser sUser
'ProcessUser "" & sUser & ""
Function ProcessUser( strUser, strOU ) 
        
        'Add User to Group
        strUserDN = Replace("LDAP://CN=sUserName, OU=Standard,OU=Managed Users,DC=MFI,DC=domain,DC=PVT", strUser )
        Set objUser = GetObject(strUserDN)
        Set objGroup = GetObject("LDAP://CN=TSM_BackupUsers,OU=Application Rights, OU=Groups, OU=Managed Users,DC=MFI,DC=Michaelfoods,DC=PVT")
        objGroup.add objUser.ADsPath
    
        Set oGrp = GetObject("WinNT://./Power Users")
        set oGrp1 = GetObject("WinNT://./Backup Operators")
        Set oUsr = GetObject("WinNT://MFI.domain.pvt/Domain Users")
        oGrp.Add oUsr.ADsPath
        oGrp1.Add oUsr.ADsPath
        
        ProcessUser = true
        
End Function

I don't guarantee the WinNT provider will handle the comma correctly but it should. The LDAP provider will work.

User avatar
thenoob74
Posts: 17
Joined: Tue Aug 10, 2010 1:55 am

HTA/VBS Noob question

Post by thenoob74 » Mon Aug 16, 2010 4:41 am

I'm sorry I didn't mean to brake it. But how does the XXXXX get replaced with the strUser? I didn't see any function that replaced that with what is entered on the HTA. thenoob742010-08-16 11:46:58

User avatar
jvierra
Posts: 13506
Joined: Tue May 22, 2007 9:57 am
Contact:

HTA/VBS Noob question

Post by jvierra » Mon Aug 16, 2010 4:46 am

By the way - you shouldn't be using ADISEdit to manage AD> it is only for adjusting th esxhema. Chages in ADSIEdit can crash AD forever.


User avatar
jvierra
Posts: 13506
Joined: Tue May 22, 2007 9:57 am
Contact:

HTA/VBS Noob question

Post by jvierra » Mon Aug 16, 2010 5:03 am

Please note that in the above you have to be careful that you get the whole script. If you are using a bad browser the lines may be trucated which would give the code you were trying to use.

Here is the long line which I have now wrapped.
strUserDN = Replace( _ "LDAP://CN=XXXXX,OU=Standard," _
& "OU=Managed Users,DC=MFI,DC=domain,DC=PVT", _
"XXXXX", strUser )

Locked