Run PowerShell script from folder Program Files via VBScript - powershell

How can I run a PowerShell script from within the %ProgramFiles% folder?
I have tried the variable %ProgramFiles% without any progress, also "Program Files" but can't get ut to work.
My current code
Set shell = WScript.CreateObject("WScript.shell")
shell.Run("powershell C:\Program Files\Temp\test.ps1"), 0 , True
It's working if I use a network share without any spaces
Set shell = WScript.CreateObject("WScript.shell")
shell.Run("powershell \\domain\SYSVOL\script\test.ps1"), 0 , True
I have also tried using """ but can't get PowerShell to work.
Anyone know how to solve this? I need to use VBScript in order to start the PowerShell script in the background at logon via a GPO. Otherwise it will show a PowerShell window.

Try this. Add parameter "-file" and double quotes around the path. You can get and store %ProgramFiles% in a variable using ExpandEnvironmentStrings:
Set shell = WScript.CreateObject("WScript.shell")
sProgramFiles = shell.ExpandEnvironmentStrings("%PROGRAMFILES%")
shell.Run "powershell -file """ & sProgramFiles & "\Temp\test.ps1""", 0 , True

Related

PowerShell in Task Manager Shows Window

I am trying to make Task Schedule Task so it is completely invisible that a PowerShell script is running so I created a Task on my Win10 machine configured as follows:
Program/Script:
powershell.exe
Add arguments (optional):
-WindowStyle Hidden -command "& {Out-File 'C:\temp\somefile.txt'}" -NonInteractive -NoLogo -NoProfile
When I run this task the powershell command windows pops up for a split second which I don't want.
You can get around this with an 'Application Host' type wrapper. This is a known issue with powershell as a console-based host.
The most convenient way to do this I've found, is to use WScript.exe and run a VBS script that will invoke the process "invisibly", with no console or task bar flicker.
VBS Code:
On Error Resume Next
ReDim args(WScript.Arguments.Count-1)
For i = 0 To WScript.Arguments.Count-1
If InStr(WScript.Arguments(i), " ") > 0 Then
args(i) = Chr(34) & WScript.Arguments(i) & Chr(34)
Else
args(i) = WScript.Arguments(i)
End If
Next
CreateObject("WScript.Shell").Run Join(args, " "), 0, False
Save the above code in a file with extension '.vbs', and place it somewhere it can be run by the client running the task. This may be in a protected fileshare on the network (if you expect the script it invokes to only run while connected to the network), or locally on the client.
Now when you invoke your console-based script (PowerShell, BAT, CScript, etc.), you invoke this VBS script with WScript explicitly WScript.exe. It also pays to throw on the 'Batch Mode' parameter //B which will suppress script errors & prompts - such as if the wrapper file itself can't be found.
At this point, all you need to do is pass powershell & the command you want powershell to run to this launch sequence:
WScript.exe //B "\\Path\To\Launcher.VBS" powershell.exe -ExecutionPolicy ByPass -file "\\Powershell\Script\To\Run"
I had the same problem, it was resolved at the simple way.
When you create a Task on Windows, just set this configuration:
Open Properties dialog;
Then you check Run whether user is logged on or not;
You can check Do not store password to avoid asking for PC password on Task execution;
In Add arguments (optional): just:
-File 'C:\temp\somefile.txt
This spcript will run without popup the prompt.
Solved in this link below:
https://stackoverflow.com/a/50630717/19926325

Running PowerShell code inside VBS with many nested quotes, in one line

