Adding printer via VBS script - networking

I hope someone can help me with following issue:
I'm trying automatically install network printer: first script asks user for his network credentials and then run second one, installing a printer. Problem is: scripts not throws any errors but no printer added:
Dim objNetwork
Set objNetwork = CreateObject("WScript.Network")
set objShell = WScript.CreateObject("WScript.Shell")
strUserName = InputBox("What is your username? (domain\username)")
objShell.Run "runas /user:" & strUserName & " ""wscript.exe C:\pbg.vbs"" "
pbg.vbs:
Dim objNetwork
Set objNetwork = CreateObject("WScript.Network")
objNetwork.AddWindowsPrinterConnection "\\10.100.1.29\Canon"
objNetwork.SetDefaultPrinter "\\10.100.1.29\Canon"
I made such two-file design because first part is run during boot time and user key-in his username/pass (there can be different users at this shared workstation) and then script use username/pass to call second part of script which is installing network printer
Thank You in advance

You could make the connection in your VBScript to the print server by authenticating right inside the connect string with the user ID/Password.
Place the code you have in front of the code you have for PBG.vbs and do t all within the code itself (faster/cleaner). You could make PBG.vbs a function within new code too.
Here are some links with the different ways:
http://msdn.microsoft.com/en-us/library/aa389290%28v=vs.85%29.aspx
Secure LDAP object manipulation with VBscript using alternate credentials
How to make an Active Directory query from VBScript on a non-domain computer using domain credentials

Doing the same thing basically with Active Directory groups that install printers for users in various parts of the building. Just add them to the group and the associated script fires and installs the printer local to that area of the building.
Since you're also working with a domain environment you don't need the first script. When the user logs on the second script would execute using rights obtained from credentials used during windows log on and the printer would install for them.

Related

Check for file on a remote server in Classic ASP [duplicate]

Is there a good way to access network shares from within a VBS script, with alternative credentials (not the credentials with which the VBS script is running)?
The intention is to perform two tasks:
programmatically navigate a remote share file structure, in order to confirm that a couple of remote files exist, and copy one file over the other (both remote)
copy files from a local drive (accessed with local username / permissions) to a remote drive (accessed with the alternate credentials)
As far as I can tell FSO (Scripting.FileSystemObject) is out of the picture, because it always runs with the credentials of the application using it - which would be the local machine user.(?)
The only viable-seeming approach I have found while googling to prepare a Batch file (or extended call to "cmd.exe") that uses "net use" to provide the remote share credentials, and then copies the files with robocopy or the like, from within the same command-shell "session". This would work OK for copying/deploying files from the local drive to the remote share, but it would ve very complicated and brittle to do any sort of file system browsing (like you would do with FSO) in this way.
Another possibility I have considered involves having two scripting sessions - you call the script (providing the alternate credentials in the command line) and it runs a cmd.exe session, which first does a "net use" to map the remote share to a temporary local drive, then runs itself in an "actually do stuff" mode and uses FSO, then when it's done (back in the cmd.exe shell) disconnects the temporary drive with "net use" again. This is clunky (multiple windows, temporary drive...) and I'm not even sure it would work.
Does anybody know either way, or know of a viable alternative? (sticking to VBScript / WScript on a windows 2000 machine - no PowerShell!)
OK, I was laboring under a misconception - that FSO would not "pick up" the network credentials established with "NET USE" (or Wscript.Network "MapNetworkDrive").
It turns out that it does, and the following sample code works very nicely (without needing to set up temporary network drives):
ServerShare = "\\192.168.3.56\d$"
UserName = "domain\username"
Password = "password"
Set NetworkObject = CreateObject("WScript.Network")
Set FSO = CreateObject("Scripting.FileSystemObject")
NetworkObject.MapNetworkDrive "", ServerShare, False, UserName, Password
Set Directory = FSO.GetFolder(ServerShare)
For Each FileName In Directory.Files
WScript.Echo FileName.Name
Next
Set FileName = Nothing
Set Directory = Nothing
Set FSO = Nothing
NetworkObject.RemoveNetworkDrive ServerShare, True, False
Set ShellObject = Nothing
Set NetworkObject = Nothing

Difference between starting process from Console applciation and ASP.NET application

