如何在不显示窗口的情况下运行PowerShell脚本?


127

如何在不向用户显示窗口或任何其他标志的情况下运行PowerShell脚本?

换句话说,脚本应在后台安静地运行,而不会给用户任何标志。

不使用第三方组件的答案的额外功劳:)


如果您对学习感兴趣,请查看此问题: stackoverflow.com/questions/573623/powershell-vs-unix-shells
Thomas Bratt

此解决方案也适用于任务计划程序:stackoverflow.com/a/51007810/571591
Hilydrow

Answers:


128

您可以像这样运行它(但是这会显示一个窗口):

PowerShell.exe -windowstyle hidden { your script.. }

或者您使用我创建的帮助程序文件来避免名为PsRun.exe的窗口执行此操作。您可以下载源文件和exe文件,并在PowerShell中使用WinForm GUI运行计划的任务。我将其用于计划任务。

编辑:正如Marco所指出的,此-windowstyle参数仅适用于V2。


6
我编译了PsRun,但是,如果将其添加到计划的任务中,它也会闪烁一个窗口...
Ciantic 2015年

2
同样在这里,由于窗口仍会弹出以运行脚本,因此也不起作用。它会快速退出,但我们正在尝试在后台运行此程序而不会受到干扰。
内森·麦卡斯凯尔

1
是的,这就是为什么响应中有“但是会显示一个窗口”的原因。
stej

21
@ThomasBratt对于计划的任务,我发现PowerShell脚本会以静默方式运行,而无需-WindowStyle Hidden将该任务设置为Run whether user is logged on or not“安全选项”部分下的“常规”选项卡。
亚当,

1
使用“系统的用户帐户”还可以避免显示窗口。
乔恩·埃德里奇

27

我遇到了同样的问题。我发现,如果你去的任务任务计划程序运行的powershell.exe脚本,你可以点击“ 运行用户是否登录或不 ”,而且绝不会显示PowerShell窗口在任务运行时。


3
不依赖于第三方扩展,可执行文件或包装脚本的最佳解决方案。
反转

1
请注意,此选项要求用户具有“作为批处理作业登录”特权
gb96 '19

此解决方案使我的脚本无法正常运行
马丁·阿尔杰拉米

18

您可以使用PowerShell社区扩展,并执行以下操作:

start-process PowerShell.exe -arg $pwd\foo.ps1 -WindowStyle Hidden

您也可以使用VBScript执行此操作:http : //blog.sapien.com/index.php/2006/12/26/more-fun-with-scheduled-powershell/

(通过此论坛主题。)


是否有NuGet插件可以让我从Visual Studio中运行它?
Piotr Kula

13

这是一种不需要命令行参数或单独启动器的方法。它不是完全不可见的,因为启动时窗口确实会瞬间显示。但是它很快就消失了。我认为,这是最简单的方法,如果您想通过双击资源管理器或通过“开始”菜单快捷方式(当然包括“启动”子菜单)来启动脚本。我喜欢它是脚本本身代码的一部分,而不是外部代码。

将其放在脚本的前面:

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

10

这里是单线:

mshta vbscript:Execute("CreateObject(""Wscript.Shell"").Run ""powershell -NoLogo -Command """"& 'C:\Example Path That Has Spaces\My Script.ps1'"""""", 0 : window.close")

尽管这可能会使窗口短暂闪烁,但这很少见。


在大多数情况下,如果您使用-windowstyle hidden,则在登录用户上下文中运行Powershell.exe会显示完整窗口或短暂闪烁。要完全删除窗口,您可以执行以下两项操作之一:1:在其他用户的上下文(例如admin帐户)中运行(不会对登录的用户显示任何窗口)。或2:将vbscript与objshell.run一起使用,并带有隐藏的窗口标志,以启动cmd.exe / c powershel.exe-文件c:\ script.ps1。从cmd调用powershell时,它将在现有的cmd窗口中运行,该窗口已被wscript.exe // b / nologo c:\ launcher.vbs隐藏。
Iconiu

哇,突然。起初我什至没有注意到您的回答。我用非常相似的脚本回答。很高兴见到一个知识渊博的人给出了真实的答案。
Gosha

这应该是公认的答案,它似乎是在每种情况下都适用的一种方法(包括在任务计划程序内部,这是我的问题)。
Martin Argerami

6

在Windows 7上从c#运行时遇到此问题,当以系统帐户运行隐藏的Powershell窗口时,“交互服务检测”服务弹出。

使用“ CreateNoWindow”参数可防止ISD服务弹出警告。

process.StartInfo = new ProcessStartInfo("powershell.exe",
    String.Format(@" -NoProfile -ExecutionPolicy unrestricted -encodedCommand ""{0}""",encodedCommand))
{
   WorkingDirectory = executablePath,
   UseShellExecute = false,
   CreateNoWindow = true
};

