I've been trying to call cmd in order to run a command and get the output from it - specifically the "query user /server:servername" command, and have found lots of posts discussing how to run it. When I run it though, it seems to work for most commands (ipconfig, ping, tracert) but not my query user command. Interestingly, the code below seems to be ok for most commands but not this one.
Process.Start("cmd", "/c query user /server:PCNAME")
I also tried creating a batch file and running that.
Dim currentdir As String = Directory.GetCurrentDirectory
Dim server As String = txt_target_server.Text
Dim cmdline As String = "query user /server:" & server & " > tmpidlvw.txt"
IO.File.WriteAllText("tempbat.bat", "#echo off" & vbNewLine & cmdline)
Process.Start("tempbat.bat")
Dim currentreader As StreamReader
Dim currentfile As String = currentdir & "\tmpidlvw.txt"
If System.IO.File.Exists(currentfile) Then
currentreader = New StreamReader(currentfile)
Dim usercount As Integer = 0
Dim userarray(100) As String
Do While Not currentreader.EndOfStream
Dim tempstring As String = currentreader.ReadLine
MsgBox(tempstring)
userarray(usercount) = tempstring
usercount += 1
Loop
currentreader.Close()
For count As Integer = 1 To usercount
MsgBox(userarray(count))
Next
Else
MsgBox(currentfile)
End If
This also fails. I found that the batch file it creates works fine if I run it normally (the code generates it ok). I've isolated it to that the process.start(cmd.exe) doesn't seem to run the same as normal cmd.
for Example, if i run process.start(cmd.exe) and then do the following
cd c:\windows\system32
dir | findstr query
I get the following
14/07/09 02:14 AM 66,048 driverquery.exe
14/07/09 02:15 AM 395,776 dsquery.dll
08/07/15 10:48 PM 1,549,312 tquery.dll
If I run the exact same command from a normal command prompt, the output is below.
14/07/09 02:39 AM 96,256 driverquery.exe
14/07/09 02:40 AM 429,056 dsquery.dll
21/11/10 04:24 AM 16,384 query.exe
08/07/15 10:48 PM 2,315,776 tquery.dll
I believe this is why it fails - the cmd called does not "see" the same directory as a normal command prompt and cannot see the query.exe file.
Does anyone know what I can do to get this to work? I've verified this happens if I run my code on another machine, and have turned off vmware debugging, antivirus, autosandbox etc.
Related
I've written a pair of apps; one that issues powershell scripts to clients (the server) and one that executes powershell scripts passed to it (the client).
I've added functions to detect if a particular script requires elevation.
In the event that a script requires elevation, the server app prompts the user for their credentials. The password is converted to a secure string and saved in a SQL database, as is the username along with the script.
The client app grabs the script and, if elevation is required, grabs the username and secure string then tries to build a credential object from it.
The functionality is working fine for non-elevated scripts, but elevated scripts are not working. Its not erroring or throwing an exception (finally) but the scripts are not executed.
The first part of this process reads the data from SQL into a datatable and then i loop through the rows of that datatable.
Once I've got a row that contains a script that needs running, I build the script.
Here's how I'm building and executing the powershell in VB...
If this_routine_elevation_required = 1 Then
Dim scriptbody As String = row("scriptbody").ToString
Dim elevated_user_un As String = row("elevated_user").ToString
Dim elevated_user_ss As String = row("securestring").ToString
credential_script = "$securepassword = '" & elevated_user_ss & "' | ConvertTo-SecureString; $username='" & elevated_user_un & "';$credential = New-Object System.Management.Automation.PsCredential($username, $securepassword)"
action_response = RunPowershellScript(credential_script & "; " & scriptbody)
End If
and here is the function that executes the powershell (using 'Imports System.Management.Automation)...
Private Function RunPowershellScript(ByVal scriptText As String) As String
' create Powershell runspace
Dim MyRunSpace As Runspace = RunspaceFactory.CreateRunspace()
MyRunSpace.Open()
Dim MyPipeline As Pipeline = MyRunSpace.CreatePipeline()
MyPipeline.Commands.AddScript(scriptText)
Dim results As Collection(Of PSObject) = MyPipeline.Invoke()
MyRunSpace.Close()
Dim MyStringBuilder As New StringBuilder()
For Each obj As PSObject In results
MyStringBuilder.AppendLine(obj.ToString())
Next
Return MyStringBuilder.ToString()
End Function
I've thrown up a messagebox of the script before its passed to the RunPowershellScript function so i could make sure nothing was malformed or to ensure i wasnt doing anything stupid (i've manipulated the secure string for the purposes of this image)...
The example here is just a test to see if the executor could stop the W32Time service, something that would normally require elevation. It does not work.
I get an empty response back from the RunPowershellScript function and the service continues to run.
It occured to me that I'm getting a securestring from the database and then converting that securestring to a securestring, so perhaps its not ending up with the correct valid password in $credential, but from what i understand I have to provide a securestring for the password parameter of PsCredential, and without -ConvertTo-SecureString it would consider the password to just be a string. I tried this and it threw an exception about the password being null.
Can anyone help point me in the right direction?
Many thanks in advance.
Is the script running locally on the target or from the server?
Credential objects are specific to the computer AND user account which creates them, so they are not transferable and can only be used on the computer which creates them.
I'm writing a program to interface with an inspection machine. The machine has the ability to output command lines during its program run.
The machine has an interface application which allows the passing and automatic start of programs into the machine. I can get this to work with a single instance, however I would like to be able to select several programs for it to run back to back.
Below is the code to pass a single program to the machine:
im ProgramName As String = cbProgram.Text
Dim ProgURL = GetXMLNode(1, ProgramName)
Dim exeDir As New IO.FileInfo(Reflection.Assembly.GetExecutingAssembly.FullName)
Dim EXEPath = IO.Path.Combine(exeDir.DirectoryName, "iscmd.exe")
' New ProcessStartInfo created
Dim p As New ProcessStartInfo
' Specify the location of the binary
p.FileName = EXEPath
' Use these arguments for the process
p.Arguments = " /run""" & ProgURL & """ /nowait"
' Use a hidden window
p.WindowStyle = ProcessWindowStyle.Hidden
' Start the process
Dim ISCMD As Process = Process.Start(p)
ISCMD.WaitForExit()
MsgBox("PING!")
The PING will show immediately after the program has been passed to the machine (but not completed). What I want to be able to do is build an array of programs and launch this process once each time a program has completed. Is it possible to use a command line from the machine to signal to my software that the next program can be started? Below is a screenshot the machines command line.
I am trying to get the logged in username of the user by using VBS.
I tried some codes which works when I run the script directly (Double Clicking it)
Set wshNetwork = CreateObject("WScript.Network")
strUser = wshNetwork.Username
WScript.Echo "Current User: " & strUser
However, what I need to do is to use CMD to run a scheduled task using the AT command.
When it ran, the username would be the computer's name instead of the logged in user.
This problem also occurs when I run CMD as administrator and use wscript to run the script.
Is there any way to bypass this context and get the logged in user instead of the one that runs the script?
The command
query session console
should provide what you need
For an easier to parse
quser console
EDITED - Included sample vbs code
Dim strCmd
strCmd = "cmd /q /c ""quser console | find /i ""console"" "" "
Dim buffer
buffer = WScript.CreateObject("WScript.Shell").Exec(strCmd).StdOut.ReadAll()
Dim c, consoleUserName
c = InStr(buffer,"console")
If c > 2 Then
consoleUserName = Trim(Mid(buffer,2,c-2))
Else
consoleUserName = ""
End If
WScript.Echo consoleUserName
I suggest you execute the command
set
from the prompt. It may reveal a few items that are set in the environment that may be of interest.
set user
will censor the list so that only variables that start user will be displayed.
i used this example to open a command prompt from within vb.net 2010
lnk to stackoverflow document
the command prompt opens as expected and i can do directories open commands like regedit etc. without an issue
but what i really want is tftp.exe when i look for it it does not show up, when doing a dir it is not listed when type tftp at command prompt i get the to recognzed command
when comparing to a normal command prompt by type cmd at the run line i can see it in the windows\system32 folder
also when i do a dir from normal command prompt and compare to dir from the cmd prompt opened by vb.net there is a 400+ number of files difference out of close to 3000 files
trying to find out why i cant see all the files here is the actul code i used
Private Sub Button30_Click(sender As System.Object, e As System.EventArgs) Handles Button30.Click
Dim command As String = "tftp -i 192.168.10.177 put test1.bin"
Dim arguments As String = ""
Dim permanent As Boolean = True
Dim p As Process = New Process()
Dim pi As ProcessStartInfo = New ProcessStartInfo()
pi.Arguments = " " + If(permanent = True, "/K", "/C") + " " + command + " " + arguments
pi.FileName = "cmd.exe"
p.StartInfo = pi
p.Start()
End Sub
This seems like a very convuluted approch you are taking, but to answer your question directly, you probably need to set the working directory like so:
pi.WorkingDirectory = "c:\windows\system32"
I have to say though, you might want to reconsider the whole approach of opening a DOS window for the user to type commands. Doesn't see very user friendly.
ok found the answer, it is becuase i am running 64bit windows and when its looking for the tftp.exe it is actually looking in the syswow64 directory and tftp.exe is not in that directory.
since i have this running and compiled for x86 and not 64bit here is the work around
Public Declare Function Wow64DisableWow64FsRedirection Lib "kernel32" (ByRef oldvalue As Long) As Boolean
then
Wow64DisableWow64FsRedirection(0)
after adding tthis to my code the tftp upload works flawlessly
I'm working on a script that will run as a scheduled task under a local admin account. The heart of the script is as follows:
'Calculate date time
dtm = Now
ymd = (Year(dtm)*10000) + (Month(dtm)*100) + Day(dtm)
hms = (Hour(dtm)*10000) + (Minute(dtm)*100) + Second(dtm)
dString = ymd & "_" & hms
Set Wso = CreateObject("WScript.Shell")
'Write random string to text file for reference by incremental script
Const ForWriting = 2
Set objFile = Fso.OpenTextFile("e:\backups\dString.txt", ForWriting, True)
objFile.WriteLine(dString)
objFile.Close
'Append random string to make full backup name unique'
'Execute full backup creation'
'PROBLEM: Below line will only execute under my domain account
Wso.Run("trueimagecmd /create /filename:""e:\backups\autoBackup_" & dString &"_.tib"" /compression:5 /incremental /partition:""C""")
The above snippet will run fine under my domain account, but will error on the line indicated above with the following:
The system cannot find the file specified
Code: 80070002
Source (null)
This error will not occur when I run it under my account. I'm not familiar enough with the permissions required to run an instance of "Wscript.Shell". Any insight is appreciated.
UPDATE:
trueImagecmd is a command line version of Acronis recovery software. I'm using this script as a way of automating the process for deployment. The command is fine and I can run this script as myself, when running under the local admin account, however, the script executes up to the point indicated, the run command is throwing the error.
UPDATE 2:
Looks like including the full path fixed the problem. Thanks all for your suggestions.
Have you tried calling trueimagecmd with the full path to the executable?
For instance C:\progra~1\trueimage\trueimagecmd.exe
Make sure you have drive E in the other machine from where it generates error. Try using c:\backups\autoBackup_" & dString &".tib" instead of e:\backups\autoBackup" & dString &"_.tib"