I'm starting to see double here from staring at this so long. I am trying to use an environment variable inside a script path that I'm going to launch from PowerShell, all initiated from a single line inside an mshta command run from a scheduled task on logon.
In case you were wondering, MSHTA can execute HTML/VBS/JS as if a local GUI app.
mshta vbscript:Execute("CreateObject(""Wscript.Shell"").Run ""powershell -NoLogo -Command """"& '\\$env:USERDNSDOMAIN\FOLDER1\FOLDER with Spaces\Folder3\Script-To-Run.ps1'"""""", 0 : window.close")
Premise: I have to do it this way to prevent momentary popups that flash onscreen when running from a scheduled task in user context. I cannot run this script in the System context.
I know that putting anything inside two single quotes gives me a string literal but if I try double quotes it seems to then use the space in the path. I've tried separating the two and concatenating them in all sorts of ways to no avail.
VBS equivalent of $env:USERDNSDOMAIN is
CreateObject("Wscript.Shell").ExpandEnvironmentStrings( "%USERDNSDOMAIN%" )
If the goal/purpose is to execute a PowerShell script without displaying the powershell.exe console window, you can do this by running it from a VBScript script executed by wscript.exe (not cscript.exe).
Example VBScript script:
Dim WshShell
Set WshShell = CreateObject("WScript.Shell")
WshShell.Run "%SystemRoot%\system32\WindowsPowerShell\v1.0\powershell.exe -NoProfile -ExecutionPolicy Bypass -File """d:\path name\whatever.ps1"" [parameter [...]]", 0, False
The second parameter of the WshShell object's Run method is 0, so powershell.exe executes from a hidden window.
(Hint: The -File parameter to powershell.exe is generally easier to use than -Command. It must be the last parameter on the powershell.exe command line.)
End result: VBScript script runs the PowerShell script from a hidden window. Also, the VBScript itself has no console window, because you executed it using wscript.exe (the GUI host).

Is it possible to react to a VBScript msgbox from a PowerShell script?

I've been working to make manual processes more of a one-click process and I've run into an issue with these msgbox popups from a VBScript script.
Essentially, I am using PowerShell and doing something like:
foreach ($loc in $locs):
& cscript $loc
Where the $loc in $locs is a variable holding the path of a .vbs file that needs to be run.
The issue is that one of our developers included two msgbox statements in each of the .vbs files and those pop up and require you to click OK. It would be trivial to edit the VBScript scripts and remove these, but I do not want to change our developers' scripts - so the question is: is it possible to make PowerShell react to the msgbox(s) that are generated from the cscript line?
I'm not sure how I would bring the box into context or react to it via PowerShell.
Run the scripts in batch mode. This will prevent any prompt from stalling execution:
foreach ($loc in $locs){
& cscript //B $loc
}
From the cscript /? usage message:
Usage: CScript scriptname.extension [option...] [arguments...]
Options:
//B Batch mode: Suppresses script errors and prompts from displaying
//D Enable Active Debugging
//E:engine Use engine for executing script
//H:CScript Changes the default script host to CScript.exe
//H:WScript Changes the default script host to WScript.exe (default)
//I Interactive mode (default, opposite of //B)
...

How do I write this in Powershell script?

I am very new to Powershell script.
I am trying to run a powershell script from a cmd
powershell.exe Set-ExecutionPolicy Unrestricted
powershell.exe .\startup.ps1
I need two lines within powershell script.
%WINDIR%\system32\inetsrv\appcmd.exe add apppool /name:"VCPool" /managedRuntimeVersion:"v4.0" /managedPipelineMode:"Integrated"
%WINDIR%\system32\inetsrv\appcmd.exe set app "WebRole_IN_0_VC/" /applicationPool:"VCPool"
Can I simply write it like this within the ps1 file?
& %WINDIR%\system32\inetsrv\appcmd.exe add apppool /name:"VCPool" /managedRuntimeVersion:"v4.0" /managedPipelineMode:"Integrated"
Many Thanks
Short answer, including a question: Why the hell does that need to be a PowerShell script?
You can simply create a batch file containing
%WINDIR%\system32\inetsrv\appcmd.exe add apppool /name:"VCPool" /managedRuntimeVersion:"v4.0" /managedPipelineMode:"Integrated"
%WINDIR%\system32\inetsrv\appcmd.exe set app "WebRole_IN_0_VC/" /applicationPool:"VCPool"
and run that directly instead of trying to figure out execution policies, etc.
Furthermore, appcmd should probably be in your PATH, so you can run it directly without needing to specify the full path to the program.
Longer answer, actually using PowerShell: There are two problems here.
You want to run a PowerShell script without having the appropriate execution policy set. This can be done with
powershell -ExecutionPolicy Unrestricted -File myscript.ps1
You need to adjust environment variable usage within PowerShell scripts, as % is not used to expand environment variables there. So you actually need
& $Env:WinDir\system32\inetsrv\appcmd.exe add apppool /name:VCPool /managedRuntimeVersion:v4.0 /managedPipelineMode:Integrated
& $Env:WinDir\system32\inetsrv\appcmd.exe set app WebRole_IN_0_VC/ /applicationPool:VCPool
Note also that you need an ampersand (&) before each line as a variable name in the beginning of a line switches into expression mode while you want to run a command, therefore needing command mode.
Furthermore quoted arguments can be a bit of a pain in PowerShell. PowerShell tries quoting arguments when necessary and it's not always obvious when things go wrong what actually comes out on the other end. In this case the easiest way is to not quote the arguments in any way whcih ensures that they come out correctly:
PS Home:\> args add apppool /name:VCPool /managedRuntimeVersion:v4.0 /managedPipelineMode:Integrated
argv[1] = add
argv[2] = apppool
argv[3] = /name:VCPool
argv[4] = /managedRuntimeVersion:v4.0
argv[5] = /managedPipelineMode:Integrated
PS Home:\> args set app WebRole_IN_0_VC/ /applicationPool:VCPool
argv[1] = set
argv[2] = app
argv[3] = WebRole_IN_0_VC/
argv[4] = /applicationPool:VCPool
However, if appcmd actually needs the quotes around the argument after a colon, then you need to quote the whole argument with single quotes and add the double quotes back in:
& $Env:WinDir\system32\inetsrv\appcmd.exe set app WebRole_IN_0_VC/ '/applicationPool:"VCPool"'
You might like to know you can combine the two launch statements into a single call within your CMD file:
powershell.exe -noprofile -executionpolicy unrestricted -file .\startup.ps1
The only slightly strange thing about calling appcmd.exe from PowerShell is you must surround the parameter in quotes, even if it contains no spaces. You have already done this, so yes it should work.

%temp% etc not working

I have the below that is used as a batch file that launches powershell (too long to go over but it is used in another script).
Anyway, I noticed the %systemroot%\temp and %systemroot% does not work.
Any idea how I can fix this?
%systemroot%\system32\WindowsPowerShell\v1.0\powershell.exe -ExecutionPolicy Unrestricted -File %SystemRoot%\TEMP\ROFS\testing_script_log.ps1
Thanks,
If you are executing that line from PowerShell rather than from CMD, you can use the PowerShell environment variable syntax:
PS C:\> & "$env:SystemRoot\System32\WindowsPowerShell\v1.0\powershell.exe"
You can use [Environment]::ExpandEnvironmentVariables to expand environment variables within a string the old-fashioned way.
$s = '%systemroot%\temp'
[Environment]::ExpandEnvironmentVariables($s)
Successfully verified with below code C#.
//file location - User Variables
string fileLocation = Environment.GetEnvironmentVariable("AZURE_FILE_PATH", EnvironmentVariableTarget.User);
//file location - System Variables
string fileLocation = Environment.GetEnvironmentVariable("AZURE_FILE_PATH", EnvironmentVariableTarget.Machine);
On Powershell script
& "D:\Visual_Studio_Workspace\AzureUpload\AzureUpload\bin\Debug\AzureUpload.exe"
AzureUpload.exe -- contain the above code C# code as Console application (Visual_Studio_Workspace\AzureUpload\AzureUpload\bin\Debug{.exe file location})