How to run a PowerShell script without displaying a window? - windows

How is it possible to run a PowerShell script without displaying a window or any other sign to the user?
In other words, the script should run quietly in the background without any sign to the user.
Extra credit for an answer that does not use third party components :)

You can either run it like this (but this shows a window for a while):
PowerShell.exe -WindowStyle hidden { your script.. }
Or you use a helper file I created to avoid the window called PsRun.exe that does exactly that. You can download the source and exe file from Run scheduled tasks with WinForm GUI in PowerShell. I use it for scheduled tasks.
Edited: as Marco noted this -WindowStyle parameter is available only for V2 and above.

I was having this same issue. I found out if you go to the Task in Task Scheduler that is running the powershell.exe script, you can click "Run whether user is logged on or not" and that will never show the powershell window when the task runs.

You can use the PowerShell Community Extensions and do this:
start-process PowerShell.exe -arg $pwd\foo.ps1 -WindowStyle Hidden
You can also do this with VBScript: http://blog.sapien.com/index.php/2006/12/26/more-fun-with-scheduled-powershell/
Schedule Hidden PowerShell Tasks (Internet Archive)
More fun with scheduled PowerShell (Internet Archive)
(Via this forum thread.)

The answer with -WindowStyle Hidden is great but the windows will still flash.
I've never seen a window flash when calling it via cmd /c start /min "".
Your machine or setup may differ but it works well for me.
1. Call a file
cmd /c start /min "" powershell -WindowStyle Hidden -ExecutionPolicy Bypass -File "C:\Users\username\Desktop\test.ps1"
2. Call a file with arguments
cmd /c start /min "" powershell -WindowStyle Hidden -ExecutionPolicy Bypass -Command ". 'C:\Users\username\Desktop\test me.ps1' -Arg1 'Hello' -Arg2 'World'"ps1'; -Arg1 'Hello' -Arg2 ' World'"
Powershell content for 2. Call a file with arguments is:
Param
(
[Parameter(Mandatory = $true, HelpMessage = 'The 1st test string parameter.')]
[String]$Arg1,
[Parameter(Mandatory = $true, HelpMessage = 'The 2nd test string parameter.')]
[String]$Arg2
)
Write-Host $Arg1
Write-Host $Arg2
3. Call a file with a function and arguments
cmd /c start /min "" powershell -WindowStyle Hidden -ExecutionPolicy Bypass -Command ". 'C:\Users\username\Desktop\test me.ps1'; Get-Test -stringTest 'Hello World'"
Powershell content for 3. Call a file with a function and arguments is:
function Get-Test() {
[cmdletbinding()]
Param
(
[Parameter(Mandatory = $true, HelpMessage = 'The test string.')]
[String]$stringTest
)
Write-Host $stringTest
return
}
In case you need to run this in Task Scheduler then call %comspec% as the Program/Script and then code for calling the file above as the argument.
Note: All examples work when the PS1 file has spaces in its path.

Here's an approach that that doesn't require command line args or a separate launcher. It's not completely invisible because a window does show momentarily at startup. But it then quickly vanishes. Where that's OK, this is, I think, the easiest approach if you want to launch your script by double-clicking in explorer, or via a Start menu shortcut (including, of course the Startup submenu). And I like that it's part of the code of the script itself, not something external.
Put this at the front of your script:
$t = '[DllImport("user32.dll")] public static extern bool ShowWindow(int handle, int state);'
add-type -name win -member $t -namespace native
[native.win]::ShowWindow(([System.Diagnostics.Process]::GetCurrentProcess() | Get-Process).MainWindowHandle, 0)

