mstsc Remote Desktop questions - vbscript

currently, to improve some inefficiencies on a daily process, I am trying to write a c# Winform app that will combine a mix of user-input with VBscripts that will expedite a previously all user-input process of looking at an excel file and moving files from VSS to certain folders of certain servers.
I was hoping to get some questions answered, pointed in the right way:
Using command line or other workaround instead of manually,
1) Is it possible to log into a 2003 remote desktop with a Smartcard/pin?
2) Is it possible to run a file/start a process on the remote desktop from a command on your machine?
Thanks for the help and time

I have only experience with the second question.
You can do this with remote scripting or with utilities like SysInternals PsExec http://technet.microsoft.com/en-us/sysinternals/bb897553.aspx
here a vbscript that remotely starts a ipconfig command and redirects it to a textfile
Note that you can't start interactive processes like this, they would start but not show up
Dim sComputer 'computer name
Dim sCmdLine 'command line of the process
Dim sCurDir 'working directory of the process
Dim oProcess 'object representing the Win32_Process class
Dim oMethod 'object representing the Create method
sComputer = "." 'this is the local computer, use a pcname or ip-adress to do it remote
sCmdLine = "cmd /c ipconfig.exe > c:\ipconfig.txt"
Set oProcess = GetObject("winmgmts://" & sComputer & "/root/cimv2:Win32_Process")
Set oMethod = oProcess.Methods_("Create")
Set oInPar = oMethod.inParameters.SpawnInstance_()
oInPar.CommandLine = sCmdLine
oInPar.CurrentDirectory = sCurDir
Set oOutPar = oProcess.ExecMethod_("Create", oInPar)
If oOutPar.ReturnValue = 0 Then
WScript.Echo "Create process method completed successfully"
WScript.Echo "New Process ID is " & oOutPar.ProcessId
Else
WScript.Echo "Create process method failed"
End If

Related

Force a vbscript to open command prompt in 64bit instead of 32bit

