I'm new to PowerShell. Now the task is to pin some programs to the Taskbar. This Tutorial is great and runs well in one of my Win7 32bit in Vmware. But same script cannot run in Win10 32bit in Vmware. So I modified the code and finally found it was because some Verbs are not found. My test code is as following:
CLS
$cmd = 'C:\Windows\System32\cmd.exe'
Test-Path $cmd
$Shell = New-Object -ComObject Shell.Application
$Desktop = $Shell.NameSpace(0X0)
$itemLnk = $Desktop.ParseName($cmd)
$itemVerbs = $itemLnk.Verbs()
Foreach($v in $itemVerbs)
{
write-host $v.Name
}
The ISE is run as admin and the result, as well as 'Verbs' found by mannually right clicking the cmd.exe, are shown as below:
So please tell me why and how to fix this, thank you!
Its probably because there is no cmd.exe located in C:\Windows\, use this instead:
$cmd = Join-Path $env:SystemRoot 'System32\cmd.exe'
Note: Im using the Join-Path cmdlet to combine the path and $env:SystemRoot to retrieve the system root (e. g. C:\Windows)
You can only use verbs above the first separator and Properties. Your program must keep running to display properties.
Here's a VBScript that list and performs the verb. ShVerb.vbs /? to read the above.
HelpMsg = vbcrlf & " ShVerb" & vbcrlf & vbcrlf & " 2014" & vbcrlf & vbcrlf & " Lists or runs an explorer verb (right click menu) on a file or folder" & vbcrlf & vbcrlf & " ShVerb <filename> [verb]" & vbcrlf & vbcrlf & " Used without a verb it lists the verbs available for the file or folder" & vbcrlf & vbcrlf
HelpMsg = HelpMsg & " The program lists most verbs but only ones above the first separator" & vbcrlf & " of the menu work when used this way" & vbcrlf & vbcrlf
HelpMsg = HelpMsg & " The Properties verb can be used. However the program has to keep running" & vbcrlf & " to hold the properties dialog open. It keeps running by displaying" & vbcrlf & " a message box."
Set objShell = CreateObject("Shell.Application")
Set Ag = WScript.Arguments
set WshShell = WScript.CreateObject("WScript.Shell")
Set fso = CreateObject("Scripting.FileSystemObject")
If Ag.count = 0 then
wscript.echo " ShVerb - No file specified"
wscript.echo HelpMsg
wscript.quit
Else If Ag.count = 1 then
If LCase(Replace(Ag(0),"-", "/")) = "/h" or Replace(Ag(0),"-", "/") = "/?" then
wscript.echo HelpMsg
wscript.quit
End If
ElseIf Ag.count > 2 then
wscript.echo vbcrlf & " ShVerb - To many parameters" & vbcrlf & " Use quotes around filenames and verbs containing spaces" & vbcrlf
wscript.echo HelpMsg
wscript.quit
End If
If fso.DriveExists(Ag(0)) = True then
Set objFolder = objShell.Namespace(fso.GetFileName(Ag(0)))
' Set objFolderItem = objFolder.ParseName(fso.GetFileName(Ag(0)))
Set objFolderItem = objFolder.self
msgbox ag(0)
ElseIf fso.FolderExists(Ag(0)) = True then
Set objFolder = objShell.Namespace(fso.GetParentFolderName(Ag(0)))
Set objFolderItem = objFolder.ParseName(fso.GetFileName(Ag(0)))
ElseIf fso.fileExists(Ag(0)) = True then
Set objFolder = objShell.Namespace(fso.GetParentFolderName(Ag(0)))
Set objFolderItem = objFolder.ParseName(fso.GetFileName(Ag(0)))
Else
wscript.echo " ShVerb - " & Ag(0) & " not found"
wscript.echo HelpMsg
wscript.quit
End If
Set objVerbs = objFolderItem.Verbs
'If only one argument list verbs for that item
If Ag.count = 1 then
For Each cmd in objFolderItem.Verbs
If len(cmd) <> 0 then CmdList = CmdList & vbcrlf & replace(cmd.name, "&", "")
Next
wscript.echo mid(CmdList, 2)
'If two arguments do verbs for that item
ElseIf Ag.count = 2 then
For Each cmd in objFolderItem.Verbs
If lcase(replace(cmd, "&", "")) = LCase(Ag(1)) then
wscript.echo(Cmd.doit)
Exit For
End If
Next
'Properties is special cased. Script has to stay running for Properties dialog to show.
If Lcase(Ag(1)) = "properties" then
WSHShell.AppActivate(ObjFolderItem.Name & " Properties")
msgbox "This message box has to stay open to keep the " & ObjFolderItem.Name & " Properties dialog open."
End If
End If
End If
Related
Currently i am doing this.But this is not working,just creating a shortcut of the vb script.
Dim objShell
Set objShell = WScript.CreateObject ("WScript.shell")
objShell.Run "E:\folder\xyz.cmd"
objShell.Sendkeys ("+{F10}")
objShell.Sendkeys "s"
Set objShell = Nothing
Can some one please help me on this.Thanks
This uses the shell's COM objects. We choose the verb we want.
Run the script without arguments for help.
To list verbs
shverb.vbs "E:\folder\xyz.cmd"
To Open
shverb.vbs "E:\folder\xyz.cmd" edit
The documentation for the shell is here https://msdn.microsoft.com/en-us/library/windows/desktop/bb787868(v=vs.85).aspx
HelpMsg = vbcrlf & " ShVerb" & vbcrlf & vbcrlf & " David Candy 2014" & vbcrlf & vbcrlf & " Lists or runs an explorer verb (right click menu) on a file or folder" & vbcrlf & vbcrlf & " ShVerb <filename> [verb]" & vbcrlf & vbcrlf & " Used without a verb it lists the verbs available for the file or folder" & vbcrlf & vbcrlf
HelpMsg = HelpMsg & " The program lists most verbs but only ones above the first separator" & vbcrlf & " of the menu work when used this way" & vbcrlf & vbcrlf
HelpMsg = HelpMsg & " The Properties verb can be used. However the program has to keep running" & vbcrlf & " to hold the properties dialog open. It keeps running by displaying" & vbcrlf & " a message box."
Set objShell = CreateObject("Shell.Application")
Set Ag = WScript.Arguments
set WshShell = WScript.CreateObject("WScript.Shell")
Set fso = CreateObject("Scripting.FileSystemObject")
If Ag.count = 0 then
wscript.echo " ShVerb - No file specified"
wscript.echo HelpMsg
wscript.quit
Else If Ag.count = 1 then
If LCase(Replace(Ag(0),"-", "/")) = "/h" or Replace(Ag(0),"-", "/") = "/?" then
wscript.echo HelpMsg
wscript.quit
End If
ElseIf Ag.count > 2 then
wscript.echo vbcrlf & " ShVerb - To many parameters" & vbcrlf & " Use quotes around filenames and verbs containing spaces" & vbcrlf
wscript.echo HelpMsg
wscript.quit
End If
If fso.DriveExists(Ag(0)) = True then
Set objFolder = objShell.Namespace(fso.GetFileName(Ag(0)))
' Set objFolderItem = objFolder.ParseName(fso.GetFileName(Ag(0)))
Set objFolderItem = objFolder.self
msgbox ag(0)
ElseIf fso.FolderExists(Ag(0)) = True then
Set objFolder = objShell.Namespace(fso.GetParentFolderName(Ag(0)))
Set objFolderItem = objFolder.ParseName(fso.GetFileName(Ag(0)))
ElseIf fso.fileExists(Ag(0)) = True then
Set objFolder = objShell.Namespace(fso.GetParentFolderName(Ag(0)))
Set objFolderItem = objFolder.ParseName(fso.GetFileName(Ag(0)))
Else
wscript.echo " ShVerb - " & Ag(0) & " not found"
wscript.echo HelpMsg
wscript.quit
End If
Set objVerbs = objFolderItem.Verbs
'If only one argument list verbs for that item
If Ag.count = 1 then
For Each cmd in objFolderItem.Verbs
If len(cmd) <> 0 then CmdList = CmdList & vbcrlf & replace(cmd.name, "&", "")
Next
wscript.echo mid(CmdList, 2)
'If two arguments do verbs for that item
ElseIf Ag.count = 2 then
For Each cmd in objFolderItem.Verbs
If lcase(replace(cmd, "&", "")) = LCase(Ag(1)) then
wscript.echo(Cmd.doit)
Exit For
End If
Next
'Properties is special cased. Script has to stay running for Properties dialog to show.
If Lcase(Ag(1)) = "properties" then
WSHShell.AppActivate(ObjFolderItem.Name & " Properties")
msgbox "This message box has to stay open to keep the " & ObjFolderItem.Name & " Properties dialog open."
End If
End If
End If
In Windows 7, I cut the user library folders and then I paste them to another location (including the content of them). When I do it that way, Windows 7 makes the changes needed (registry, path ... etc.) in order to get those special folders working again.
Is there a way to script it (in VBS if possible)?
I've given a look at WshShell.SpecialFolders commands and the fso.MoveFolder but I don't find the way...
Does anyone have an idea or a link in order to help me? Thanks by advance.
You need to use shell objects from Shell32. This lists or executes a command on a file/folder object (eg Cut). You can use Shell.namespace to get a special folder, see https://msdn.microsoft.com/en-us/library/windows/desktop/bb774094(v=vs.85).aspx
HelpMsg = vbcrlf & " ShVerb" & vbcrlf & vbcrlf & " David Candy 2014" & vbcrlf & vbcrlf & " Lists or runs an explorer verb (right click menu) on a file or folder" & vbcrlf & vbcrlf & " ShVerb <filename> [verb]" & vbcrlf & vbcrlf & " Used without a verb it lists the verbs available for the file or folder" & vbcrlf & vbcrlf
HelpMsg = HelpMsg & " The program lists most verbs but only ones above the first separator" & vbcrlf & " of the menu work when used this way" & vbcrlf & vbcrlf
HelpMsg = HelpMsg & " The Properties verb can be used. However the program has to keep running" & vbcrlf & " to hold the properties dialog open. It keeps running by displaying" & vbcrlf & " a message box."
Set objShell = CreateObject("Shell.Application")
Set Ag = WScript.Arguments
set WshShell = WScript.CreateObject("WScript.Shell")
Set fso = CreateObject("Scripting.FileSystemObject")
If Ag.count = 0 then
wscript.echo " ShVerb - No file specified"
wscript.echo HelpMsg
wscript.quit
Else If Ag.count = 1 then
If LCase(Replace(Ag(0),"-", "/")) = "/h" or Replace(Ag(0),"-", "/") = "/?" then
wscript.echo HelpMsg
wscript.quit
End If
ElseIf Ag.count > 2 then
wscript.echo vbcrlf & " ShVerb - To many parameters" & vbcrlf & " Use quotes around filenames and verbs containing spaces" & vbcrlf
wscript.echo HelpMsg
wscript.quit
End If
If fso.DriveExists(Ag(0)) = True then
Set objFolder = objShell.Namespace(fso.GetFileName(Ag(0)))
' Set objFolderItem = objFolder.ParseName(fso.GetFileName(Ag(0)))
Set objFolderItem = objFolder.self
msgbox ag(0)
ElseIf fso.FolderExists(Ag(0)) = True then
Set objFolder = objShell.Namespace(fso.GetParentFolderName(Ag(0)))
Set objFolderItem = objFolder.ParseName(fso.GetFileName(Ag(0)))
ElseIf fso.fileExists(Ag(0)) = True then
Set objFolder = objShell.Namespace(fso.GetParentFolderName(Ag(0)))
Set objFolderItem = objFolder.ParseName(fso.GetFileName(Ag(0)))
Else
wscript.echo " ShVerb - " & Ag(0) & " not found"
wscript.echo HelpMsg
wscript.quit
End If
Set objVerbs = objFolderItem.Verbs
'If only one argument list verbs for that item
If Ag.count = 1 then
For Each cmd in objFolderItem.Verbs
If len(cmd) <> 0 then CmdList = CmdList & vbcrlf & replace(cmd.name, "&", "")
Next
wscript.echo mid(CmdList, 2)
'If two arguments do verbs for that item
ElseIf Ag.count = 2 then
For Each cmd in objFolderItem.Verbs
If lcase(replace(cmd, "&", "")) = LCase(Ag(1)) then
wscript.echo(Cmd.doit)
Exit For
End If
Next
'Properties is special cased. Script has to stay running for Properties dialog to show.
If Lcase(Ag(1)) = "properties" then
WSHShell.AppActivate(ObjFolderItem.Name & " Properties")
msgbox "This message box has to stay open to keep the " & ObjFolderItem.Name & " Properties dialog open."
End If
End If
End If
Copying files in a folder to a blank or existing zip file. Cause zip files are folders in the shell.
Set objShell = CreateObject("Shell.Application")
Set Ag=Wscript.Arguments
set WshShell = WScript.CreateObject("WScript.Shell")
Set SrcFldr=objShell.NameSpace(Ag(1))
Set DestFldr=objShell.NameSpace(Ag(0))
Set FldrItems=SrcFldr.Items
DestFldr.CopyHere FldrItems, &H214
Msgbox "Finished"
I've created MyApplication.msi package using WiX Installer, kept in D drive and running it via Administrator Command Prompt as follows:
Right click on cmd.exe - Run as administrator
C:\Windows\system32>"D:\MyApplication.msi"
The package gets started and runs as required.
Now, I need a batch file which will be able to do above steps automatically.
How can this be done?
You can use standard runas windows command like this
runas /user:administrator D:\MyApplication.msi
but it may ask for password.
Another option is to use sysinternals.com (now it is belongs to Microsoft) tools
psexec -u UserName -p password D:\MyApplication.msi
Or you can right click you program - Properties and tick Run As Administrator on the Compatability tab.
VBScript can automate Right Click - RunAs (in Vista and later RunAs elevates to Admin token - XP and before allows you to choose a different user). RunAs appears on the menu as Run As Administrator (Vista and later).
Here's a vbscript program that executes verbs on files.
HelpMsg = vbcrlf & " ShVerb" & vbcrlf & vbcrlf & " David Candy 2014" & vbcrlf & vbcrlf & " Lists or runs an explorer verb (right click menu) on a file or folder" & vbcrlf & vbcrlf & " ShVerb <filename> [verb]" & vbcrlf & vbcrlf & " Used without a verb it lists the verbs available for the file or folder" & vbcrlf & vbcrlf
HelpMsg = HelpMsg & " The program lists most verbs but only ones above the first separator" & vbcrlf & " of the menu work when used this way" & vbcrlf & vbcrlf
HelpMsg = HelpMsg & " The Properties verb can be used. However the program has to keep running" & vbcrlf & " to hold the properties dialog open. It keeps running by displaying" & vbcrlf & " a message box."
Set objShell = CreateObject("Shell.Application")
Set Ag = WScript.Arguments
set WshShell = WScript.CreateObject("WScript.Shell")
Set fso = CreateObject("Scripting.FileSystemObject")
If Ag.count = 0 then
wscript.echo " ShVerb - No file specified"
wscript.echo HelpMsg
wscript.quit
Else If Ag.count = 1 then
If LCase(Replace(Ag(0),"-", "/")) = "/h" or Replace(Ag(0),"-", "/") = "/?" then
wscript.echo HelpMsg
wscript.quit
End If
ElseIf Ag.count > 2 then
wscript.echo vbcrlf & " ShVerb - To many parameters" & vbcrlf & " Use quotes around filenames and verbs containing spaces" & vbcrlf
wscript.echo HelpMsg
wscript.quit
End If
If fso.DriveExists(Ag(0)) = True then
Set objFolder = objShell.Namespace(fso.GetFileName(Ag(0)))
' Set objFolderItem = objFolder.ParseName(fso.GetFileName(Ag(0)))
Set objFolderItem = objFolder.self
msgbox ag(0)
ElseIf fso.FolderExists(Ag(0)) = True then
Set objFolder = objShell.Namespace(fso.GetParentFolderName(Ag(0)))
Set objFolderItem = objFolder.ParseName(fso.GetFileName(Ag(0)))
ElseIf fso.fileExists(Ag(0)) = True then
Set objFolder = objShell.Namespace(fso.GetParentFolderName(Ag(0)))
Set objFolderItem = objFolder.ParseName(fso.GetFileName(Ag(0)))
Else
wscript.echo " ShVerb - " & Ag(0) & " not found"
wscript.echo HelpMsg
wscript.quit
End If
Set objVerbs = objFolderItem.Verbs
'If only one argument list verbs for that item
If Ag.count = 1 then
For Each cmd in objFolderItem.Verbs
If len(cmd) <> 0 then CmdList = CmdList & vbcrlf & replace(cmd.name, "&", "")
Next
wscript.echo mid(CmdList, 2)
'If two arguments do verbs for that item
ElseIf Ag.count = 2 then
For Each cmd in objFolderItem.Verbs
If lcase(replace(cmd, "&", "")) = LCase(Ag(1)) then
wscript.echo(Cmd.doit)
Exit For
End If
Next
'Properties is special cased. Script has to stay running for Properties dialog to show.
If Lcase(Ag(1)) = "properties" then
WSHShell.AppActivate(ObjFolderItem.Name & " Properties")
msgbox "This message box has to stay open to keep the " & ObjFolderItem.Name & " Properties dialog open."
End If
End If
End If
Not sure if this question has already asked.
Created a batch file, its working fine. But what I need is, to keep open command prompt when batch is executing. Basically, when we click on batch file, the "command prompt" as soon as batch execution completes. If any error comes I cants see any error. So i want to freeze command prompt. Hope I am clear with my question.
Thank you.
Arfeen.
rem Pause if command double clicked
If /i "%cmdcmdline:~0,6%"=="cmd /c" pause
Put above as last two lines. Pauses if double clicked but doesn't pause if typed.
Run As Administrator
You need to right click and choose Run As Administrator. Only certain programs show the elevation dialog. Explorer and Task Manager being the two common ones. This script automates right clicking.
Lists or runs an explorer verb (right click menu) on a file or folder
ShVerb <filename> [verb]
Used without a verb it lists the verbs available for the file or folder
The program lists most verbs but only ones above the first separator
of the menu work when used this way
The Properties verb can be used. However the program has to keep running
to hold the properties dialog open. It keeps running by displaying
a message box.
The script
HelpMsg = vbcrlf & " ShVerb" & vbcrlf & vbcrlf & " David Candy 2014" & vbcrlf & vbcrlf & " Lists or runs an explorer verb (right click menu) on a file or folder" & vbcrlf & vbcrlf & " ShVerb <filename> [verb]" & vbcrlf & vbcrlf & " Used without a verb it lists the verbs available for the file or folder" & vbcrlf & vbcrlf
HelpMsg = HelpMsg & " The program lists most verbs but only ones above the first separator" & vbcrlf & " of the menu work when used this way" & vbcrlf & vbcrlf
HelpMsg = HelpMsg & " The Properties verb can be used. However the program has to keep running" & vbcrlf & " to hold the properties dialog open. It keeps running by displaying" & vbcrlf & " a message box."
Set objShell = CreateObject("Shell.Application")
Set Ag = WScript.Arguments
set WshShell = WScript.CreateObject("WScript.Shell")
Set fso = CreateObject("Scripting.FileSystemObject")
If Ag.count = 0 then
wscript.echo " ShVerb - No file specified"
wscript.echo HelpMsg
wscript.quit
Else If Ag.count = 1 then
If LCase(Replace(Ag(0),"-", "/")) = "/h" or Replace(Ag(0),"-", "/") = "/?" then
wscript.echo HelpMsg
wscript.quit
End If
ElseIf Ag.count > 2 then
wscript.echo vbcrlf & " ShVerb - To many parameters" & vbcrlf & " Use quotes around filenames and verbs containing spaces" & vbcrlf
wscript.echo HelpMsg
wscript.quit
End If
If fso.DriveExists(Ag(0)) = True then
Set objFolder = objShell.Namespace(fso.GetFileName(Ag(0)))
' Set objFolderItem = objFolder.ParseName(fso.GetFileName(Ag(0)))
Set objFolderItem = objFolder.self
msgbox ag(0)
ElseIf fso.FolderExists(Ag(0)) = True then
Set objFolder = objShell.Namespace(fso.GetParentFolderName(Ag(0)))
Set objFolderItem = objFolder.ParseName(fso.GetFileName(Ag(0)))
ElseIf fso.fileExists(Ag(0)) = True then
Set objFolder = objShell.Namespace(fso.GetParentFolderName(Ag(0)))
Set objFolderItem = objFolder.ParseName(fso.GetFileName(Ag(0)))
Else
wscript.echo " ShVerb - " & Ag(0) & " not found"
wscript.echo HelpMsg
wscript.quit
End If
Set objVerbs = objFolderItem.Verbs
'If only one argument list verbs for that item
If Ag.count = 1 then
For Each cmd in objFolderItem.Verbs
If len(cmd) <> 0 then CmdList = CmdList & vbcrlf & replace(cmd.name, "&", "")
Next
wscript.echo mid(CmdList, 2)
'If two arguments do verbs for that item
ElseIf Ag.count = 2 then
For Each cmd in objFolderItem.Verbs
If lcase(replace(cmd, "&", "")) = LCase(Ag(1)) then
wscript.echo Cmd.doit
Exit For
End If
Next
'Properties is special cased. Script has to stay running for Properties dialog to show.
If Lcase(Ag(1)) = "properties" then
WSHShell.AppActivate(ObjFolderItem.Name & " Properties")
msgbox "This message box has to stay open to keep the " & ObjFolderItem.Name & " Properties dialog open."
End If
End If
End If
Try to set PAUSE at the end???
I am trying to learn how to run a vbscript in elevated mode. I can't quite get this to work if there are arguments to the vbscript I am trying to run elevated.
Here is a simple example:
OSVersion.vbs
' Return a string indicating the operating system
strComputer = "."
Set objWMIService = GetObject("winmgmts:" _
& "{impersonationLevel=impersonate}!\\" & strComputer & "\root\cimv2")
Set colOperatingSystems = objWMIService.ExecQuery _
("Select * from Win32_OperatingSystem")
'Wscript.echo Wscript.Arguments(0)
For Each objOperatingSystem in colOperatingSystems
Wscript.StdOut.Write objOperatingSystem.Caption
Wscript.StdOut.WriteBlankLines(1)
Wscript.StdOut.Write "Version " & objOperatingSystem.Version
Next
RunElevated.vbs
' Run the script in elevated mode
'
' This will be needed to install programs into Program Files
prgName = Wscript.Arguments.Item(0)
prgArgs = ""
If Wscript.Arguments.Count > 1 Then
For i = 1 To Wscript.Arguments.Count - 1
prgArgs = prgArgs & " " & Wscript.Arguments.Item(i)
Next
End If
Wscript.echo "Running: " & prgName & prgArgs
Set objShell = CreateObject("Shell.Application")
Set fso = CreateObject("Scripting.FileSystemObject")
strPath = fso.GetParentFolderName (WScript.ScriptFullName)
If fso.FileExists(strPath & "\" & prgName) Then
objShell.ShellExecute "wscript.exe", _
Chr(34) & strPath & "\" & prgName & Chr(34), _
"", "runas", 1
Else
Wscript.echo "Script file not found"
End If
The OSVersion.vbs script runs fine:
cscript OSVersion.vbs
Microsoft (R) Windows Script Host Version 5.8
Copyright (C) Microsoft Corporation. All rights reserved.
Microsoft Windows 7 Home Premium
Version 6.1.7601
Problem #1 When I try to run this elevated, nothing appears on stdout
C:\Users\ChemModeling\Documents\FreeThink\Java\install>cscript RunElevated.vbs OSVersion.vbs
Microsoft (R) Windows Script Host Version 5.8
Copyright (C) Microsoft Corporation. All rights reserved.
Running: OSVersion.vbs
Problem #2 I cannot figure out how to include an argument to the script I am passing to RunElevated. I read that you should use a syntax like '"my parameters here"' so I tried this:
' Run the script in elevated mode
'
' This will be needed to install programs into Program Files
prgName = Wscript.Arguments.Item(0)
prgArgs = ""
If Wscript.Arguments.Count > 1 Then
For i = 1 To Wscript.Arguments.Count - 1
prgArgs = prgArgs & " " & Wscript.Arguments.Item(i)
Next
End If
Wscript.echo "Running: " & prgName & prgArgs
Set objShell = CreateObject("Shell.Application")
Set fso = CreateObject("Scripting.FileSystemObject")
strPath = fso.GetParentFolderName (WScript.ScriptFullName)
If fso.FileExists(strPath & "\" & prgName) Then
objShell.ShellExecute "wscript.exe", _
Chr(39) & Chr(34) & strPath & "\" & prgName & prgArgs & Chr(34) & Chr(39), _
"", "runas", 1
Else
Wscript.echo "Script file not found"
End If
If I run:
cscript RunElevated.vbs OSVersion.vbs Test
Microsoft (R) Windows Script Host Version 5.8
Copyright (C) Microsoft Corporation. All rights reserved.
Running: OSVersion.vbs Test
I then get an error "There is no engine for file extension ".vbs Test".
Can anyone suggest what I need to change?
I have made some headway in resolving this problem-
I changed the first script to:
OSVersion.vbs
' Return a string indicating the operating system
strComputer = "."
Set objWMIService = GetObject("winmgmts:" _
& "{impersonationLevel=impersonate}!\\" & strComputer & "\root\cimv2")
Set colOperatingSystems = objWMIService.ExecQuery _
("Select * from Win32_OperatingSystem")
'Wscript.echo Wscript.Arguments(0)
For Each objOperatingSystem in colOperatingSystems
Wscript.Echo objOperatingSystem.Caption
Wscript.Echo "Version " & objOperatingSystem.Version
Next
so I could actually see if something happened.
I changed the second script to:
' Run the script in elevated mode
'
' This will be needed to install programs into Program Files
prgName = Wscript.Arguments.Item(0)
prgArgs = ""
If Wscript.Arguments.Count > 1 Then
For i = 1 To Wscript.Arguments.Count - 1
prgArgs = prgArgs & " " & Wscript.Arguments.Item(i)
Next
End If
Wscript.echo "Running: " & prgName & prgArgs
Set objShell = CreateObject("Shell.Application")
Set fso = CreateObject("Scripting.FileSystemObject")
strPath = fso.GetParentFolderName (WScript.ScriptFullName)
If fso.FileExists(strPath & "\" & prgName) Then
objShell.ShellExecute "wscript.exe", _
Chr(34) & strPath & "\" & prgName & Chr(34) & prgArgs, _
"", "runas", 1
Else
Wscript.echo "Script file not found"
End If
and used: wscript RunElevated.vbs OSVersion.vbs Test
And now I see the information I am echoing in popups when the script runs.
So I am back to problem #1, I am starting a new shell to run in administrator mode, so if I switch to cscript and try to write the information to stdout or use Wscript.StdOut.Write, it will appear in the new shell and I will never see it, or at least that's what I believe the problem is.
Is there a standard way to address this issue?
Problem #1:
You're not seeing any output when you run your script elevated, because the RunElevated.vbs script re-launches your OSVersion.vbs script using WScript.exe. OSVersion.vbs uses Standard Input and Output which are only available from the console. Changing the command line in RunElevated.vbs to use cscript.exe instead of wscript.exe solves this problem. For more, check out my article Error Trapping and Capturing Third-Party Output in WSH.
Problem #2
It looks like your problem here is that you're mixing different kinds of quotes. A command should look like this:
"C:\path with spaces\command.exe" "parameter with spaces" "and another"
Try out these scripts.
RunElevated.vbs
' Run a script in Elevated Mode
strName = WScript.Arguments.Item(0)
strArgs = ""
If WScript.Arguments.Count > 1 Then
For i = 1 To WScript.Arguments.Count - 1
strArgs = strArgs & " " & WScript.Arguments.Item(i)
Next
End If
WScript.echo "Running: ", strName, strArgs
Set objShell = CreateObject("Shell.Application")
Set objFso = CreateObject("Scripting.FileSystemObject")
strPath = objFso.GetParentFolderName(WScript.ScriptFullName)
strParams = Chr(34) & strPath & "\" & strName & Chr(34)
If strArgs <> "" Then
strParams = strParams & " " & Chr(34) & strArgs & Chr(34)
End If
If objFso.FileExists(strPath & "\" & strName) Then
objShell.ShellExecute "cscript.exe", strParams, "", "runas", 1
Else
WScript.echo "Script file not found"
End If
OSVersion.vbs
'Test passing arguments to launched script
If WScript.Arguments.Count > 0 Then
For i = 0 To WScript.Arguments.Count - 1
strArgs = Trim(strArgs & " " & WScript.Arguments.Item(i))
Next
End If
' Return a string indicating the operating system
strComputer = "."
Set objWMIService = GetObject("winmgmts:" _
& "{impersonationLevel=impersonate}!\\" & strComputer & "\root\cimv2")
Set colOperatingSystems = objWMIService.ExecQuery _
("Select * from Win32_OperatingSystem")
For Each objOperatingSystem in colOperatingSystems
WScript.StdOut.Write objOperatingSystem.Caption
WScript.StdOut.WriteBlankLines(1)
WScript.StdOut.Write "Version " & objOperatingSystem.Version
WScript.StdOut.WriteBlankLines(2)
Next
' Print out any passed arguments
WScript.StdOut.WriteBlankLines(2)
WScript.StdOut.Write strArgs
WScript.StdOut.WriteBlankLines(2)
' Keep the window from closing before you get a chance to read it
WScript.StdOut.Write "Press any key to continue "
strInput = WScript.StdIn.Read(1)
In order to capture the output, I would probably try a different approach using the WshShell Execute method. There are command line tools available such as Elevate or HStart that can launch command lines with elevated privileges. Here's how I would do it using Elevate.
' Run a script in Elevated Mode
strName = WScript.Arguments.Item(0)
strArgs = ""
If WScript.Arguments.Count > 1 Then
For i = 1 To WScript.Arguments.Count - 1
strArgs = strArgs & " " & WScript.Arguments.Item(i)
Next
End If
WScript.echo "Running: ", strName, strArgs
Set WshShell = CreateObject("WScript.Shell")
Set objFso = CreateObject("Scripting.FileSystemObject")
strPath = objFso.GetParentFolderName(WScript.ScriptFullName)
strParams = Chr(34) & strPath & "\" & strName & Chr(34)
If strArgs <> "" Then
strParams = strParams & " " & Chr(34) & strArgs & Chr(34)
End If
If objFso.FileExists(strPath & "\" & strName) Then
Set WshShellExec = WshShell.Exec("elevate cscript.exe " & strParams)
Select Case WshShellExec.Status
Case WshFinished
strOutput = WshShellExec.StdOut.ReadAll
Case WshFailed
strOutput = WshShellExec.StdErr.ReadAll
End Select
Else
WScript.echo "Script file not found"
End If
WScript.echo strOutput
I discovered two interesting things; first, I had to get the proper number of quotations and spaces, second, I had to actually call an interim script first and then call the final script elevated.
Intial Calling Script snippet:
If objFSO.FileExists("C:\Windows\System32\elevate.vbs") Then
objWSHShell.ShellExecute "wscript.exe", Chr(34) & Chr(34) & "C:\Windows\System32\elevate.vbs" & Chr(32) & strCampus & Chr(32) & strLocation & Chr(32) & strAssetTag & Chr(34) & Chr(34), "", "", 1
Else
MsgBox "Regbrand script file not found",0,"Error Message"
End If
Notice the Chr() statements and the 3 variables being passed from the original script to the interim script.
Interim Script snippet:
If Args.Count = 0 Then
MsgBox "Missing arguments to UAC permissions script.",0,"Missing Parameters"
Else
strCampus = Args.Item(0)
strLocation = Args.Item(1)
strAssetTag = Args.Item(2)
strFilePath = objFSO.GetParentFolderName (WScript.ScriptFullName)
If objFSO.FileExists("C:\Windows\System32\regbrand.vbs") Then
objWSHShell.ShellExecute "wscript.exe", Chr(34) & Chr(34) & "C:\Windows\System32\regbrand.vbs" & Chr(32) & strCampus & Chr(32) & strLocation & Chr(32) & strAssetTag & Chr(34) & Chr(34), "", "runas", 1
Else
MsgBox "Script file not found",0,"Error Message"
End If
End If
In the interim script we pass the same arguments to the final script. Again, note the Chr() statements.
The first script passes 3 arguments and calls the interim script, which in turn calls the 3rd script "regbrand.vbs" with elevated permissions. It works just like it should. If you remove the interim script, it did not work. I have not figured that out yet, but believe it has something to do with calling the original script from a network location. However, I hope the syntax for calling and passing the parameters is helpful.