Here's a one-liner:
mshta vbscript:Execute("CreateObject(""Wscript.Shell"").Run ""powershell -NoLogo -Command """"& 'C:\Example Path That Has Spaces\My Script.ps1'"""""", 0 : window.close")
Although it's possible for this to flash a window very briefly, that should be a rare occurrence.

ps1 hidden from the Task Scheduler and shortcut too
mshta vbscript:Execute("CreateObject(""WScript.Shell"").Run ""powershell -ExecutionPolicy Bypass & 'C:\PATH\NAME.ps1'"", 0:close")

I think that the best way to hide the console screen of the PowerShell when your are running a background scripts is this code ("Bluecakes" answer).
I add this code in the beginning of all my PowerShell scripts that I need to run in background.
# .Net methods for hiding/showing the console in the background
Add-Type -Name Window -Namespace Console -MemberDefinition '
[DllImport("Kernel32.dll")]
public static extern IntPtr GetConsoleWindow();
[DllImport("user32.dll")]
public static extern bool ShowWindow(IntPtr hWnd, Int32 nCmdShow);
'
function Hide-Console
{
$consolePtr = [Console.Window]::GetConsoleWindow()
#0 hide
[Console.Window]::ShowWindow($consolePtr, 0)
}
Hide-Console
If this answer was help you, please vote to "Bluecakes" in his answer in this post.

I was having this problem when running from c#, on Windows 7, the "Interactive Services Detection" service was popping up when running a hidden powershell window as the SYSTEM account.
Using the "CreateNoWindow" parameter prevented the ISD service popping up it's warning.
process.StartInfo = new ProcessStartInfo("powershell.exe",
String.Format(#" -NoProfile -ExecutionPolicy unrestricted -encodedCommand ""{0}""",encodedCommand))
{
WorkingDirectory = executablePath,
UseShellExecute = false,
CreateNoWindow = true
};

Here's a fun demo of controlling the various states of the console, including minimize and hidden.
Add-Type -Name ConsoleUtils -Namespace WPIA -MemberDefinition #'
[DllImport("Kernel32.dll")]
public static extern IntPtr GetConsoleWindow();
[DllImport("user32.dll")]
public static extern bool ShowWindow(IntPtr hWnd, Int32 nCmdShow);
'#
$ConsoleMode = #{
HIDDEN = 0;
NORMAL = 1;
MINIMIZED = 2;
MAXIMIZED = 3;
SHOW = 5
RESTORE = 9
}
$hWnd = [WPIA.ConsoleUtils]::GetConsoleWindow()
$a = [WPIA.ConsoleUtils]::ShowWindow($hWnd, $ConsoleMode.MAXIMIZED)
"maximized $a"
Start-Sleep 2
$a = [WPIA.ConsoleUtils]::ShowWindow($hWnd, $ConsoleMode.NORMAL)
"normal $a"
Start-Sleep 2
$a = [WPIA.ConsoleUtils]::ShowWindow($hWnd, $ConsoleMode.MINIMIZED)
"minimized $a"
Start-Sleep 2
$a = [WPIA.ConsoleUtils]::ShowWindow($hWnd, $ConsoleMode.RESTORE)
"restore $a"
Start-Sleep 2
$a = [WPIA.ConsoleUtils]::ShowWindow($hWnd, $ConsoleMode.HIDDEN)
"hidden $a"
Start-Sleep 2
$a = [WPIA.ConsoleUtils]::ShowWindow($hWnd, $ConsoleMode.SHOW)
"show $a"

When you scheduled task, just select "Run whether user is logged on or not" under the "General" tab.
Alternate way is to let the task run as another user.

Create a shortcut that calls the PowerShell script and set the Run option to Minimized. This will prevent a window from flashing although you will still get a momentary blip of the script running on the Task Bar.

For easy command line usage, there is a simple wrapper app:
https://github.com/stax76/run-hidden
Example command line:
run-hidden powershell -command calc.exe

I got really tired of going through answers only to find it did not work as expected.
Solution
Make a vbs script to run a hidden batch file which launches the powershell script. Seems silly to make 3 files for this task but atleast the total size is less than 2KB and it runs perfect from tasker or manually (you dont see anything).
scriptName.vbs
Set WinScriptHost = CreateObject("WScript.Shell")
WinScriptHost.Run Chr(34) & "C:\Users\leathan\Documents\scriptName.bat" & Chr(34), 0
Set WinScriptHost = Nothing
scriptName.bat
powershell.exe -ExecutionPolicy Bypass C:\Users\leathan\Documents\scriptName.ps1
scriptName.ps1
Your magical code here.

