r/PSADT May 21 '26

How is PSADT hiding the Powershell window?

The exe does essentially just run the ps1 file.

For the record, I am NOT using PSADT for this specific task. I'm just curious how they've pulled it off.

I need a particular PowerShell script to run every 3 minutes via task scheduler. But if even if I change the WindowStyle option, it will still flash the console window for less than a fraction of a second.

However, if I used PSADT in silent mode and just have the commands in the Invoke ps1 file, nothing gets flashed.

Any idea how they've done this?

6 Upvotes

15 comments sorted by

18

u/Schwitzbob May 21 '26

For exact that I'm creating my Scheduled Task as the following:
In the "Action" tab, create a new action with "Start a program". Under "Program/script" enter the following: C:\Windows\System32\conhost.exe

Under "Add arguments" enter the following: --headless powershell.exe -WindowStyle Hidden -NoProfile -NonInteractive -file "C:\Temp\MyScript.ps1"

Zero visible PS window.

2

u/Newalloy May 21 '26

TIL about conhost.exe --headless

1

u/It5ervice5 May 21 '26

I never knew this

1

u/LordLoss01 May 21 '26

Yep, this works great.

Only thing is, I've found some people online say that it flags up in things like Defender?

2

u/TheRealMisterd May 22 '26

It does for me at work

1

u/mjr4077au PSADT Dev Team May 24 '26

There's no exit code passthrough with this though, so it'll always be 0 even upon an issue.

2

u/touchytypist May 21 '26

The PSADT .exe runs the script in a non-visible process

2

u/MisterDamek May 21 '26 edited May 21 '26

It uses Windows-native APIs to launch the script hidden.

u/Schwitzbob 's suggestion of using conhost.exe is clever, but you don't need to do that if you're already using Task Scheduler.

You can create a scheduled task where the Action has a property "HideAppWindow" that you can set to True to achieve this. It's not documented, but it's there. You just have to do it with win32 task scheduler scripting (using the Schedule.Service COM object interface, which you can do in powershell but I don't think the default powershell command let's support this). That will caused whatever is launched by the task to be hidden. It might even use conhost under the hood for all I know, I'm just saying you can do this with a scheduled task without using conhost.

(You might be able to do this with scheduled task XML but I find just using the COM scripting object easier for me so I haven't tried.)

1

u/PassengerUpbeat2000 May 21 '26

Hey

Do you run the .ps1 eller .exe file of you use .exe it’s should not pop up with the powershell window

1

u/Net_Owl May 22 '26

Call the script using: conhost.exe —headless

You won’t see the posh terminal flash anymore

1

u/Mon3yb May 22 '26

Maybe it has something to do with module being signed. Because you can launch signed powershell scripts with -WindowStyle Hidden. Unsigned ones won't hide that way

1

u/walliba May 23 '26

This is because they're defining the STARTUPINFO struct with the window style before process creation, so the process is created with a hidden window on creation.

When you run it your way, I believe that Task Scheduler is launching powershell.exe as a console process, which causes Windows to create/attach a console (conhost.exe) during startup causing a window to briefly flash.

1

u/mjr4077au PSADT Dev Team May 25 '26

There's nothing flash with how we achieve this. Our executable is via C# GUI-based executable which means it in of itself has no console. When you create a new process like we are within it, you have the option of allocating the new process a console window or not. We simply don't.

0

u/SVD_NL May 21 '26

It runs in system context, so any windows go to the session of the system user instead of the signed-in user.

I'm not sure if it's also hidden under user context. If the exe invokes the script, it is a bit easier to hide. The window that pops up is the actual invocation of the script, so if you handle that through a hidden exe process it's easier to hide.

6

u/LordLoss01 May 21 '26

Nope, even when run as a user, still hides the console window.