I have a Web API application that needs to run a Python script which in turn runs a Perl script:) does some otehr stuff and get the output results from it.
The way I do this is with starting a Process:
var start = new ProcessStartInfo()
{
FileName = _pythonPath, //#"C:\Python27\python.exe",
Arguments = arguments, //#"D:\apps\scripts\Process.py
UseShellExecute = false,
RedirectStandardOutput = true,
RedirectStandardError = true
};
using (Process process = Process.Start(start))
{
using (StreamReader reader = process.StandardOutput)
{
var result = reader.ReadToEnd();
var err = process.StandardError.ReadToEnd();
process.WaitForExit();
return result;
}
}
The script inside tries to connect to Perforce server using P4 Python API and then Perl script call a P4 command as well. When running this code from Console application, everything goes fine. The program automatically gets the Perforce settings (I've got a P4V client with all the settings specified). But when running from ASP.NET Web API, it doesn't get the settigns and says that it cannot conenct to perforce:1666 server (I guess this is the standard value when no settign specified).
I do understand that not so many people use Perforce, especially in such way and can help here, but would like to know what is the difference between running this script from Console app and Web API app that mich cause this different behaviour.
One of the most obvious differences between running code from a console application and running code in IIS* is that, usually, the two pieces of code will be running under different user accounts.
Frequently, if you're experiencing issues where code works in one of those situations and not the other, it's a permissions or a per-user-settings issue. You can verify whether this is the case by either running the console application under the same user account that is configured for the appropriate IIS application pool, or vice verse, configure the application pool to use your own user account, and then see whether the problem persists.
If you've confirmed that it's a permissions issue and/or per-user-settings, then you need to decide how you want to fix it. I'd usually recommend not running IIS application pools under your own user account - if you cannot seem to get the correct settings configured for the existing application pool user, I'd usually recommend creating a separate user account (either locally on the machine or as part of your domain, depending on what's required) and giving it just the permissions/settings that it requires to do the job.
*IIS Express being the exception here because it doesn't do application pools and the code does end up running under your own user account.

Documents.Add fails on ASP.NET (VB.NET)

I am having an issue with opening a document using Microsoft Word from ASP.NET MVC.
This works perfectly on my developer machine, but not when deployed to IIS.
Dim word = New Microsoft.Office.Interop.Word.Application
'This line is failing to return a document object
Dim letter = word.Documents.Add(letter_doc_path)
'This line then fails due to [letter] being null
letter.MailMerge.OpenDataSource(csvPath)
I have added permissions in "Component Services" (dcomcnfg) to the NETWORK SERVICE user which allows the creation of the Word object in the first place, but I am completely stuck as what to do with this one.
I have also tried suppressing Word dialogs with the following line just in case
word.DisplayAlerts = Microsoft.Office.Interop.Word.WdAlertLevel.wdAlertsNone
The issue isn't helped by not having an error (apart from the null object reference obviously) - maybe there's a way to query Word for a specific error message?
Word requires the normal.dot template file when opening any document, the problem was occurring because the IIS user didn't have anywhere to create the normal.dot so it was failing in the background.
This was fixed by setting the UserTemplate path for the newly created word instance (immediately after creating it).
The path must be writeable by the IIS user (NETWORK SERVICE in my case).
word.Options.DefaultFilePath(Microsoft.Office.Interop.Word.WdDefaultFilePath.wdUserTemplatesPath) = working_folder
So just for completeness, here's the original example with the winning line included:
Dim word = New Microsoft.Office.Interop.Word.Application
'this line fixed it
word.Options.DefaultFilePath(Microsoft.Office.Interop.Word.WdDefaultFilePath.wdUserTemplatesPath) = working_folder
Dim letter = word.Documents.Add(letter_doc_path)
I was having the same problem, and the settings that wheelibin suggested weren't enough to create documents using the NETWORK SERVICE account.
What I ended up doing is:
Create a user account for this
process to run under.
Login as the user and run Word (this
does various setup tasks in Word so
the application doesn't try putting
up modal dialogs when running as a
service).
Create a new application pool and set
the pool to run as the user account.
If you're using Windows
Authentication, and your server is
Windows 2003 (or 2000, presumably),
then this issue applies, and you
need to either change the SPN of the
server, which will break Windows
Authentication for any application
running under a different user
account, or you have to switch the
authentication provider over to NTLM
instead of Kerberos.
IIS 7 can use Kernel Mode Authentication to avoid the issue.
I am not sure how are you catching the errors.
Please take a look at the following pages if you find some clue from that.
Error while using Microsoft Office 2003 in web application
Error while calling MS-Word from ASP.NET
"There is insufficient memory or disk space. Save the document now" - Opening MS Word from ASP.NET

SDelete called from asp.net page

I want to use SDelete after some code is run on an asp.net page. SDelete is a command line tool. My specific question is has anyone been able to run this SDelete from an asp.net page? More generic question would be, how do you run a command line utility from an asp.net page?
thanks
You can run a command line utility using the Process Class
Process myProcess = new Process();
myProcess.StartInfo.UseShellExecute = false;
// You can start any process, HelloWorld is a do-nothing example.
myProcess.StartInfo.FileName = "C:\\HelloWorld.exe";
myProcess.StartInfo.CreateNoWindow = true;
myProcess.Start();
One more example closer to asp.net, that I wait to end, and read the output.
Process compiler = new Process();
compiler.StartInfo.FileName = "c:\\hello.exe";
compiler.StartInfo.StandardOutputEncoding = System.Text.Encoding.UTF8;
compiler.StartInfo.UseShellExecute = false;
compiler.StartInfo.CreateNoWindow = false;
compiler.StartInfo.RedirectStandardError = true;
compiler.StartInfo.RedirectStandardOutput = true;
compiler.StartInfo.RedirectStandardInput = true;
// here I run it
compiler.Start();
compiler.StandardInput.Flush();
compiler.StandardInput.Close();
// here I get the output
string cReadOutput = compiler.StandardOutput.ReadToEnd();
compiler.WaitForExit();
compiler.Close();
Aristos' answer will work in cases where user privs are in order and the SysInternals EULA is acknowledged. By that, I mean the sdelete.exe utility from SysInternals will be run under the Asp.Net account assigned in IIS. If that account doesn't have the proper permissions and hasn't accepted the popup EULA, the file isn't deleted. I'm facing that very issue right now.
You can specify the domain/user/password used to run the process. That is outlined here:
http://social.msdn.microsoft.com/Forums/hu-HU/netfxbcl/thread/70b2419e-cb1a-4678-b2ae-cedcfe08d06f
The author of that thread had similar problems, which he cleared up by changing the ownership of the sdelete.exe file.
This thread also has some information about logging in as the user used to execute the process and accepting the SysInternals EULA:
sdelete.exe is not working with cfexecute
However that isn't feasible if you plan on using the built-in Asp.Net system accounts since those user accounts don't allow typ login. I may be forced to create a separate user that I can login with and accept the EULA, then specify those credentials to run the process. Unfort in my case, though, I may not have the option of creating users on my production server.
There are ways to force the EULA accept with a command line param, or a simple registry entry. But I think that only works for "regular" users--not the built in system users.

asp.net run program with Administrator account

I need to run one console application from ASP.NET application using Administrator account and with Desktop interaction enabled. I have tried code below, console app runs ok but within NETWORK SERVICE account. Any ideas how to run console under Administrator account?
string enginePath = Server.MapPath(#"~/engine/MyConsole.exe");
System.Diagnostics.ProcessStartInfo info = new System.Diagnostics.ProcessStartInfo(enginePath, "");
System.Diagnostics.Process p = System.Diagnostics.Process.Start(info);
p.WaitForExit();
Regards,
Tomas
you could use impersonation, there is an example here
personally i dont like impersonation in asp.net, you need to deal with passwords either not being changed or changing them in code. Is there no way to run what you want as the asp.net user?
edit:
You could acyually impersonate the network service by using "NETWORK SERVICE" as the user name, that would at least allieviate the password issues a little,
Another user already suggested impersonation. If that's good enough, there you go. Like he said, though, there are some maintenance headaches to deal with and some security implications.
Some options that I've used in the past which may or may not be applicable in your situation are:
If the task is on a predictable schedule, just add it to the Scheduled Tasks in Windows, set the appropriate worker account (Administrator, or whatever), and let 'er go. I believe there are also ways to programmatically trigger a scheduled task, but I've never had to do that. A Google search should get you going.
Implement the console app logic as a service running under the appropriate account. Then have the service listen for a "trigger" from your web app--a file drop or something simpler.
Either way the idea is to avoid storing any credientials in your ASP page, and to not have to grant that process rights it doesn't need.
You can use a manifest file and built it into your console application that will instruct it to always run under an admin account. See this example.
If this doesn't work for you then you could try passing in Admin account credentials in the ProcessStartInfo property e.g.
string enginePath = Server.MapPath(#"~/engine/MyConsole.exe");
System.Diagnostics.ProcessStartInfo info = new System.Diagnostics.ProcessStartInfo(enginePath, "");
info.UserName = "Administrator";
info.Password = "Password";
System.Diagnostics.Process p = System.Diagnostics.Process.Start(info); p.WaitForExit();

Resources