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.
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've got a tricky thing to do here.
I'm using task scheduler to auto-reboot all the computer during the weekend by calling a simple .bat file containing a shutdown command.
I wanted to give the user the possiblilty to cancel that reboot by displaying them a popup saying "Computer is about to restart, do you wish to continue ? Ok or Cancel". I have done that with VB using the popupbox method, it works perfectly.
Here is the problem i'm facing: The task is running under the System account and unless the task is set to run with the current logged on user, the popup box won't appear. I could change the account set in the task but I've got hundreds of users so impossible.
I've done some kind of a workaround, calling the VBS from Psexec... Works, but it's not perfect.
Here is my Psexec command that calls the VB:
Psexec -accepteula -s -i cmd /c C:\Windows\System32\Weekly_Reboot.vbs
Here is my VB:
Dim WshShell, BtnCode
Set WshShell = WScript.CreateObject("WScript.Shell")
BtnCode = WshShell.Popup("Computer is about to restart, do you wish to continue?", 30, "/!\ Weekly Restart /!\", 4 + 32)
Select Case BtnCode
case 6
Dim objShell
Set objShell = WScript.CreateObject("WScript.Shell")
objShell.Run "c:\Windows\System32\Weekly_Reboot.bat"
case 7
WScript.Echo "No prob - the computer won't restart"
case -1
Set objShell = WScript.CreateObject("WScript.Shell")
objShell.Run "c:\Windows\System32\Weekly_Reboot.bat"
End Select
And here is the actual reboot command:
Shutdown /f /r /c "This is the weekly reboot"
Any idea would be really awesome ! I really tried googling it, but no luck.
Here is the problem i'm facing: The task is running under the System account and unless the task is set to run with the current logged on user, the popup box won't appear. I could change the account set in the task but I've got hundreds of users so impossible.
Change the task to run under the group called Users. It will make the task run for any logged in user.
I'm not certain if this is needed: but you might want to run it using the highest privileges.
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.
Is it possible to include in a VB.net 2008 Project a VBScript (test.vbs) and run it if its while the processing necessary? But the main thing is it should be possible to BUILD just one .exe.
If so, can you also receive values / arguments from the VBS file?
Here is an example, although it's pointless, but it is used for unterstanding:
VB.net -> exe is running
the exe runs please_find_the_coputername.vbs
The script please_find_the_coputername.vbs -> obtained the computer name and sends this variable to VB.net
VB.Net displays the computer name via Msgbox().
Note: I know that I can read out the computer name with VB.net but this example is only for understanding my questions.
Edit:
HI #maxedev thank you for your answer.
Wow.. its nice trick.
But I want only to do this VBScript code in VB.net:
Dim strComputer
strComputer = "LP-BKR"
Set objWMIService = GetObject("winmgmts:{impersonationLevel=impersonate}!\\" _
& strComputer & "\root\cimv2")
Set colComputer = objWMIService.ExecQuery ("Select * from Win32_ComputerSystem")
For Each objComputer in colComputer
Wscript.Echo "Logged-on Domain: " & objComputer.Domain
Wscript.Echo "Logged-on UserName: " & objComputer.UserName
Wscript.Echo "Logged-on ComputerName: " & objComputer.Name
Next
set objWMIService = Nothing
set colComputer = Nothing
I searched the whole day to get the same Value... but didn't find anything. That's why I decide to do that in this way. But if I think, the trick with clipboard is risky. It pushes the still clipboard text away. How can I realize it?
I'm not sure exactly what you're trying to accomplish, but you could write to a text file and then read it through vb.net - or you could do something like this post to use the clipboard to pass info ie :
VBS:
Set WshShell = WScript.CreateObject("WScript.Shell")
WshShell.Run "cmd.exe /c echo hello world | clip", 0, TRUE
VB.NET:
MessageBox.Show(Clipboard.GetText)
--shows "hello world"
One solution would be to add a reference to the MS Script Control:
http://msdn.microsoft.com/en-us/library/aa227400(v=vs.60).aspx
Using that, you can add literally add code (VBScript) with the AddCode() method then run it and get the output back. I have a tiny example here.
Windows automatically provides the information you're looking for in environment variables:
%USERNAME% -> username of the logged in user
%USERDOMAIN% -> WINS name of the domain the user is logged into
%USERDNSDOMAIN% -> FQDN of the domain the user is logged into
%COMPUTERNAME% -> hostname of the computer
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"