SunshineVK
asked on
HTA application to run script with alternate credentials Windows 2003 domain
Hi,
We have two domains with our users having an id in each domain. I need the users to run a VBscript to map the file shares in Domain B with the domain B user id and password after they have logged in to domain A.
1. User logs in to a machine in Domain A
2. Runs the script in network path in Domain B with user ID & password in Domain B.
I was trying to do this with an HTA app but am unable to pass the credentials to script in Domain B through the HTA.
Can someone please help or point me the right direction
thanks !!
We have two domains with our users having an id in each domain. I need the users to run a VBscript to map the file shares in Domain B with the domain B user id and password after they have logged in to domain A.
1. User logs in to a machine in Domain A
2. Runs the script in network path in Domain B with user ID & password in Domain B.
I was trying to do this with an HTA app but am unable to pass the credentials to script in Domain B through the HTA.
Can someone please help or point me the right direction
thanks !!
Do you want hard-coded credentials in the HTA or do you want the users to enter the username/password into it?
Joe
Joe
ASKER
Hii Joe,
I want users to enter the username and password into it.
I want users to enter the username and password into it.
Here are some sites to help you with passing credentials while using HTA scripts.
http://www.robvanderwoude.com/vbstech_ui_password.php
http://davebritt.blogspot.com/2006/08/using-hta-to-hide-credentials.html
http://www.robvanderwoude.com/vbstech_ui_password.php
http://davebritt.blogspot.com/2006/08/using-hta-to-hide-credentials.html
Function GetPassword( myPrompt )
' This function uses Internet Explorer to
' create a dialog and prompt for a password.
'
' Argument: [string] prompt text, e.g. "Please enter password:"
' Returns: [string] the password typed in the dialog screen
'
' Written by Rob van der Woude
' http://www.robvanderwoude.com
' Error handling code written by Denis St-Pierre
Dim objIE
' Create an IE object
Set objIE = CreateObject( "InternetExplorer.Application" )
' specify some of the IE window's settings
objIE.Navigate "about:blank"
objIE.Document.Title = "Password" & String( 100, vbTab )
objIE.ToolBar = False
objIE.Resizable = False
objIE.StatusBar = False
objIE.Width = 320
objIE.Height = 180
' Center the dialog window on the screen
With objIE.Document.ParentWindow.Screen
objIE.Left = (.AvailWidth - objIE.Width ) \ 2
objIE.Top = (.Availheight - objIE.Height) \ 2
End With
' Wait till IE is ready
Do While objIE.Busy
WScript.Sleep 200
Loop
' Insert the HTML code to prompt for a password
objIE.Document.Body.InnerHTML = "<DIV ALIGN=""center""><P>" & myPrompt _
& "</P>" & vbCrLf _
& "<P><INPUT TYPE=""password"" SIZE=""20"" " _
& "ID=""Password""></P>" & vbCrLf _
& "<P><INPUT TYPE=""hidden"" ID=""OK"" " _
& "NAME=""OK"" VALUE=""0"">" _
& "<INPUT TYPE=""submit"" VALUE="" OK "" " _
& "OnClick=""VBScript:OK.Value=1""></P></DIV>"
' Make the window visible
objIE.Visible = True
' Wait till the OK button has been clicked
On Error Resume Next
Do While objIE.Document.All.OK.Value = 0
WScript.Sleep 200
' Error handling code by Denis St-Pierre
If Err Then 'user clicked red X (or alt-F4) to close IE window
IELogin = Array( "", "" )
objIE.Quit
Set objIE = Nothing
Exit Function
End if
Loop
On Error Goto 0
' Read the password from the dialog window
GetPassword = objIE.Document.All.Password.Value
' Close and release the object
objIE.Quit
Set objIE = Nothing
End Function
Here's a quick sample... If you want any changes, please let me know.
<html>
<head>
<hta:application
ID="objMap"
ApplicationName="Map"
SINGLEINSTANCE="YES"
WINDOWSTATE="MAXIMIZE"
CONTEXTMENU="NO"
SYSMENU="YES"
MINIMIZEBUTTON="NO"
MAXIMIZEBUTTON="NO"
BORDER="THIN"
SCROLL="NO"
/>
<head>
<script language="vbscript">
window.resizeTo 350,190
Dim strWindowTitle
Dim strDriveLetter
Dim strDomain
Dim strUNC
'---------------------------------------------------
' User Variables
'---------------------------------------------------
strWindowTitle="Map Drive"
strDriveLetter="O:"
strDomain="YOURDOMAIN"
strUNC="\\YOURSERVER\YOURSHARE"
'---------------------------------------------------
If right(strDriveLetter,1)<>":" then strDriveLetter=strDriveLetter & ":"
Set WshShell=CreateObject("Wscript.Shell")
set wshNetwork = CreateObject( "WScript.Network" )
Set fso=CreateObject("Scripting.FileSystemObject")
document.title=strWindowTitle
Sub Window_OnLoad
window.MoveTo (screen.availWidth / 2 - (document.body.clientWidth / 2)), _
(screen.availHeight / 2 - (document.body.clientHeight / 2))
txtUsername.focus
End Sub
Sub MapDrive
ON ERROR RESUME NEXT
strUsername=txtUsername.value
strPassword=txtPassword.value
If strUsername="" then
DataArea.innerHTML="Please enter a username."
Exit Sub
End If
If strPassword="" then
DataArea.innerHTML="Please enter a password."
Exit Sub
End If
If fso.FolderExists(strDriveLetter) then
DataArea.innerHTML= strDriveLetter & " is already in use."
Exit Sub
End If
wshNetwork.MapNetworkDrive strDriveLetter, strUNC,,strUsername, strPassword
If err.number <> 0 then
DataArea.innerHTML="Error mapping drive " & strDriveLetter
'Comment the following line to hide the actual error
DataArea.innerHTML=DataArea.innerHTML & "<br><br>" & err.description
Else
If fso.FolderExists(strDriveLetter) then
DataArea.innerHTML="Drive " & strDriveletter & " mapped successfully."
End If
End If
End Sub
</script>
<style>
body
{
font: 10pt arial;
background-color: buttonface;
}
td {
font: 10pt arial;
}
button {
border: 2px solid darkgray;
}
</style>
</head>
<body>
<table>
<tr>
<td>
<u>U</u>sername:
</td>
<td>
<input type="text" name="txtUsername" accesskey="u">
</td>
<td>
</td>
</tr>
<tr>
<td>
<u>P</u>assword:
</td>
<td>
<input type="password" name="txtPassword" accesskey="p">
</td>
<td>
<button onclick="MapDrive" accesskey="m"><u>M</u>ap</button>
</td>
</tr>
</table>
<br>
<div id="DataArea"></div>
</body>
</html>
ASKER
Hi jostrander,
The HTA needs run a vbscript in the UNC path with the alternate credentials e.g. if i have the vbscript in \\MYSERVER.DOMAINB\MYSHARE \testscrip t.vbs, this script shoud be run with the credentials I input to the HTA.
The HTA needs run a vbscript in the UNC path with the alternate credentials e.g. if i have the vbscript in \\MYSERVER.DOMAINB\MYSHARE
Oh, I think I understand better now. You want an HTA to execute a .vbs but with alternate credentials. Will the actual process for the vbs be created locally or on a remote server?
Scratch that last question, I reread your original post and see now that you are wanting to launch a login script from an alternate domain. I'll see what I can do. I may have to go home soon though, so if anyone has time, feel free to jump in :)
Ok, give this a try.
I have it do a net use first, but WITHOUT mapping a drive. This will just open a pipe to the server.
After that, it checks to see if the login script exists. If it does it runs it.
I've tested it across domains and it seems to be working well for me.
I have it do a net use first, but WITHOUT mapping a drive. This will just open a pipe to the server.
After that, it checks to see if the login script exists. If it does it runs it.
I've tested it across domains and it seems to be working well for me.
<html>
<head>
<hta:application
ID="objRemoteScript"
ApplicationName="RemoteScript"
SINGLEINSTANCE="YES"
WINDOWSTATE="MAXIMIZE"
CONTEXTMENU="NO"
SYSMENU="YES"
MINIMIZEBUTTON="NO"
MAXIMIZEBUTTON="NO"
BORDER="THIN"
SCROLL="NO"
/>
<head>
<script language="vbscript">
window.resizeTo 350,190
Dim strWindowTitle
Dim strDomain
Dim strLoginScript
'---------------------------------------------------
' User Variables
'---------------------------------------------------
strWindowTitle="Run Remote Script"
strLoginScript="\\YOURSERVER\YOURSHARE\test.vbs"
strDomain="REMOTEDOMAIN"
'---------------------------------------------------
If right(strDriveLetter,1)<>":" then strDriveLetter=strDriveLetter & ":"
Set WshShell=CreateObject("Wscript.Shell")
Set fso=CreateObject("Scripting.FileSystemObject")
document.title=strWindowTitle
Sub Window_OnLoad
window.MoveTo (screen.availWidth / 2 - (document.body.clientWidth / 2)), _
(screen.availHeight / 2 - (document.body.clientHeight / 2))
txtUsername.focus
End Sub
Sub RunScript
strUsername=txtUsername.value
strPassword=txtPassword.value
If strUsername="" then
DataArea.innerHTML="Please enter a username."
Exit Sub
End If
If strPassword="" then
DataArea.innerHTML="Please enter a password."
Exit Sub
End If
pos=InstrRev(strLoginScript,"\")-1
strUNC=left(strLoginScript,pos)
strCMD = "net use " & strUNC & " /user:" & strDomain & "\" & strUserName & " " & strPassword
WshShell.run strCMD,0,true
If fso.FileExists(strLoginScript) then
WshShell.run strLoginScript,,true
DataArea.innerHTML="Script ran successfully."
Else
DataArea.innerHTML="Error running script."
End If
End Sub
</script>
<style>
body
{
font: 10pt arial;
background-color: buttonface;
}
td {
font: 10pt arial;
}
button {
border: 2px solid darkgray;
}
</style>
</head>
<body>
<table>
<tr>
<td>
<u>U</u>sername:
</td>
<td>
<input type="text" name="txtUsername" accesskey="u">
</td>
<td>
</td>
</tr>
<tr>
<td>
<u>P</u>assword:
</td>
<td>
<input type="password" name="txtPassword" accesskey="p">
</td>
<td>
<button onclick="RunScript" accesskey="r"><u>R</u>un Script</button>
</td>
</tr>
</table>
<br>
<div id="DataArea"></div>
</body>
</html>
Hi, here's a HTA I wrote about 18 months ago to run a second program with alternate credentials.
It uses PSExec, located in the same folder as the HTA file. Change strSecondProgram to point to the second script you want to run.
Regards,
Rob.
It uses PSExec, located in the same folder as the HTA file. Change strSecondProgram to point to the second script you want to run.
Regards,
Rob.
<html>
<head>
<title>Run Program With Alternate Credentials</title>
<HTA:APPLICATION
APPLICATIONNAME="Run Program With Alternate Credentials"
BORDER="thin"
SCROLL="no"
SINGLEINSTANCE="yes"
WINDOWSTATE="normal"
>
<script language="VBScript">
Dim strPSExecPath
Dim strComputer
Dim strSecondProgram
Sub Window_onLoad
intWidth = 600
intHeight = 480
Me.ResizeTo intWidth, intHeight
Me.MoveTo ((Screen.Width / 2) - (intWidth / 2)),((Screen.Height / 2) - (intHeight / 2))
Set objFSO = CreateObject("Scripting.FileSystemObject")
If Mid(document.location, 6, 3) = "///" Then
strHTAPath = Mid(Replace(Replace(document.location, "%20", " "), "/", "\"), 9)
Else
strHTAPath = Mid(Replace(Replace(document.location, "%20", " "), "/", "\"), 6)
End If
strPSExecPath = Left(strHTAPath, InStrRev(strHTAPath, "\")) & "psexec.exe"
strSecondProgram = Left(strHTAPath, InStrRev(strHTAPath, "\")) & "Script2.vbs"
'strSecondProgram = "C:\Program Files\Internet Explorer\iexplore.exe"
If objFSO.FileExists(strPSExecPath) Then
strPSExecPath = objFSO.GetFile(strPSExecPath).ShortPath
Else
MsgBox "Could not find PSExec at:" & VbCrLf & strPSExecPath
Window.Close
End If
Set objNetwork = CreateObject("WScript.Network")
strComputer = objNetwork.ComputerName
txt_username.Focus
End Sub
Sub Default_Buttons
If Window.Event.KeyCode = 13 Then
btn_submit.Click
End If
End Sub
Sub Run_Second_Program
If txt_username.Value = "" Then
MsgBox "Please enter a user name."
txt_username.Focus
ElseIf txt_password.Value = "" Then
MsgBox "Please enter a password."
txt_password.Focus
Else
Set objShell = CreateObject("WScript.Shell")
strUser = txt_username.Value
strPass = txt_password.Value
If Right(LCase(strSecondProgram), 4) = ".hta" Then
strCommand = strPSExecPath & " -accepteula -i -d -u " & strUser & " -p " & strPass & " \\" & strComputer & " mshta.exe """ & strSecondProgram & """"
ElseIf Right(LCase(strSecondProgram), 4) = ".vbs" Then
strCommand = strPSExecPath & " -accepteula -i -d -u " & strUser & " -p " & strPass & " \\" & strComputer & " wscript.exe """ & strSecondProgram & """"
Else
strCommand = strPSExecPath & " -accepteula -i -d -u " & strUser & " -p " & strPass & " \\" & strComputer & " """ & strSecondProgram & """"
End If
' MsgBox strCommand
' Exit Code 1326 is invalid password from PSExec 1.85
strExitCode = objShell.Run(strCommand, 0, True)
If strExitCode = 1326 Then
MsgBox "Username or Password invalid. Please verify your credentials."
txt_password.Value = ""
txt_password.Focus
Else
window.close
End If
End If
End Sub
</script>
</head>
<body style="background-color:#B0C4DE" onkeypress='vbs:Default_Buttons'>
<table width='90%' height='100%' align='center' border='0'>
<tr>
<td align="center" style="font-family: arial; font-size: 24px; font-weight: bold;">
Run Program With Alternate Credentials
</td>
</tr>
<tr>
<td align='center' style="font-family: arial; font-size: 16px; font-weight: bold;">
Enter username: <input type="text" maxlength="30" size="40" id="txt_username" name="txt_username" style="font-size: 14px;"><BR><BR>
Enter password: <input type="password" maxlength="30" size="40" id="txt_password" name="txt_password" style="font-size: 14px;"><BR>
<br>Note: Username must be DOMAIN\UserName
</td>
</tr>
<tr>
<td align='center'>
<input type="button" value="Go!" name="btn_submit" onClick="vbs:Run_Second_Program" style="font-size: 16px;"><br><br>
</td>
</tr>
</table>
</body>
</html>
line 38 can be removed from there... rushing to go home :D
ASKER
Hi Jostrander,
I could run the script fine but it starts up with the windows logon creds, not with the userid and password that a put into the HTA.
I could run the script fine but it starts up with the windows logon creds, not with the userid and password that a put into the HTA.
Ah, I see. I'm having it map over to the other domain using the username/password you enter and then execute the remote script in the profile of the currently logged on user. This is normally what I would want in my environment... unless I wanted the script run in a different profile or at elevated privileges.
Just so we're on the same page, you are wanting the remote script to execute locally, but with credentials from another domain? If that's correct, then the tool Rob mentioned (psexec) would need to be used here. There is a potential issue with this though, if the local computer is in domainA and the command is run with domainB credentials, the domainB credentials must have proper permissions to the local computer and it might not run in the proper profile.
If all the trust relationships and permissions are set properly however, this method would work fine.
Is the remote script creating a process on a remote server? If so, we can do that without psexec. Can you elaborate a bit on what the remote script is doing?
Thanks,
Joe
Just so we're on the same page, you are wanting the remote script to execute locally, but with credentials from another domain? If that's correct, then the tool Rob mentioned (psexec) would need to be used here. There is a potential issue with this though, if the local computer is in domainA and the command is run with domainB credentials, the domainB credentials must have proper permissions to the local computer and it might not run in the proper profile.
If all the trust relationships and permissions are set properly however, this method would work fine.
Is the remote script creating a process on a remote server? If so, we can do that without psexec. Can you elaborate a bit on what the remote script is doing?
Thanks,
Joe
1 more thing...
If all the remote script is doing is mapping drives in domainB... there's no reason at all that you cannot have it map with domainB credentials, yet run in domainA user's profile... this is preferred.
If all the remote script is doing is mapping drives in domainB... there's no reason at all that you cannot have it map with domainB credentials, yet run in domainA user's profile... this is preferred.
ASKER
Hi Jostrander,
Your assumption that the script is mapping drives is correct, but two domain's are managed by different supports teams with each having no access on the other domain.
Access management on both domain is by separate groups and its preferable to map the drives in Domain B with Domain B credentials even though the user is logging into a machine in domain A with Domain A creds.
Your assumption that the script is mapping drives is correct, but two domain's are managed by different supports teams with each having no access on the other domain.
Access management on both domain is by separate groups and its preferable to map the drives in Domain B with Domain B credentials even though the user is logging into a machine in domain A with Domain A creds.
Hi, have you tried mine? Does it work for your situation at all? I haven't tried it across domains?
Rob.
Rob.
ASKER
Hi Rob,
I haven't tried your solution yet, will test it today and update.
I haven't tried your solution yet, will test it today and update.
I think I know why my method isn't working for you...
In my testing, the remote script is on the same server as all the shares that I'm mapping to. I'm opening a pipe to this server with alternate credentials. When the remote script launches, the Secondary Logon Service uses this pipe to map the drive. This works fine in my testing because all the shares that I'm mapping to are on the same server as the the remote script.
As you said, the script launches for you (proof that secondary logon service is accessing the script using alternate credentials), but if that script includes mappings to other servers, it won't work. This can be remedied by opening a pipe to each of the other servers before attempting to launch the remote script.
I could add some code fairly quickly to do this. 1 method would be to add a list of remote servers in the HTA, or have the HTA read the remote script to gather the remote server names.
If you're interested in trying something like this, let me know.
Thanks,
Joe
In my testing, the remote script is on the same server as all the shares that I'm mapping to. I'm opening a pipe to this server with alternate credentials. When the remote script launches, the Secondary Logon Service uses this pipe to map the drive. This works fine in my testing because all the shares that I'm mapping to are on the same server as the the remote script.
As you said, the script launches for you (proof that secondary logon service is accessing the script using alternate credentials), but if that script includes mappings to other servers, it won't work. This can be remedied by opening a pipe to each of the other servers before attempting to launch the remote script.
I could add some code fairly quickly to do this. 1 method would be to add a list of remote servers in the HTA, or have the HTA read the remote script to gather the remote server names.
If you're interested in trying something like this, let me know.
Thanks,
Joe
ASKER
Hi Jostrander,
I am fine with trying what you are suggesting, but considering that we have a farm of hundreds of servers spilt in to 6 different dev, test, preprod & prod environments, it seems a bit cumbersome. I'll try to get hold of the actual drive mapping script from the dev team and post it here shortly so you can have a better idea about what I am trying to achieve.
I am fine with trying what you are suggesting, but considering that we have a farm of hundreds of servers spilt in to 6 different dev, test, preprod & prod environments, it seems a bit cumbersome. I'll try to get hold of the actual drive mapping script from the dev team and post it here shortly so you can have a better idea about what I am trying to achieve.
You should only need to authenticate to the root server on Domain B once this is done than all the shares pertaining to that user should become available.
You could also use something like AutoIT Script
See the code below, which you can compile into an executable once you've downloaded and installed AutoIT. I just wrote it in the last 30 minutes and so it's not tested or anything but should do the trick.
AutoIT is free and can be downloaded from www.autoitscripts.com
Cheers
You could also use something like AutoIT Script
See the code below, which you can compile into an executable once you've downloaded and installed AutoIT. I just wrote it in the last 30 minutes and so it's not tested or anything but should do the trick.
AutoIT is free and can be downloaded from www.autoitscripts.com
Cheers
#include <EditConstants.au3>
#include <GUIConstantsEx.au3>
GUICreate('My Logon Window', 280, 100)
GUISetBkColor(0xFFFFFF)
GUISetFont(8, 400, -1, 'Tahoma')
GUICtrlCreateLabel('UserName:', 10, 12)
$GUI_USERNAME = GUICtrlCreateInput('', 70, 10, 195, 20)
GUICtrlCreateLabel('Password:', 10, 42)
$GUI_PASSWORD = GUICtrlCreateInput('', 70, 40, 195, 20, $ES_PASSWORD)
$MAPSHARE = GUICtrlCreateButton('Connect...', 120, 70, 70, 20)
$GUICLOSE = GUICtrlCreateButton('Exit', 195, 70, 70, 20)
GUISetState()
While 1
$MSG = GUIGetMsg()
Switch $MSG
Case $GUI_EVENT_CLOSE
Exit
Case $GUICLOSE
Exit
Case $MAPSHARE
FNC_MAPSHARE()
Exit
EndSwitch
WEnd
Func FNC_MAPSHARE()
$USERNAME = GUICtrlRead($GUI_USERNAME)
$PASSWORD = GUICtrlRead($GUI_PASSWORD)
DriveMapAdd('X:', '\\SERVER.DOMAINB.COM\SHARE', 0, $USERNAME, $PASSWORD)
If @error > 0 Then FNC_MAPERROR(@error)
DriveMapAdd('Y:', '\\SERVER.DOMAINB.COM\SHARE', 0, $USERNAME, $PASSWORD)
If @error > 0 Then FNC_MAPERROR(@error)
DriveMapAdd('Z:', '\\SERVER.DOMAINB.COM\SHARE', 0, $USERNAME, $PASSWORD)
If @error > 0 Then FNC_MAPERROR(@error)
EndFunc
Func FNC_MAPERROR($TMP_MAPERROR)
If $TMP_MAPERROR = 1 Then
MsgBox(0, 'Map Drive Error', 'Undefined Error, please check your username and/or password.')
ElseIf $TMP_MAPERROR = 2 Then
MsgBox(0, 'Map Drive Error', 'Access to the remote share was denied.')
ElseIf $TMP_MAPERROR = 3 Then
MsgBox(0, 'Map Drive Error', 'The Drive Letter is already assigned.')
ElseIf $TMP_MAPERROR = 4 Then
MsgBox(0, 'Map Drive Error', 'Invalid Drive Letter.')
ElseIf $TMP_MAPERROR = 5 Then
MsgBox(0, 'Map Drive Error', 'Invalid Remote Share.')
ElseIf $TMP_MAPERROR = 6 Then
MsgBox(0, 'Map Drive Error', 'Invalid Password.')
EndIf
EndFunc
ScreenShot.jpg
I hate to say it, but I think anything we come up with here is going to be a kludge unless a trust relationship is established between the domains or we rewrite a script for your domain to map drives to the remote domain.
1) Even if you did a method like I was talking about (opening a pipe to each server that exists in the remote script)... the remote script may have conditionals in it... if member of this group do this, etc...
2) If you run a tool like PSEXEC, the credentials you use in the command must have permission to run the process on the local computer. Since the credentials are in another domain, this will fail... much like doing a "runas /user:pcname\xxxxx ..." when user xxxxx doesn't exist on the local PC.
3) AutoIT is a cool tool and maybe you'd want to use it... but this example is essentially a login script rewrite, like my 1st post (not a remote script launcher).
I'd have to say that considering you are in a large environment and have no domain trust, the best option would be to write a new secondary login script, local to your domain. In this login script, pass the remote credentials with each mapping (like my 1st post or matrixnz's).
1) Even if you did a method like I was talking about (opening a pipe to each server that exists in the remote script)... the remote script may have conditionals in it... if member of this group do this, etc...
2) If you run a tool like PSEXEC, the credentials you use in the command must have permission to run the process on the local computer. Since the credentials are in another domain, this will fail... much like doing a "runas /user:pcname\xxxxx ..." when user xxxxx doesn't exist on the local PC.
3) AutoIT is a cool tool and maybe you'd want to use it... but this example is essentially a login script rewrite, like my 1st post (not a remote script launcher).
I'd have to say that considering you are in a large environment and have no domain trust, the best option would be to write a new secondary login script, local to your domain. In this login script, pass the remote credentials with each mapping (like my 1st post or matrixnz's).
If your remote script is pretty basic... here's a sample of what I have working:
<html>
<head>
<hta:application
ID="objRemoteScript"
ApplicationName="RemoteScript"
SINGLEINSTANCE="YES"
WINDOWSTATE="MAXIMIZE"
CONTEXTMENU="NO"
SYSMENU="YES"
MINIMIZEBUTTON="NO"
MAXIMIZEBUTTON="NO"
BORDER="THIN"
SCROLL="NO"
/>
<head>
<script language="vbscript">
window.resizeTo 350,190
Dim strWindowTitle
Dim strDomain
Dim strLoginScript
Dim strServerList
Dim strUsername
Dim strPassword
'---------------------------------------------------
' User Variables
'---------------------------------------------------
strWindowTitle="Run Remote Script"
strLoginScript="\\dc1\netlogon\logon.vbs"
strServerList="dc1,fs1"
strDomain="SOMEDOMAIN"
'---------------------------------------------------
If right(strDriveLetter,1)<>":" then strDriveLetter=strDriveLetter & ":"
Set WshShell=CreateObject("Wscript.Shell")
Set fso=CreateObject("Scripting.FileSystemObject")
document.title=strWindowTitle
Sub Window_OnLoad
window.MoveTo (screen.availWidth / 2 - (document.body.clientWidth / 2)), _
(screen.availHeight / 2 - (document.body.clientHeight / 2))
txtUsername.focus
End Sub
Sub RunScript
strUsername=txtUsername.value
strPassword=txtPassword.value
If strUsername="" then
DataArea.innerHTML="Please enter a username."
Exit Sub
End If
If strPassword="" then
DataArea.innerHTML="Please enter a password."
Exit Sub
End If
pos=InstrRev(strLoginScript,"\")-1
strUNC=left(strLoginScript,pos)
arrServers=split(strServerList,",")
For each strHost in arrServers
OpenPipe strHost
Next
If fso.FileExists(strLoginScript) then
WshShell.run strLoginScript,,true
DataArea.innerHTML="Script ran successfully."
Else
DataArea.innerHTML="Error running script."
End If
End Sub
Sub OpenPipe(strServer)
strCMD = "net use \\" & strServer & "\ipc$ /user:" & strDomain & "\" & strUserName & " " & strPassword
WshShell.run strCMD,,true
End Sub
</script>
<style>
body
{
font: 10pt arial;
background-color: buttonface;
}
td {
font: 10pt arial;
}
button {
border: 2px solid darkgray;
}
</style>
</head>
<body>
<table>
<tr>
<td>
<u>U</u>sername:
</td>
<td>
<input type="text" name="txtUsername" accesskey="u">
</td>
<td>
</td>
</tr>
<tr>
<td>
<u>P</u>assword:
</td>
<td>
<input type="password" name="txtPassword" accesskey="p">
</td>
<td>
<button onclick="RunScript" accesskey="r"><u>R</u>un Script</button>
</td>
</tr>
</table>
<br>
<div id="DataArea"></div>
</body>
</html>
and here's the other example I mentioned... where it makes a list of servers found in the remote script and opens a pipe to each, then runs the remote script.
This works for me, but only because my remote script is very simple:
-->
set wshNetwork = CreateObject( "WScript.Network" )
wshNetwork.MapNetworkDrive "X:", "\\FS1\VOL1"
wshNetwork.MapNetworkDrive "Y:", "\\Fs2\something"
wshNetwork.MapNetworkDrive "Z:", "\\FS3\USER\BOOKS"
<--
Chances are that yours is much more complicated, so this is probably still a bad idea... but here it is anyway... for fun :)
This works for me, but only because my remote script is very simple:
-->
set wshNetwork = CreateObject( "WScript.Network" )
wshNetwork.MapNetworkDrive
wshNetwork.MapNetworkDrive
wshNetwork.MapNetworkDrive
<--
Chances are that yours is much more complicated, so this is probably still a bad idea... but here it is anyway... for fun :)
<html>
<head>
<hta:application
ID="objRemoteScript"
ApplicationName="RemoteScript"
SINGLEINSTANCE="YES"
WINDOWSTATE="MAXIMIZE"
CONTEXTMENU="NO"
SYSMENU="YES"
MINIMIZEBUTTON="NO"
MAXIMIZEBUTTON="NO"
BORDER="THIN"
SCROLL="NO"
/>
<head>
<script language="vbscript">
window.resizeTo 350,190
Dim strWindowTitle
Dim strDomain
Dim strLoginScript
Dim strServerList
Dim strUsername
Dim strPassword
Dim oDict
Set oDict = CreateObject("Scripting.Dictionary")
'---------------------------------------------------
' User Variables
'---------------------------------------------------
strWindowTitle="Run Remote Script"
strLoginScript="\\fs1\blah\test5.vbs"
strDomain="MYDOMAIN"
'---------------------------------------------------
If right(strDriveLetter,1)<>":" then strDriveLetter=strDriveLetter & ":"
Set WshShell=CreateObject("Wscript.Shell")
Set fso=CreateObject("Scripting.FileSystemObject")
document.title=strWindowTitle
Sub Window_OnLoad
window.MoveTo (screen.availWidth / 2 - (document.body.clientWidth / 2)), _
(screen.availHeight / 2 - (document.body.clientHeight / 2))
txtUsername.focus
End Sub
Sub CheckKey
If window.event.keycode=13 then RunScript
End Sub
Sub RunScript
strUsername=txtUsername.value
strPassword=txtPassword.value
If strUsername="" then
DataArea.innerHTML="Please enter a username."
Exit Sub
End If
If strPassword="" then
DataArea.innerHTML="Please enter a password."
Exit Sub
End If
tmp=split(strLoginScript,"\\")(1)
pos=Instr(tmp,"\")-1
strServer=left(tmp,pos)
OpenPipe strServer
GetServerList
For each strHost in oDict.Keys
'msgbox strHost
OpenPipe strHost
Next
If fso.FileExists(strLoginScript) then
WshShell.run strLoginScript,,true
DataArea.innerHTML="Script ran successfully."
Else
DataArea.innerHTML="Error running script."
End If
End Sub
Sub GetServerList
oDict.RemoveAll
Set fso=CreateObject("Scripting.FileSystemObject")
Set oFile=fso.OpenTextFile(strLoginScript,1)
text=oFile.ReadAll
oFile.Close
arrLines=split(text,vbCrLf)
For each line in arrLines
strServer=""
pos=0
pos=instr(line,"\\")
If pos > 0 then
tmp=split(line,"\\")(1)
If instr(tmp,"\") then
posB=""
strServer=""
posB=Instr(tmp,"\")-1
strServer=lcase(left(tmp,posB))
If NOT oDict.Exists(strServer) then
If GetPing(strServer)=True then
oDict.Add strServer,strServer
End If
End If
End If
End If
Next
End Sub
Function GetPing(host)
Set objPing = GetObject("winmgmts:{impersonationLevel=impersonate}")._
ExecQuery("select * from Win32_PingStatus where address = '"_
& host & "'")
For Each objStatus in objPing
If IsNull(objStatus.StatusCode) or objStatus.StatusCode<>0 Then
test=False
Else
test=True
End If
Next
If test=True then
GetPing=True
Else
GetPing=False
End If
End Function
Sub OpenPipe(strServer)
strCMD = "net use \\" & strServer & "\ipc$ /user:" & strDomain & "\" & strUserName & " " & strPassword
WshShell.run strCMD,0,true
End Sub
</script>
<style>
body
{
font: 10pt arial;
background-color: buttonface;
}
td {
font: 10pt arial;
}
button {
border: 2px solid darkgray;
}
</style>
</head>
<body onkeypress="CheckKey">
<table>
<tr>
<td>
<u>U</u>sername:
</td>
<td>
<input type="text" name="txtUsername" accesskey="u">
</td>
<td>
</td>
</tr>
<tr>
<td>
<u>P</u>assword:
</td>
<td>
<input type="password" name="txtPassword" accesskey="p">
</td>
<td>
<button onclick="RunScript" accesskey="r" ><u>R</u>un Script</button>
</td>
</tr>
</table>
<br>
<div id="DataArea"></div>
</body>
</html>
Hey wait a second....I think we might be approaching this all wrong. As Joe stated, we need to set up a trust to the remote server, so what if we use CmdKey to add credentials that are to be used for any connections to a particular server?
See here:
https://www.experts-exchange.com/questions/23199300/VBScript-map-drives-when-not-a-domain-member.html
What that tries to do is provide credentials for any connection to strServer, then at this section
' Do other tasks if required
you can add the drive mapping code needed.
I think the main problem of mine and Joe's approach is that we are launching a script using alternate credentials, which means any drive mapping is going to occur in *that* user profile, and not the currently logged in one that you're after.
Regards,
Rob.
See here:
https://www.experts-exchange.com/questions/23199300/VBScript-map-drives-when-not-a-domain-member.html
What that tries to do is provide credentials for any connection to strServer, then at this section
' Do other tasks if required
you can add the drive mapping code needed.
I think the main problem of mine and Joe's approach is that we are launching a script using alternate credentials, which means any drive mapping is going to occur in *that* user profile, and not the currently logged in one that you're after.
Regards,
Rob.
ASKER CERTIFIED SOLUTION
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Thanks Joe....you haven't specified the server in your /add: parameter of CmdKey....I didn't know you could do that, but that saves some time if you use the same credentials for multiple connections.
Should you remove the credentials afterwards, in case things change later?
Regards,
Rob.
Should you remove the credentials afterwards, in case things change later?
Regards,
Rob.
yeah, I was surprised myself. I did my testing on an XP host that was not part of any domain. Tried connecting to several servers prior to launching (none connected). After launching and logging into the HTA, all drives mapped and I could access any server I wanted.
I can't think of any reason why the credentials would need to be removed after. They should disappear on logoff or reboot.
I can't think of any reason why the credentials would need to be removed after. They should disappear on logoff or reboot.
Oh cool. I thought they were persistent. Anyway, thanks for rewriting the HTA.
Rob.
Rob.
You are right Rob, they are persistent.
SunshineVK, if the last script works for you, we will probably want to add a line after the script finishes.
Before the End Sub on the RunScript sub, something like:
WshShell.run "cmdkey /delete:*",0
SunshineVK, if the last script works for you, we will probably want to add a line after the script finishes.
Before the End Sub on the RunScript sub, something like:
WshShell.run "cmdkey /delete:*",0
ASKER
Jostrander/ Rob,
This works !!!!
I'll play around with this today and let you guys know if I run into any bugs.
Thanks
This works !!!!
I'll play around with this today and let you guys know if I run into any bugs.
Thanks
Find any bugs?
SunshineVK, any update on where you're at with this?
Rob.
Rob.
ASKER
The login script in the other domain wasn't getting executed with credentials passed using this. We had to convert all this code to VB and convert the login script to an executable to make it all work.
https://www.experts-exchange.com/questions/25536690/Run-a-VB-Script-as-a-different-domain-account.html?cid=1133&anchorAnswerId=29119217#a29119217