I have been trying to get this script to work all day!
Here are some facts about my situation...
I have a program named "ffmpeg.exe" in my "C:\Windows\System32\" folder.
I DO NOT have that program in my "C:\Windows\SysWOW64\" folder.
Currently this is the script I have...
Option Explicit
Dim oFSO, oShell, sCommand
Dim sFilePath, sTempFilePath
Set oFSO = CreateObject("Scripting.FileSystemObject")
sFilePath = "C:\test\in_video.mkv"
sTempFilePath = "C:\test\out_video.mp4"
sCommand = "%comspec% /k ffmpeg -n -i """ + sFilePath + """ -c:v copy -c:a copy """ + sTempFilePath + """"
WScript.Echo sCommand
Set oShell = WScript.CreateObject("WScript.Shell")
oShell.Run sCommand, 1, True
Set oShell = Nothing
Set oFSO = Nothing
If I run this script manually at a command prompt then it seems to work just fine. But if I let another app run it (for example in this case uTorrent), it runs the script as expected but when it tries to process the oShell.Run command it runs that in a 32bit environment! Then I get this...
If I try to open up a new command prompt (nothing special) i seems to default to a 64bit environment and then I can type "ffmpeg" and it shows me the help content as expected.
So for some reason I can't get the script to run applications (specifically CMD) in the 64bit environment. Anyone know how I can achieve this?
Update
Seems that my script is in fact being ran in 32bit mode! Even though the script title bar says "C:\Windows\System32\cscript.exe", which is a 64bit environment!!
I used the following script to determine that it was running in a 32bit environment...
Dim WshShell
Dim WshProcEnv
Dim system_architecture
Dim process_architecture
Set WshShell = CreateObject("WScript.Shell")
Set WshProcEnv = WshShell.Environment("Process")
process_architecture= WshProcEnv("PROCESSOR_ARCHITECTURE")
If process_architecture = "x86" Then
system_architecture= WshProcEnv("PROCESSOR_ARCHITEW6432")
If system_architecture = "" Then
system_architecture = "x86"
End if
Else
system_architecture = process_architecture
End If
WScript.Echo "Running as a " & process_architecture & " process on a " _
& system_architecture & " system."
If it is only for cmd or some file in System32 you can use sysnative as suggested by the comment. It will lead to the 64Bit System32 even from 32Bit executables. Just replace "system32" with "sysnative" for every use. (unfortunately this is not present on 32bit windows so you need to check if you use a script on systems with both architectures... )
If you have a lot of accesses or use com objects I found it easier however to just use the same method to restart your script. The following code:
If fso.FileExists("C:\Windows\SysWOW64\wscript.exe") Then ' very basic check for 64bit Windows, you can replace it with a more complicated wmi check if you find it not reliable enough
If InStr(1, WScript.FullName, "SysWOW64", vbTextCompare) <> 0 Then ' = case insensitive check
newFullName = Replace(WScript.FullName, "SysWOW64", "Sysnative", 1, -1, vbTextCompare) ' System32 is replaced by Sysnative to deactivate WoW64, cscript or wscript stay the same
newArguments = "" ' in case of command line arguments they are passed on
For Each arg In WScript.Arguments
newArguments = newArguments & arg & " "
Next
wso.Run newFullName & " """ & WScript.ScriptFullName & """ " & newArguments, , False
WScript.Quit '32 Bit Scripting Host is closed
End If
End If
Basically closes the script whenever it was called with 32Bit Scripting host and restarts it with the 64Bit one so everything is found where it is expected to be.

Log on as local administrator in VBS

I have what should be a very simple script. I have a series of 6 PCs that I need to check the existence of a file and report back. Where the difficulty lies is that these devices are not part of AD and are part of a work group. From windows explorer using C$ I'm prompted to log on as a local administrator on the remote PC. How can I perform the same logon and automate the process using the script below?
Set objFSO = CreateObject("Scripting.FileSystemObject")
For i = 1 To 6
If objFSO.FileExists("\\10.4.55." & i & "\c$\Program Files\X-1 Technologies\offline.fla") Then
Wscript.Echo "Reg:" & i & " Off-Line."
Else
Wscript.Echo "Reg:" & i & " On-Line."
End If
Next
Thanks, Lloyd

SELECT ProcessId unexpected behaviour inside HTA

First of all, thanks for reading.
I have a HTA to centralize some repetitive task.
Login into several servers via ssh and send multiple commands is one of them.
This code is working like a charm inside a vbs file
Option Explicit
Dim Shell, WMI, wql, process
Set Shell = CreateObject("WScript.Shell")
Set WMI = GetObject("winmgmts:{impersonationLevel=impersonate}!\\.\root\cimv2")
wql = "SELECT ProcessId FROM Win32_Process WHERE Name = 'putty.exe'"
dim cmd : cmd=InputBox("Enter command")
For Each process In WMI.ExecQuery(wql)
Shell.AppActivate process.ProcessId
Shell.SendKeys cmd & " {ENTER}"
Next
But this equivalent, inside a HTA only sends the command to one or two windows.
sub sendToPuttyWindow(cmd)
Dim Shell, WMI, wql, process
Set Shell = CreateObject("WScript.Shell")
Set WMI = GetObject("winmgmts:{impersonationLevel=impersonate}!\\.\root\cimv2")
wql = "SELECT ProcessId FROM Win32_Process WHERE Name = 'putty.exe'"
For Each process In WMI.ExecQuery(wql)
Shell.AppActivate process.ProcessId
Shell.SendKeys cmd & " {ENTER}"
Next
end sub
Currently I'm calling the vbs file from the hta, but I would like to maintain the HTA file as independent as possible.
Could you please help me?
Do not use SendKeys for automating PuTTY. It sends all emulated keystrokes to the current foreground window, whatever that may be. If you need to run several commands in a row: use plink from the PuTTY suite. It was built for this exact purpose.
plink -ssh -batch -m file user#host

What is the equivalent of a Batch ECHO Command using VBScript?

We currently use Windows Batch (DOS) command files to control our process flow. To display messages to the Console, we would use the ECHO command. These messages would show up in our Scheduler software, which used to be Tivoli and now is CA WA Workstation\ ESP.
I would like to start using VBS files instead of CMD\BAT files and am trying to figure out how to do the equivalent of an ECHO to the console.
When I try to use either the WScript.Echo command or write to Standard Out, the messages are displayed in dialog boxes for both and they require the OK button to be pushed to continue. Not surprisingly, when I run unattended though a scheduler, the job hits one of these commands and just hangs since there is no one to OK the messagebox.
SET FS = CreateObject("Scripting.FileSystemObject")
SET StdOut = FS.GetStandardStream(1)
StdOut.Write("Test 1")
WScript.echo("Test 2")
I realize I could write the messages to a Log file using the Scripting object, but this could fail if an invalid path is provided or because of insufficient permissions. Besides, being able to see feedback write within the Scheduler is awfully convenient.
How do I write to the Console using VBScript? I’ve seen other posts here that suggest that the above methods which didn't work for the reason describe above were the way to do it.
wscript.echo is the correct command - but to output to console rather than dialogue you need to run the script with cscript instead of wscript.
You can resolve this by
running your script from command line like so:
cscript myscript.vbs
changing the default file association (or creating a new file extension and association for those scripts you want to run with cscript).
change the engine via the script host option (i.e. as per http://support.microsoft.com/kb/245254)
cscript //h:cscript //s
Or you can add a few lines to the start of your script to force it to switch "engine" from wscript to cscript - see http://www.robvanderwoude.com/vbstech_engine_force.php (copied below):
RunMeAsCScript
'do whatever you want; anything after the above line you can gaurentee you'll be in cscript
Sub RunMeAsCScript()
Dim strArgs, strCmd, strEngine, i, objDebug, wshShell
Set wshShell = CreateObject( "WScript.Shell" )
strEngine = UCase( Right( WScript.FullName, 12 ) )
If strEngine <> "\CSCRIPT.EXE" Then
' Recreate the list of command line arguments
strArgs = ""
If WScript.Arguments.Count > 0 Then
For i = 0 To WScript.Arguments.Count
strArgs = strArgs & " " & QuoteIt(WScript.Arguments(i))
Next
End If
' Create the complete command line to rerun this script in CSCRIPT
strCmd = "CSCRIPT.EXE //NoLogo """ & WScript.ScriptFullName & """" & strArgs
' Rerun the script in CSCRIPT
Set objDebug = wshShell.Exec( strCmd )
' Wait until the script exits
Do While objDebug.Status = 0
WScript.Sleep 100
Loop
' Exit with CSCRIPT's return code
WScript.Quit objDebug.ExitCode
End If
End Sub
'per Tomasz Gandor's comment, this will ensure parameters in quotes are covered:
function QuoteIt(strTemp)
if instr(strTemp," ") then
strTemp = """" & replace(strTemp,"""","""""") & """"
end if
QuoteIt = strTemp
end function

