173

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

换句话说,脚本应该在后台安静地运行,而不需要向用户发出任何信号。

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

4

20 回答 20

167

您可以像这样运行它(但这会显示一段时间的窗口):

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

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

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

于 2009-11-26T10:22:09.897 回答
56

我遇到了同样的问题。我发现如果您转到正在运行powershell.exe脚本的任务计划程序中的任务,您可以单击“无论用户是否登录都运行”,并且在任务运行时永远不会显示 powershell 窗口。

于 2018-05-31T18:35:53.247 回答
19

您可以使用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/

(通过此论坛主题。)

于 2009-11-26T07:58:23.603 回答
17

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

将其放在脚本的前面:

$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)
于 2015-01-16T20:40:11.680 回答
14

这是一个单行:

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

尽管这可能会非常短暂地闪烁窗口,但这应该很少发生。

于 2017-08-03T02:46:20.710 回答
13

答案-WindowStyle Hidden很好,但窗口仍然会闪烁。

通过调用它时,我从未见过窗口闪烁cmd /c start /min ""

您的机器或设置可能会有所不同,但对我来说效果很好。

1.调用文件

cmd /c start /min "" powershell -WindowStyle Hidden -ExecutionPolicy Bypass -File "C:\Users\username\Desktop\test.ps1"

2. 调用带参数的文件

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'"

2的Powershell内容。调用带有参数的文件是:

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. 使用函数和参数调用文件

cmd /c start /min "" powershell -WindowStyle Hidden -ExecutionPolicy Bypass -Command ". 'C:\Users\username\Desktop\test me.ps1'; Get-Test -stringTest 'Hello World'"

3.使用函数和参数调用文件的Powershell内容是:

function Get-Test() {
  [cmdletbinding()]
  Param
  (
    [Parameter(Mandatory = $true, HelpMessage = 'The test string.')]
    [String]$stringTest
    )
  Write-Host $stringTest
  return
}

如果您需要在任务计划程序中运行它,则%comspec%作为程序/脚本调用,然后调用上述文件作为参数的代码。

注意:当 PS1 文件的路径中有空格时,所有示例都有效。

在此处输入图像描述

于 2021-04-28T12:21:13.353 回答
11

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

    mshta vbscript:Execute("CreateObject(""WScript.Shell"").Run ""powershell -ExecutionPolicy Bypass & 'C:\PATH\NAME.ps1'"", 0:close")
于 2019-12-15T16:09:19.230 回答
7

我认为当您运行后台脚本时隐藏 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”。

于 2017-09-25T21:08:29.810 回答
6

从 c# 运行时我遇到了这个问题,在 Windows 7 上,当以 SYSTEM 帐户运行隐藏的 powershell 窗口时,弹出“交互式服务检测”服务。

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

process.StartInfo = new ProcessStartInfo("powershell.exe",
    String.Format(@" -NoProfile -ExecutionPolicy unrestricted -encodedCommand ""{0}""",encodedCommand))
{
   WorkingDirectory = executablePath,
   UseShellExecute = false,
   CreateNoWindow = true
};
于 2014-01-29T06:47:36.507 回答
4

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

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"
于 2019-09-01T16:42:16.840 回答
4

创建一个调用 PowerShell 脚本的快捷方式并将运行选项设置为最小化。这将防止窗口闪烁,尽管您仍然会在任务栏上看到正在运行的脚本的瞬间。

于 2021-06-24T01:25:11.833 回答
4

为了方便命令行使用,有一个简单的包装应用程序:

https://github.com/stax76/run-hidden

示例命令行:

run-hidden powershell -command calc.exe
于 2021-07-22T09:29:19.083 回答
3

我真的厌倦了通过答案才发现它没有按预期工作。

解决方案

制作一个 vbs 脚本来运行一个隐藏的批处理文件,该文件会启动 powershell 脚本。为这个任务制作 3 个文件似乎很愚蠢,但至少总大小小于 2KB,它可以从 tasker 或手动运行完美(你什么都看不到)。

脚本名.vbs

Set WinScriptHost = CreateObject("WScript.Shell")
WinScriptHost.Run Chr(34) & "C:\Users\leathan\Documents\scriptName.bat" & Chr(34), 0
Set WinScriptHost = Nothing

脚本名称.bat

powershell.exe -ExecutionPolicy Bypass C:\Users\leathan\Documents\scriptName.ps1

脚本名称.ps1

Your magical code here.
于 2020-12-06T22:58:59.627 回答
2

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

https://github.com/Vittel/RunHiddenConsole

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

如果有人知道如何检查创建的进程是否正在等待输入,我很乐意提供您的解决方案:)

于 2018-11-17T19:56:23.597 回答
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”,按回车键并用“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

- 现在将文件路径更改为 .ps1 脚本的位置并保存文本文档。

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

完毕!如果您现在打开 .vbs,当您的脚本在后台运行时,您应该看不到控制台窗口。

如果这对您有用,请务必投票!

于 2020-06-02T09:18:54.247 回答
2

当您计划任务时,只需在“常规”选项卡下选择“无论用户是否登录都运行”。

另一种方法是让任务以另一个用户身份运行。

于 2021-01-06T07:27:28.833 回答
1

等到Powershell执行完毕,在vbs中得到结果

这是使用 Exec() 时Omegastripes 代码隐藏命令提示符窗口的改进版本

将来自 cmd.exe 的混淆响应拆分为一个数组,而不是将所有内容都放入一个难以解析的字符串中。

此外,如果在执行 cmd.exe 期间发生错误,将在 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
于 2020-12-21T08:51:00.480 回答
0
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
于 2020-12-21T08:41:05.587 回答
0
powershell.exe -windowstyle hidden -noexit -ExecutionPolicy Bypass -File <path_to_file>

然后设置运行:最小化

应该可以按预期工作,而无需添加隐藏窗口闪烁的代码,只是稍微延迟了执行。

于 2021-03-17T05:57:37.543 回答
0

在我尝试过的所有解决方案中,这是迄今为止最好和最容易设置的。从这里下载 hiddenw.exe - https://github.com/SeidChr/RunHiddenConsole/releases

假设您想无控制台运行 Powershell v5。只需将 hiddenw.exe 重命名为 powershellw.exe。如果要对 cmd 执行此操作,请重命名为 cmdw.exe。如果要为 Powershell v7 (pwsh) 执行此操作,请重命名为 pwshw.exe。您可以创建 hiddenw.exe 的多个副本,然后将其重命名为实际进程并在末尾添加字母 w。然后,只需将该进程添加到您的系统环境 PATH 中,这样您就可以从任何地方调用它。或者直接复制到 C:\Windows。然后,只需调用它,如下所示:

powershellw .\example.ps1

于 2022-01-28T00:47:04.307 回答