5

我认为,运行后台脚本时隐藏PowerShell控制台屏幕的最佳方法是此代码(“ Bluecakes ”答案)。

我将此代码添加到需要在后台运行的所有PowerShell脚本的开头。

# .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

如果此答案对您有帮助,请在此帖子的答案中投票给“ Bluecakes”。


对我来说,控制台仍然显示约一秒钟。
thdoan

3

ps1也隐藏在任务计划程序和快捷方式中

    mshta vbscript:Execute("CreateObject(""WScript.Shell"").Run ""powershell -ExecutionPolicy Bypass & 'C:\PATH\NAME.ps1'"", 0:close")

2

我创建了一个小工具,将调用传递到您要从无窗口启动的任何控制台工具,并传递到原始文件:

https://github.com/Vittel/RunHiddenConsole

编译后,只需将可执行文件重命名为“ <targetExecutableName> w.exe”(附加“ w”),然后将其放在原始可执行文件旁边。然后,您可以使用常规参数调用eG powershellw.exe,它不会弹出一个窗口。

如果有人对如何检查所创建的进程是否正在等待输入有所了解,不高兴包括您的解决方案:)


1
如果要在启动时MessageBox不使用任何窗口闪烁的情况下运行Powershell脚本,则这是最佳答案(要求将EXE编译为Winexe,而不是控制台应用程序,并且要求将Task Scheduler设置为“仅在登录用户时运行”) on”,因此对话框将在当前桌面会话中显示。)感谢您执行此操作,powershellw.exe多年来一直是我的愿望清单!
卡尔·沃尔什

PS:我已经包括了“等待输入”的解决方案(还有一些错误修正)!
克里斯,

@CarlWalsh我假设您的意思是它不是控制台应用程序,而是win表单应用程序,这是正确的。只是它不包括任何窗口。但是项目类型应在csproj文件中定义,并且在Visual Studio中打开它后,无需设置特定的输出类型
克里斯

2

这是Windows 10中不包含任何第三方组件的有效解决方案。通过将PowerShell脚本包装到VBScript中可以工作。

步骤1:我们需要更改某些Windows功能,以允许VBScript运行PowerShell并默认情况下使用PowerShell打开.ps1文件。

-运行并输入“ regedit”。单击确定,然后使其运行。

-粘贴此路径“ HKEY_CLASSES_ROOT \ Microsoft.PowerShellScript.1 \ Shell”,然后按Enter。

-现在打开右侧的条目并将其值更改为0。

-以管理员身份打开PowerShell,并键入“ Set-ExecutionPolicy -ExecutionPolicy RemoteSigned”,按Enter,并用“ y”确认更改,然后输入。

步骤2:现在我们可以开始包装脚本了。

-将Powershell脚本另存为.ps1文件。

-创建一个新的文本文档并粘贴此脚本。

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,将文件路径更改为.ps1脚本的位置,然后保存文本文档。

-现在,右键单击文件,然后重命名。然后将文件扩展名更改为.vbs,然后按Enter,然后单击“确定”。

完成!如果现在打开.vbs,则在后台运行脚本时应该看不到任何控制台窗口。

如果适合您,请确保投票!


1

这是一个有趣的演示,它控制控制台的各种状态,包括最小化和隐藏状态。

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"
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.