Script to remote lock a screen under Windows 7

I was pointed in this direction by the author of a script I've been using for a couple of years now.
It allows the remote locking of a desktop, and works fine locally and remotely under Windows XP, and works fine locally under Windows 7, but when trying to use it remotely against a Windows 7 machine it fails to work.
It's been great for a few years now and has been very useful, but we've recently started to deploy Windows 7 machines on site and once the upgrade is fully completed I won't be able to use this anymore.
The same question that I have was posed a couple of years back, but went unanswered.
Here is the VBS code:
' StartProcess.vbs
' Sample VBScript to start a process. Inputbox for name
' Author Guy Thomas http://computerperformance.co.uk/
' Version 2.2 - December 2005
' -------------------------------------------------------'
Option Explicit
Dim objWMIService, objProcess
Dim strShell, objProgram, strComputer, strExe, strInput
strExe = "rundll32.exe user32.dll,LockWorkStation"
' Input Box to get name of machine to run the process
Do
strComputer = (InputBox(" ComputerName to Run Script",_
"Computer Name"))
If strComputer <> "" Then
strInput = True
End if
Loop until strInput = True
' Connect to WMI
set objWMIService = getobject("winmgmts://"_
& strComputer & "/root/cimv2")
' Obtain the Win32_Process class of object.
Set objProcess = objWMIService.Get("Win32_Process")
Set objProgram = objProcess.Methods_( _
"Create").InParameters.SpawnInstance_
objProgram.CommandLine = strExe
'Execute the program now at the command line.
Set strShell = objWMIService.ExecMethod( _
"Win32_Process", "Create", objProgram)
'WScript.echo "Created: " & strExe & " on " & strComputer
WSCript.Quit
' End of Example of a Process VBScript
Running rundll32.exe user32.dll,LockWorkStation on my Win7 64 bit locks the screen, so this seems quite OK. But when looking at http://msdn.microsoft.com/en-us/library/windows/desktop/aa376875(v=vs.85).aspx I read
The LockWorkStation function is callable only by processes running on
the interactive desktop. In addition, the user must be logged on, and
the workstation cannot already be locked.
I have no experience with WMI but I assume that WMI does not run rundll32.exe on the interactive desktop!?
This is working for me with remote Windows 7 x64 systems :
psexec.exe -accepteula \\REMOTECOMPUTERNAME -i -s %windir%\system32\rundll32.exe user32.dll,LockWorkStation
Regards

Resources