How to run a PowerShell script without displaying a window?

518,150

Solution 1

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.

Solution 2

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.

Solution 3

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/

(Via this forum thread.)

Solution 4

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)

Solution 5

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.

Share:
518,150

Related videos on Youtube

Solaiman Mansyur
Author by

Solaiman Mansyur

Working on configuration, control and reporting backend for a fintech / machine learning startup based in Cambridge. Using Java 8, Apache Kafka, Apache Zookeeper, Elasticsearch, MongoDB, Oracle 12c. Previously: using C#, NServiceBus, ASP.NET MVC, MS SQL Server and Oracle 11g databases developing management and control software in C#, C++, C for high bandwidth video over ATM and IP networks embedded work with C / Motorola 68000

Updated on April 24, 2022

Comments

  • Solaiman Mansyur
    Solaiman Mansyur about 2 years

    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 :)

    • Solaiman Mansyur
      Solaiman Mansyur over 14 years
      Checkout this question if you are interested in learning: stackoverflow.com/questions/573623/powershell-vs-unix-shells
    • Hilydrow
      Hilydrow almost 4 years
      This solution works for Task Scheduler as well: stackoverflow.com/a/51007810/571591
    • ryanwebjackson
      ryanwebjackson almost 3 years
      There are other options, such as a Windows service, if you need to absolutely avoid showing a window.
    • desseim
      desseim about 2 years
      For anyone interested, the window flashing even with -WindowStyle hidden is a known Windows limitation with CUI applications (it only works as expected with GUI ones -- hence the pythonw.exe / javaw.exe-type solutions implemented by other projects). It is being (rather) actively discussed on GitHub, with several suggestions for potential workarounds / fixes at the PowerShell or OS level. So, it might get patched, "one day".
  • Ciantic
    Ciantic over 8 years
    I compiled the PsRun, however, if I add it to the scheduled task, it also flashes a window...
  • Nathan McKaskle
    Nathan McKaskle over 7 years
    Same here, also does not work because the window still pops up to run the script. It exits quickly but we're trying to run this in the background without interruption.
  • stej
    stej over 7 years
    Yes, that's why there is "but this shows a windows for a while" in the response.
  • adam
    adam over 7 years
    @ThomasBratt For scheduled tasks, I've found PowerShell scripts run silently without -WindowStyle Hidden if the task is set to Run whether user is logged on or not on the General tab under "Security Options" section.
  • Piotr Kula
    Piotr Kula over 5 years
    Is there a NuGet paclage for this so I can run it from Visual Studio?
  • Richard Stagg
    Richard Stagg over 5 years
    Best solution without depending on a third-party extension, executable, or wrapper script.
  • Venryx
    Venryx over 5 years
    This is a nice option, but be aware that if you have a "wait for input" line at the end of your script, the window being hidden will make you unable to complete that wait line, causing the process to stay around forever. So if you know you're going to sometimes be adding the "wait for input" line after the tasks are done (for inspection/debugging), the other approaches (@AndyLowry @gavraham) are better as you can easily "re-show" the console window at that point. (just call ShowWindow(..., 1))
  • Jon Eldridge
    Jon Eldridge over 5 years
    Using User Account to SYSTEM also avoids a window being displayed.
  • Carl Walsh
    Carl Walsh over 5 years
    This is the best answer if you want to run powershell scripts using MessageBox without any flash of the window on startup (requiring an EXE compiled as a Winexe, not a console app, and requiring Task Scheduler to be set to "Run only when user is logged on" so dialogs show in the current desktop session.) Thanks for implementing this, powershellw.exe has been on my wishlist for years!
  • Iconiu
    Iconiu about 5 years
    In most cases, running Powershell.exe in the logged on users context will either show a full window or flash briefly if you use -windowstyle hidden. To totally remove window you can do one of two things: 1: Run in a different user's context such as admin account (won't display any windows to the logged on user). Or 2: Use a vbscript with objshell.run with a hidden window flag to launch cmd.exe /c powershel.exe -file c:\script.ps1. When powershell is called from cmd it will run in the existing cmd window which is already hidden by wscript.exe //b /nologo c:\launcher.vbs.
  • Chris
    Chris almost 5 years
    PS: i have included the solution for "waiting for input" a while ago (as well as a couple of bugfixes)!
  • Chris
    Chris almost 5 years
    @CarlWalsh i assume you mean that its not an console app, but a win forms app instead, which is correct. just it doesnt include any windows. but the project type should be defined in the csproj file and you should not need to set a specific output type after opening it with visual studio
  • gb96
    gb96 over 4 years
    Note that this option requires the user to have the "Log on as Batch Job" privilege
  • Garric
    Garric over 4 years
    wow, Suddenly. I did not even notice your answer at first. I answered with a very similar script. It's nice to see a knowledgeable person who gives a real answer.
  • js2010
    js2010 about 4 years
    -windowstyle hidden doesn't completely work. The window will at least flash.
  • thdoan
    thdoan about 4 years
    For me the console still displays for about a second.
  • Martin Argerami
    Martin Argerami almost 4 years
    This solution makes my script not to run properly.
  • Martin Argerami
    Martin Argerami almost 4 years
    This should be the accepted answer, it is the one method that seems to work in every situation (including inside the task scheduler, which was my problem).
  • McVitas
    McVitas almost 4 years
    PowerShell.exe -windowstyle hidden -command yourscript.ps1 I use this as scheduled task to backup some folder on my machine so it does not jump into my face when it works
  • johnwait
    johnwait over 3 years
    For those interested: The powershell.exe executable has so far always been linked to use the character-mode (i.e. console) subsystem, so even if PowerShell was to hide its console window at the earliest possible time, a console window would always show from the start of the PowerShell process until it hides it. I only see two ways around that: either convince Microsoft to release, along with powershell.exe & powershell_ise.exe, an official, GUI-linked, and console-optional build (unlikely); or you/someone to fork the PowerShell open-source project and create a patch to make such build possible
  • letmaik
    letmaik over 3 years
    Caveat: The exit code from the PowerShell script gets lost here and is always 0.
  • letmaik
    letmaik over 3 years
    Not a solution if your script involves displaying any kind of gui.
  • mklement0
    mklement0 over 3 years
    @johnwait: See GitHub issue #3028.
  • Garric
    Garric over 3 years
    This solution will prevent you from displaying notifications to the current user. Hiding the code does not mean that it will be useful at all for the person who is working now.
  • Safwan
    Safwan about 3 years
    Interesting method, but how can you capture the output from PS (StdOut) into a variable to use in the vbs script without using a temporary file?
  • Garric
    Garric about 3 years
    As I recall, This is my an extremely simplified method presented here in my other comment, which returns StdOut result. You should not demand from this simple code that for which it is not intended.
  • Safwan
    Safwan about 3 years
    I went through the longer code in your other comment, it does capture StdOut but it also relaunches the script in a hidden console, effectively hiding a lot of other things, I was simply looking for a way to just hide the PS window that is started by the script, but thanks anyway for your replay, cheers.
  • Chris
    Chris about 3 years
    This worked wonderfully for me when scheduling a powershell in a scheduled task created by a GPO. For kicks, I combined with the "-windowstyle hidden" option. No pop up window at all.
  • shadowz1337
    shadowz1337 about 3 years
    Why can't you just use the .bat file in scheduled task? Why do you need to use .vbs to call .bat? I just tested using the .BAT file in scheduled task and it works fine without any popups
  • FHC
    FHC about 3 years
    It works as "Target:" in a link as well. I wish this answer was higher up on the page, would have saved me a lot of time. Thank you!
  • Ste
    Ste about 3 years
    You can at least get around the window flashing with calling cmd with cmd /c start /min "" powershell -WindowStyle Hidden -ExecutionPolicy Bypass -File "C:\Users\username\Desktop\test.ps1".
  • user2924019
    user2924019 almost 3 years
    Link is now dead.
  • Capgros
    Capgros almost 3 years
    Worked Flawlessly. Just what i was looking for
  • Leathan
    Leathan over 2 years
    I forgot the reason why I was not using scheduled task, but there are lots of reasons I could think of off the top of my head, none of which are guaranteed to be right as I forgot. I only remember posting my solution because I originally tried the others and they did not work. I do remember scheduled tasks was not what I wanted though maybe because it was too dynamic idk. In fact the answer might be I used the vbs because I could not use scheduled task, anyway its all irrelevant, just submit yours as another answer if its not on here.
  • Leathan
    Leathan over 2 years
    @shadowz1337 Figured it out since I needed to do it again. There are various oddities when starting a task hidden from the scheduler that prevent the bat file from actually being hidden. The vbs here specifically fixes this issue, with this you can run a hidden bat as your admin user, else ud have to do system, or run as any user. see superuser.com/questions/478052/… for detailed explanations.
  • Leathan
    Leathan over 2 years
    Works +1. Also user run as user "system" works if you need the elevation. Or my answer if you need your user.
  • Kobato
    Kobato over 2 years
    This is interesting, but I actually discovered that you CAN see the window. It just flashes MUCH MUCH quicker than the other times, but if you're paying very close attention, the window still popped up. If you want to see what I'm talking about, then open a windowed window (like explorer) and you'll see it loses focus for a brief moment as the other window gains focus
  • Kobato
    Kobato over 2 years
    This was actually very helpful, because so many of the other solutions are a bit cumbersome and/or not ideal. This one is FAST. I modified it to run-as admin mode as well since that's what I came here for (no flashing windows + run as admin). github.com/cherryleafroad/run-hidden
  • Ste
    Ste over 2 years
    It's not a perfect workaround but it worked in all of my use cases and I've never seen it flash. It losing focus of File Explorer would happen regardless would it not seeing as calling a PS script would do that anyway?
  • Kobato
    Kobato over 2 years
    It can only lose focus on a window if something popped up in front of it (no matter how brief). Of course the focus is restored once it disappears, but the point remains. I did have to look VERY VERY closely to see the flash (it may have only appeared for a few frames) as I couldn't see it if I wasn't looking for it, so it is less of a flash than other (flashy) methods. I ended up using the code from the run-hidden which was actually hidden (no lose focus or anything as well), although I haven't tested the other answers. Your answer was definitely less invasive than other flashes at least
  • Jesse Chisholm
    Jesse Chisholm over 2 years
    Also, if your script starts any other background programs, they will not have windows either.
  • shadowz1337
    shadowz1337 over 2 years
    I just use achedule task to call nircmd exec hide to run the .bat file, which then invokes my Powershell script as admin and this is completely hidden to the user from start to end.
  • aj go
    aj go over 2 years
    this is what i looking for. thank mate
  • Leathan
    Leathan over 2 years
    Im sure there are other ways, but for me, if I replace the first step it doesnt run hidden, maybe because im not signed on the user im having the script run as? I dont know.
  • shadowz1337
    shadowz1337 over 2 years
    not sure what you mean by "doesn't run hidden if you replace the first step". Anyway, the way I do it is using Task Scheduler to call a .bat file with nircmd. Like this "nircmd exec hide D:\Test.bat". Nircmd is a tool from Nirsoft, just download it and put it into your C:\Windows folder, so that you can call it from anywhere. Then, in the .bat file, just call your Powershell script like this - powershell.exe -ExecutionPolicy ByPass -File "D:\Test.ps1". So basically, Task Scheduler uses Nircmd to call the .bat file, which then calls the Powershell script. Completely hidden, no popups.
  • shadowz1337
    shadowz1337 over 2 years
    And the reason why it is completely hidden is because Nircmd supports running commands without a console, by using the "exec hide" switch. The nice thing about this is I can still make my .bat or .ps1 scripts to show popups whenever I need it to. For example, if I have a script that shows a GUI to prompt the user to enter something, then that will still popup. The script itself is run in the background without disruption to the user, but I can still see the actual user input popup when required.
  • shadowz1337
    shadowz1337 over 2 years
    If you need to run Powershell elevated, just use this in your .bat file - CMD /C PowerShell "SL -PSPath '%CD%'; $Path = (GL).Path; SL ~; Start PowerShell -Verb RunAs -Args \"-ExecutionPolicy ByPass" SL -PSPath '"$Path"'; & '".\Test.ps1"'"\""
  • shadowz1337
    shadowz1337 over 2 years
    Finally, I also use Autohotkey scripts, which I can run based on hotkey triggers. E.g. I can configure my Autohotkey script to do something when I press CTRL+SHIFT+O. I can invoke this hotkey trigger via a Powershell script. So again, nircmd calls .bat script, which calls Powershell script, which then invokes hotkey to trigger my Autohotkey script. I'll still get actual user prompt popups for Autohotkey.
  • shadowz1337
    shadowz1337 over 2 years
    In your Powershell script, you can use something like this to trigger the hotkeys: [void][System.Reflection.Assembly]::LoadWithPartialName('Sys‌​tem.Windows.Forms') Add-Type -AssemblyName PresentationFramework Add-Type -AssemblyName Microsoft.VisualBasic [System.Windows.Forms.SendKeys]::SendWait("^{F16}");
  • Peter
    Peter over 2 years
    For the "Call a file with arguments" the semicolon seems to be extra as it prevents the script from executing.
  • Ste
    Ste over 2 years
    @Peter, thanks for pointing that out. I've fixed that and added the ps1 content also for clarity.
  • Peter
    Peter over 2 years
    @Ste maybe you have still left some stuff in there by mistake, or I am just not understanding what this part is supposed to do ps1'; -Arg1 'Hello' -Arg2 ' World'"
  • Ste
    Ste over 2 years
    That has been removed in my edit for Call a file with arguments. In the Call a file with a function and arguments example the ; is required after calling the file to call the function with those params.
  • jamie
    jamie over 2 years
    This seems not to work when you use "%USERPROFILE%" in one of your arguments.
  • stax76
    stax76 over 2 years
    @jamie I think this is normal behavior! The Process class does not expand env vars and user applications like run-hidden typically don't do this either, I believe.
  • jamie
    jamie over 2 years
    Uh I see. Thanks for explaining that.
  • Shivam Anand
    Shivam Anand about 2 years
    Thanks, this was helpful
  • Esperento57
    Esperento57 about 2 years
    Good job soldier !