I once had an interesting app, or better say a bundle of apps. It was not about the apps, but about the fact that the customer wanted the installation to be done from a remote server. You may say ok sooo what’s the big deal?
When you create an app in SCCM and put it to run with Administrative rights, the system context “user” is the one who does the job, not your user that you are currently logged in with, even if it’s an administrator. The share/server was accessible to almost all the users, but the access was given per user, not per machine. Of course it makes sense to give the permissions per user so you don’t have to add/clean machines all the time from the database.
But when you try to install that MSI from the share you will end up with an error something like, the media was not found or is not accessible. That’s because you have to login with your user first in order to have access first.
As you know VBScript is not so friendly with messageboxes, it doesn’t let you make something customizable, after reading some of the documentation i was certain it’s impossible to do this with VBScript. However, i remembered that you can use a Internet Explorer application and pass the variables trough it.
This was along time ago so i don’t remember over what post i’ve encoutered and i found something similar to what i was searching for. I have added some functionality like hidden password field, not null checks, etc.
So how does the script look like?
' Core variable definitions --------------------------------------------------- ' strComputer = "." Set oSH = CreateObject("WScript.Shell") Set NetworkObject = CreateObject("WScript.Network") Set objFSO = CreateObject("Scripting.FileSystemObject") Set objCtx = CreateObject("WbemScripting.SWbemNamedValueSet") Set objShell = CreateObject("Wscript.Shell") objCtx.Add "__ProviderArchitecture", 64 Set objLocator = CreateObject("Wbemscripting.SWbemLocator") Set objServices = objLocator.ConnectServer("","root\default","","",,,,objCtx) Set objReg1 = objServices.Get("StdRegProv") Set objReg=GetObject("winmgmts:{impersonationLevel=impersonate}!\\" & strComputer & "\root\default:StdRegProv") scriptDir = left(WScript.ScriptFullName,(Len(WScript.ScriptFullName))-(len(WScript.ScriptName))) '-----------------------Show input for user-------------------------------- ' strPw = GetPassword( "Please input your username and password:") arrArgs = Split(strPw, " ") retval=arrArgs(0) retval2=arrArgs(1) If retval <> "" Then Usernameretval = retVal Else wscript.quit(900) End If If retval2 <> "" Then Passwordretval = retVal2 Else wscript.quit(900) End If '################################################################################################################ '# Show login window # '################################################################################################################ Function GetPassword( myPrompt ) ' This function uses Internet Explorer to ' create a dialog and prompt for a username and password(hidden text). Dim objIE Set objIE = WScript.CreateObject("InternetExplorer.Application", "IE_") objIE.Navigate "about:blank" objIE.Document.Title = "Please input your account credentials" objIE.ToolBar = False objIE.Resizable = False objIE.StatusBar = False objIE.Width = 400 objIE.Height = 250 Set objWMIService = GetObject("Winmgmts:\\.\root\cimv2") Set colItems = objWMIService.ExecQuery("Select * from Win32_DesktopMonitor",,48) For Each objItem in colItems intScreenHeight = objItem.ScreenHeight intScreenWidth = objItem.ScreenWidth Next If intScreenHeight <> "" AND intScreenWidth <> "" Then objIE.Left = ( intScreenWidth - objIE.Width ) \ 2 objIE.Top = ( intScreenHeight - objIE.Height ) \ 2 End If objIE.Document.Body.InnerHTML = "<DIV align='center'><P>" & myPrompt _ & "</P>" & vbCrLf _ & "<P>Username: <INPUT TYPE='text' SIZE= '20'" _ & "ID='UserName'></P>" & vbCrLf _ & "<P>Password: <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>" objIE.Visible = True Do While objIE.Document.All.OK.Value = 0 WScript.Sleep 200 Loop GetPassword = objIE.Document.All.UserName.Value & " " & objIE.Document.All.Password.Value objIE.Quit Set objIE = Nothing End Function
Ok so let’s break down the code a little bit shall we?
Dim objIE Set objIE = WScript.CreateObject("InternetExplorer.Application", "IE_") objIE.Navigate "about:blank" objIE.Document.Title = "Please input your account credentials" objIE.ToolBar = False objIE.Resizable = False objIE.StatusBar = False objIE.Width = 400 objIE.Height = 250
We create an object which is an InternetExplorer.Application. We give it a title, set it to open a blank page and give it some size.
Set objWMIService = GetObject("Winmgmts:\\.\root\cimv2") Set colItems = objWMIService.ExecQuery("Select * from Win32_DesktopMonitor",,48) For Each objItem in colItems intScreenHeight = objItem.ScreenHeight intScreenWidth = objItem.ScreenWidth Next If intScreenHeight <> "" AND intScreenWidth <> "" Then objIE.Left = ( intScreenWidth - objIE.Width ) \ 2 objIE.Top = ( intScreenHeight - objIE.Height ) \ 2 End If
Using WMI we query the monitor rezolution and we set the window to open in the middle of the screen.
objIE.Document.Body.InnerHTML = "<DIV align='center'><P>" & myPrompt _ & "</P>" & vbCrLf _ & "<P>Username: <INPUT TYPE='text' SIZE= '20'" _ & "ID='UserName'></P>" & vbCrLf _ & "<P>Password: <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>" objIE.Visible = True Do While objIE.Document.All.OK.Value = 0 WScript.Sleep 200 Loop
We create a simple HTML that has two fields. Username which will be visible text, and password which is hidden. Also we place the OK button with an OnClick event. As you can see, as long as the OK value is 0 the window is running. The moment we hit the OK button we send to VBScript the OK value 1, which allows us to continue to the next lines:
GetPassword = objIE.Document.All.UserName.Value & " " & objIE.Document.All.Password.Value objIE.Quit Set objIE = Nothing
We get the username and password that the user has input, store it in the function and close the IE object (window).
As you can see we have a variable in which we keep the information received:
strPw = GetPassword( "Please input your username and password:")
We then split the string
arrArgs = Split(strPw, " ") retval=arrArgs(0) retval2=arrArgs(1) If retval <> "" Then Usernameretval = retVal Else wscript.quit(900) End If If retval2 <> "" Then Passwordretval = retVal2 Else wscript.quit(900) End If
And there you go, an easy and simple script if you ever need it in the future. It can be used in an external install script or inside the MSI as a Custom Action.
In the end it will look like this:
You can customize the HTML to place as many fields as you need. You can also add more buttons and just check what value you send trough them. For example you can place a Cancel button
"<INPUT TYPE='submit' VALUE='OK'" _ & "OnClick='VBScript:OK.Value=1'></P></DIV>"
But overall is an easy to use/customize script.