I have created a small tool passing the call to any console tool you want to start windowless through to the original file:
https://github.com/Vittel/RunHiddenConsole
After compiling just rename the executable to "<targetExecutableName>w.exe" (append a "w"), and put it next to the original executable.
You can then call e.G. powershellw.exe with the usual parameters and it wont pop up a window.
If someone has an idea how to check whether the created process is waiting for input, ill be happy to include your solution :)

Wait until Powershell is executed and get the result in vbs
This is an improved version of the Omegastripes code Hide command prompt window when using Exec()
Splits the confused responses from cmd.exe into an array instead of putting everything into a hard-to-parse string.
In addition, if an error occurs during the execution of cmd.exe, a message about its occurrence will become known in vbs.
Option Explicit
Sub RunCScriptHidden()
strSignature = Left(CreateObject("Scriptlet.TypeLib").Guid, 38)
GetObject("new:{C08AFD90-F2A1-11D1-8455-00A0C91F3880}").putProperty strSignature, Me
objShell.Run ("""" & Replace(LCase(WScript.FullName), "wscript", "cscript") & """ //nologo """ & WScript.ScriptFullName & """ ""/signature:" & strSignature & """"), 0, True
End Sub
Sub WshShellExecCmd()
For Each objWnd In CreateObject("Shell.Application").Windows
If IsObject(objWnd.getProperty(WScript.Arguments.Named("signature"))) Then Exit For
Next
Set objParent = objWnd.getProperty(WScript.Arguments.Named("signature"))
objWnd.Quit
'objParent.strRes = CreateObject("WScript.Shell").Exec(objParent.strCmd).StdOut.ReadAll() 'simple solution
Set exec = CreateObject("WScript.Shell").Exec(objParent.strCmd)
While exec.Status = WshRunning
WScript.Sleep 20
Wend
Dim err
If exec.ExitCode = WshFailed Then
err = exec.StdErr.ReadAll
Else
output = Split(exec.StdOut.ReadAll,Chr(10))
End If
If err="" Then
objParent.strRes = output(UBound(output)-1) 'array of results, you can: output(0) Join(output) - Usually needed is the last
Else
objParent.wowError = err
End If
WScript.Quit
End Sub
Const WshRunning = 0,WshFailed = 1:Dim i,name,objShell
Dim strCmd, strRes, objWnd, objParent, strSignature, wowError, output, exec
Set objShell = WScript.CreateObject("WScript.Shell"):wowError=False
strCmd = "C:\Windows\System32\WindowsPowerShell\v1.0\powershell.exe -ExecutionPolicy Bypass Write-Host Hello-World."
If WScript.Arguments.Named.Exists("signature") Then WshShellExecCmd
RunCScriptHidden
If wowError=False Then
objShell.popup(strRes)
Else
objShell.popup("Error=" & wowError)
End If

powershell.exe -windowstyle hidden -noexit -ExecutionPolicy Bypass -File <path_to_file>
then set the run: Minimized
should work as expected without added code for hidden window flash
just slightly more delayed execution.

Here is a working solution in windows 10 that does not include any third-party components. It works by wrapping the PowerShell script into VBScript.
Step 1: we need to change some windows features to allow VBScript to run PowerShell and to open .ps1 files with PowerShell by default.
-go to run and type "regedit". Click on ok and then allow it to run.
-paste this path "HKEY_CLASSES_ROOT\Microsoft.PowerShellScript.1\Shell" and press enter.
-now open the entry on the right and change the value to 0.
-open PowerShell as an administrator and type "Set-ExecutionPolicy -ExecutionPolicy RemoteSigned", press enter and confirm the change with "y" and then enter.
Step 2: Now we can start wrapping our script.
-save your Powershell script as a .ps1 file.
-create a new text document and paste this script.
Dim objShell,objFSO,objFile
Set objShell=CreateObject("WScript.Shell")
Set objFSO=CreateObject("Scripting.FileSystemObject")
'enter the path for your PowerShell Script
strPath="c:\your script path\script.ps1"
'verify file exists
If objFSO.FileExists(strPath) Then
'return short path name
set objFile=objFSO.GetFile(strPath)
strCMD="powershell -nologo -command " & Chr(34) & "&{" &_
objFile.ShortPath & "}" & Chr(34)
'Uncomment next line for debugging
'WScript.Echo strCMD
'use 0 to hide window
objShell.Run strCMD,0
Else
'Display error message
WScript.Echo "Failed to find " & strPath
WScript.Quit
End If
-now change the file path to the location of your .ps1 script and save the text document.
-Now right-click on the file and go to rename. Then change the filename extension to .vbs and press enter and then click ok.
DONE! If you now open the .vbs you should see no console window while your script is running in the background.

c="powershell.exe -ExecutionPolicy Bypass (New-Object -ComObject Wscript.Shell).popup('Hello World.',0,'ОК',64)"
s=Left(CreateObject("Scriptlet.TypeLib").Guid,38)
GetObject("new:{C08AFD90-F2A1-11D1-8455-00A0C91F3880}").putProperty s,Me
WScript.CreateObject("WScript.Shell").Run c,0,false

Out of all the solutions I've tried, this is by far the best and easiest to set up. Download hiddenw.exe from here - https://github.com/SeidChr/RunHiddenConsole/releases
Let's say you want to run Powershell v5 consoleless. Simply rename hiddenw.exe to powershellw.exe. If you want to do this for cmd, then rename to cmdw.exe. If you want to do it for Powershell v7 (pwsh), then rename to pwshw.exe. You can create multiple copies of hiddenw.exe and just rename to the actual process with the letter w at the end. Then, simply add the process to your system environmental PATH, so you can call it from anywhere. Or just copy to C:\Windows. Then, just call it, like this:
powershellw .\example.ps1

I found compiling to exe was the easiest way to achieve this. Theres a number of ways to compile a script, but you can try ISE Steroids
Open "Windows PowerShell ISE", install and run ISESteroids:
Install-Module -Name "ISESteroids" -Scope CurrentUser -Repository PSGallery -Force
Start-Steroids
Then go to Tools->Turn code into EXE, select 'Hide Console Window', and then create the application.
You can run this directly from task scheduler without the need for wrappers or 3rd party apps.

What I do is transform the .ps1 file into an invisible .exe file using an awesome app called Ps1 To Exe which you can download here : https://www.majorgeeks.com/files/details/ps1_to_exe.html
Maybe this helps (although I hope after 12 years you have found a suitable solution... 🙂)

In other words, the script should run quietly in the background without any sign to the user.
Extra credit for an answer that does not use third party components :)
I found a way to do this by compiling a PowerShell script to a Windows executable. Third party modules are required to build the executable but not to run it. My end goal was to compile a one line PowerShell script that ejects a DVD on my system:
(New-Object -com "WMPlayer.OCX.7").cdromcollection.item(0).eject()
My target system is running Windows 7. The specific WMF update needed varies based on Windows version:
Download and install the WMF 5.1 package
The required PowerShell modules should be applicable to any Windows version. Here are the exact commands I used to install the necessary modules and compile the exe. You'll need to tweak the drive, directory and filename details for your system:
mkdir i:\tmp\wmf
cd i:\tmp\wmf
pkunzip ..\Win7AndW2K8R2-KB3191566-x64.zip
c:\windows\system32\windowspowershell\v1.0\powershell.exe
Set-ExecutionPolicy RemoteSigned
.\Install-WMF5.1.ps1
<click> "Restart Now"
c:\Windows\System32\WindowsPowerShell\v1.0\powershell -version 3.0
[Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12
Install-PackageProvider -Name NuGet -MinimumVersion 2.8.5.201 -Force
Install-Module -Name ps2exe -RequiredVersion 1.0.5
ps2exe i:\utils\scripts\ejectDVD.ps1 -noConsole

A single vbs file solution. You first have to convert your ps script to base64 string, place it in a variable in the template shown below and save it as I vbs file. Runs without powershell popppring up.
dim EncodedCommand
EncodedCommand = "COMMAND"
pSCmd = "powershell.exe -noexit -windowstyle Hidden -executionpolicy bypass -encodedcommand " & EncodedCommand
CreateObject("WScript.Shell").Run pSCmd, 0, True

Related

Double-Click Execute as Administrator

I have a powershell file saved to my desktop that I'd like to be able to double-click on and run as administrator. I've tried updating the shortcut used to launch powershell to always run as admin, but I still get the same permission issue. Is there a way to setup the shortcut so that the file always executes as admin? Or another way to set it up so that all powershell scripts run as admin when double-clicked?
Thanks for any help!
Create a "proxy script" to launch other scripts as admin with, and then launch PowerShell using Start-Process -Verb RunAs to elevate it before execution:
RunAsProxy.ps1
# First arg should be the script path
$script = $args[0]
# Rest of args should be any script parameters
$scriptArgs = $args[1..$args.Count] -join ' '
$startProcessArgs = #{
Wait = $true
Verb = 'RunAs'
FilePath = 'powershell'
ArgumentList = "-File `"$script`" $scriptArgs"
}
Start-Process #startProcessArgs
exit $LASTEXITCODE
Create your shortcut to point to RunAsProxy.ps1 instead of the target script. Pass in the path to the target script you want to run elevated and optionally any parameters to that script. If UAC is enabled, you should get prompted to elevate before execution.
This should be re-usable with other scripts you want to do the same with.

Powershell script strange behaviour when invoked from CMD/CLI

This scripts works fine when executed from Powershell console...
but does not work when executed with Powershell.exe from CMD.exe...
(powershell.exe -file script.ps1, using Powershell 5.1.17763.771)
# display Windows Shell Folder propertes
$App = New-Object -ComObject Shell.Application;
$AppNS = $App.NameSpace( "c:\windows" );
$AppNS.Self.InvokeVerb( "Properties" );
I tested other GUI objects (Winforms & WPF)
and they work fine...
?any ideas...
The problem is that the in-process COM object you're creating goes out of scope when the calling process exits, which in your case, when called from cmd.exe via PowerShell's CLI, means that the window typically never even gets a chance to display or is automatically closed after a very brief appearance.
In an interactive PowerShell session, the process lives on after exiting the script - that's why your code works there.
When you invoke a script via via PowerShell's CLI (powershell.exe for Windows PowerShell, pwsh for PowerShell Core, without the -NoExit switch to keep the process alive indefinitely), the PowerShell process exits when the script terminates.
Use of -NoExit would be a stopgap at best, because it would keep the PowerShell process around indefinitely, even though you presumably want it to live only for as long as the Properties dialog window is open - whenever the user chooses to close it.
Therefore, you need to synchronously wait for (a) the Properties dialog window to open and then (b) wait for it close before exiting the script.
You can do this with the help of the .NET UI Automation library as follows; note that the code uses PowerShell v5+ syntax:
using namespace System.Windows.Automation
# Load the UI Automation client assemblies.
# Requires Windows PowerShell or PowerShell Core v7+ (on Windows only).
Add-Type -AssemblyName UIAutomationClient; Add-Type -AssemblyName UIAutomationTypes
# Initiate display of the Windows folder's Properties dialog.
$App = New-Object -ComObject Shell.Application
$AppNS = $App.NameSpace('c:\windows')
$AppNS.Self.InvokeVerb('Properties')
# Comment out this line to suppress the verbose messages.
$VerbosePreference = 'Continue'
Write-Verbose 'Wating for the window''s creation...'
do {
# Search among the current process' top-level windows for a winow
# with class name '#32770', which is what the Properties dialog windows
# use (don't know why, but it has been stable over time).
$w = [AutomationElement]::RootElement.FindFirst([TreeScope]::Children,
[AndCondition]::new(
[PropertyCondition]::new([AutomationElement]::ClassNameProperty, '#32770'),
[PropertyCondition]::new([AutomationElement]::ProcessIdProperty, $PID)
)
)
Start-Sleep -Milliseconds 100
} while (-not $w)
Write-Verbose 'Window has appeared, waiting for it to close...'
while ($w.Current.ProcessId) {
Start-Sleep -Milliseconds 100
}
Write-Verbose 'Window is now closed, moving on.'
# At this point, if the script was invoked via PowerShell's CLI (powershell.exe -file ...)
# the PowerShell process terminates.
Now, invoking your PowerShell script as follows from your batch file will pop up the Properties dialog and wait for it to close before continuing:
#echo off
:: # ... your batch file
:: # Pop up the Properties dialog and *wait for it to close*.
powershell.exe -file script.ps1
:: # ...
If, by contrast, you simply want to launch the Properties dialog while continuing to run your batch file (be sure to disable the verbose messages first):
:: # Only *initiate* display of the Properties dialog and *continue execution*.
start /B powershell.exe -file script.ps1
Seems like it has to wait for the graphics to finish. "get-childitem | out-gridview" does a similar thing. Or add "sleep 120" to the end of the script, or find some other way to wait. Killing the script kills the window.
powershell -noexit .\explorer.ps1

How to use a string variable as a telnet command in a vbscript?

I'm trying to run a Powershell script that will call a batch script that will start a telnet session and run the following command:
mediaGet("gei",1)
Thanks to this stackoverflow question Is it possible to use a batch file to establish a telnet session, send a command and have the output written to a file? I have written two scripts:
telnet.bat
start telnet.exe 162.100.10.10
cscript telnet.vbs
telnet.vbs
set OBJECT=WScript.CreateObject("WScript.Shell")
Dim cmd
cmd = "mediaGet("gei",1)
WScript.sleep 50
OBJECT.SendKeys cmd
WScript.sleep 50
OBJECT.SendKeys "{ENTER}"
WScript.sleep 50
OBJECT.SendKeys "exit{ENTER}"
WScript.sleep 5000
OBJECT.SendKeys " "
However, when I run the scripts, the vbs script cannot read the string of the variable cmd. So I changed it as such:
cmd = "mediaGet" & chr(40) & chr(34) & "gei" & ",1" & chr(41)
But still, it outputs it on the telnet terminal as such:
mediaGet"gei",1
How can I make it read the parenthesis in the string variable?
If the scripts end up working, does anyone know how to save the output of the vbs script into a log file?
I have no idea what mediaget is or what it does (actually I've never heard of it), so, I will not comment on that.
However, running external commands via PowerShell is very common and well documented. See these:
PowerShell: Running Executables
Execution of external commands in PowerShell done right
All that being said...
If you are using the powershell.exe consolehost that is one thing, but all you are doing is calling VBScript and cmd.exe items. Since that is the case then why not just use cmd.exe?
Yet, PowerShell can do this directly, so, why the extra steps to .bat and .vbs?
Example: rough and untested, because I have no need to download and test mediaget
Start-Process -FilePath 'telnet.exe' -ArgumentList '162.100.10.10'
[system.reflection.assembly]::loadwithpartialname("System.Windows.Forms")
$SendKeys = [System.Windows.Forms.SendKeys]
$sendkeys::SendWait('mediaGet gei,1')
Start-Sleep -Seconds .5
$sendkeys::SendWait("{ENTER}")
Start-Sleep -Seconds .5
$sendkeys::SendWait("exit{ENTER}")
You can even replace Telnet with your own code, using the .Net namespace.
New-Object System.Net.Sockets.TcpClient
Calling it this way ...
New-Object System.Net.Sockets.TcpClient('162.100.10.10', 80)
You can use that to write your own module or use this one from the MS powershellgallery.com.
A quick YouTube search shows me that mediaget is a web download tool.
If all you are doing is hitting a website / ftp site to download a file, you can do that directly in PowerShell as well. See this:
3 ways to download files with PowerShell

Multithreaded Powershell GUI Application never displays when called from CMD.exe

I have finally finished my powershell wpf application for internal use at my company, and it runs as expected when called from a powershell window, however when I try to call it from CMD, or from Visual Studio as an external tool, the GUI window never shows up.
My application functions very closely to this write up, with a few changes to the display and functions that run in the background.
Can anyone explain why my ps1 file does not display the gui when I call it from CMD, but it does when called from the powershell command window? Here is the gist of the script:
$Global:syncHash = [hashtable]::Synchronized(#{})
$newRunspace =[runspacefactory]::CreateRunspace()
$newRunspace.ApartmentState = "STA"
$newRunspace.ThreadOptions = "ReuseThread"
$newRunspace.Open()
$newRunspace.SessionStateProxy.SetVariable("syncHash",$syncHash)
[void][System.Reflection.Assembly]::LoadWithPartialName('presentationframework')
$psCmd = [PowerShell]::Create().AddScript({
[xml]$xaml = #"
<valid wpf>
"#
$reader=(New-Object System.Xml.XmlNodeReader $xaml)
$syncHash.Window=[Windows.Markup.XamlReader]::Load( $reader )
[xml]$XAML = $xaml
$xaml.SelectNodes("//*[#*[contains(translate(name(.),'n','N'),'Name')]]") | %{
#Find all of the form types and add them as members to the synchash
$syncHash.Add($_.Name,$syncHash.Window.FindName($_.Name) )
}
## Custom functions for items in syncHash here ##
$syncHash.Window.ShowDialog() | Out-Null
$syncHash.Error = $Error
})
$psCmd.Runspace = $newRunspace
$date = $psCmd.BeginInvoke()
I am calling this script in cmd.exe "C:\Windows\System32\WindowsPowerShell\v1.0\powershell.exe C:\pathToFile\file.ps1"
My Execution policy has been updated so that I can run scripts as well.
Thanks for all the help, I got it figured out. For some reason I needed to run the command with the NoExit option
powershell.exe -ExecutionPolicy Bypass -NoExit -File "pathToFile\File.ps1"

How to condense PowerShell script to fit on a single line

Quick question. I am trying to write the following PowerShell script, but I would like it to fit on a single line:
$app = New-Object -comobject Excel.Application
$wb1 = $app.Workbooks.Open("C:\xampp\upload_files\Launchpad.xlsm")
$app.Run("Refresh")
$wb1.Close($false)
$app.Quit()
The pseudo-code would look something like this:
$app = New-Object -comobject Excel.Application AND $wb1 = $app.Workbooks.Open AND "C:\xampp\upload_files\Launchpad.xlsm") AND $app.Run("Refresh") AND $wb1.Close($false) AND $app.Quit()
The reason I want to fit on a line is because I would like to insert the arguments directly in the 'arguments' box of Windows Task Scheduler. The reason for this is that for some reason scripts have been disabled (e.g. I cannot call a .ps1 file...)
I know this will still work, as I already have a "one liner" PS script running. What would the syntax look like??
Kind regards,
G.
Powershell statements can be separated with semicolons:
$app = New-Object -COM 'Excel.Application'; $wb1 = $app.Workbooks.Open("..."); ...
The PowerShell executable takes a -Command parameter that allows you to specify a command string for execution in PowerShell:
powershell.exe -Command "stmnt1; stmnt2; ..."
To run this via Task Scheduler you'd put powershell.exe into the "program" field and -Command "stmnt1; stmnt2; ..." into the "arguments" field of the task.
However, as #alroc said: you should verify why script execution has been restricted. If it's just the default setting you can simply change it by running Set-ExecutionPolicy RemoteSigned or override it by adding -ExecutionPolicy ByPass to a PowerShell command line. However, if the setting is enforced by policy changing/bypassing the setting will fail, and you could get into quite some trouble for violating company policies.
Here is a solution that you might use if the script is not that easy to convert, but you are on Windows running at least PowerShell V5.
It converts the code into Base64 and uses PowerShell.exe with the parameter -encodedCommand to pass the encodedCommand as string.
$command = Get-Content .\YourPowerShellFileContainingTheCode.ps1 -raw
# Get-Content may require "-encoding utf8" or other encodings depending on your file
$encodedCommand = [Convert]::ToBase64String([Text.Encoding]::Unicode.GetBytes($command))
Write-Output "Text for application:"
Write-Output "PowerShell.exe" ""
Write-Output "Text for argurments:"
Write-Output "-encodedCommand $encodedCommand"
It would look like this, but with a much larger command:
Text for application:
PowerShell.exe
Text for argurments:
-encodedCommand SABvACAASABvACAASABvACwAIABzAHQAYQBjAGsAbwB2AGUAcgBmAGwAbwB3AA==

Resources