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

发布于 2024-08-12 10:19:56 字数 187 浏览 6 评论 0原文

如何运行 PowerShell 脚本而不向用户显示窗口或任何其他标志?

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

不使用第三方组件的答案需额外加分:)

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

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(27

尝蛊 2024-08-19 10:19:57

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

https://github.com/stax76/run-隐藏

命令行示例:

run-hidden powershell -command calc.exe

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
独夜无伴 2024-08-19 10:19:57

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

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.

败给现实 2024-08-19 10:19:57

我真的厌倦了浏览答案却发现它没有按预期工作。

解决方案

创建一个 vbs 脚本来运行一个隐藏的批处理文件,该文件启动 powershell 脚本。为这个任务创建 3 个文件似乎很愚蠢,但至少总大小小于 2KB,并且它可以从任务管理器或手动运行完美(你看不到任何东西)。

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 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.
燃情 2024-08-19 10:19:57

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

https: //github.com/Vittel/RunHiddenConsole

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

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

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

请持续率性 2024-08-19 10:19:57

单个 vbs 文件解决方案。首先必须将 ps 脚本转换为 base64 字符串,将其放置在如下所示模板中的变量中,并将其另存为 vbs 文件。运行时不会弹出 powershell。

dim EncodedCommand
EncodedCommand = "COMMAND"

pSCmd = "powershell.exe -noexit -windowstyle Hidden -executionpolicy bypass -encodedcommand " & EncodedCommand

CreateObject("WScript.Shell").Run pSCmd, 0, True

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
记忆消瘦 2024-08-19 10:19:57

等待Powershell执行并在vbs中获取结果

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

将来自 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

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
樱&纷飞 2024-08-19 10:19:57
powershell.exe -windowstyle hidden -noexit -ExecutionPolicy Bypass -File <path_to_file>

然后设置运行:最小化

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

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.

只等公子 2024-08-19 10:19:57

在我尝试过的所有解决方案中,这是迄今为止最好且最容易设置的解决方案。从这里下载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。然后,只需将该进程添加到您的系统环境路径中,以便您可以从任何地方调用它。或者直接复制到 C:\Windows。然后,只需调用它,如下所示:

powershellw .\example.ps1

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

只想待在家 2024-08-19 10:19:57

这是 Windows 10 中的工作解决方案,不包含任何第三方组件。它的工作原理是将 PowerShell 脚本包装到 VBScript 中。

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

-go运行并输入“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

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

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

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

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.

我的影子我的梦 2024-08-19 10:19:57

如果您正在寻找不需要任何命令行参数的版本,只需在 powershell 脚本中编写代码即可使用新的 Windows 终端。

我在这里找到了这个解决方案

$ShowWindowAsyncCode = '[DllImport("user32.dll")] public static extern bool ShowWindowAsync(IntPtr hWnd, int nCmdShow);'
$ShowWindowAsync = Add-Type -MemberDefinition $ShowWindowAsyncCode -name Win32ShowWindowAsync -namespace Win32Functions -PassThru

$hwnd = (Get-Process -PID $pid).MainWindowHandle
if ($hwnd -ne [System.IntPtr]::Zero) {
  # When you got HWND of the console window:
  # (It would appear that Windows Console Host is the default terminal application)
  $ShowWindowAsync::ShowWindowAsync($hwnd, 0)
} else {
  # When you failed to get HWND of the console window:
  # (It would appear that Windows Terminal is the default terminal application)

  # Mark the current console window with a unique string.
  $UniqueWindowTitle = New-Guid
  $Host.UI.RawUI.WindowTitle = $UniqueWindowTitle
  $StringBuilder = New-Object System.Text.StringBuilder 1024

  # Search the process that has the window title generated above.
  $TerminalProcess = (Get-Process | Where-Object { $_.MainWindowTitle -eq $UniqueWindowTitle })
  # Get the window handle of the terminal process.
  # Note that GetConsoleWindow() in Win32 API returns the HWND of
  # powershell.exe itself rather than the terminal process.
  # When you call ShowWindowAsync(HWND, 0) with the HWND from GetConsoleWindow(),
  # the Windows Terminal window will be just minimized rather than hidden.
  $hwnd = $TerminalProcess.MainWindowHandle
  if ($hwnd -ne [System.IntPtr]::Zero) {
    $ShowWindowAsync::ShowWindowAsync($hwnd, 0)
  } else {
    Write-Host "Failed to hide the console window."
  }
}

If your looking for a version that doesn't require any command line parameters, just code in your powershell script and works with the new windows Terminal.

I found this solution here

$ShowWindowAsyncCode = '[DllImport("user32.dll")] public static extern bool ShowWindowAsync(IntPtr hWnd, int nCmdShow);'
$ShowWindowAsync = Add-Type -MemberDefinition $ShowWindowAsyncCode -name Win32ShowWindowAsync -namespace Win32Functions -PassThru

$hwnd = (Get-Process -PID $pid).MainWindowHandle
if ($hwnd -ne [System.IntPtr]::Zero) {
  # When you got HWND of the console window:
  # (It would appear that Windows Console Host is the default terminal application)
  $ShowWindowAsync::ShowWindowAsync($hwnd, 0)
} else {
  # When you failed to get HWND of the console window:
  # (It would appear that Windows Terminal is the default terminal application)

  # Mark the current console window with a unique string.
  $UniqueWindowTitle = New-Guid
  $Host.UI.RawUI.WindowTitle = $UniqueWindowTitle
  $StringBuilder = New-Object System.Text.StringBuilder 1024

  # Search the process that has the window title generated above.
  $TerminalProcess = (Get-Process | Where-Object { $_.MainWindowTitle -eq $UniqueWindowTitle })
  # Get the window handle of the terminal process.
  # Note that GetConsoleWindow() in Win32 API returns the HWND of
  # powershell.exe itself rather than the terminal process.
  # When you call ShowWindowAsync(HWND, 0) with the HWND from GetConsoleWindow(),
  # the Windows Terminal window will be just minimized rather than hidden.
  $hwnd = $TerminalProcess.MainWindowHandle
  if ($hwnd -ne [System.IntPtr]::Zero) {
    $ShowWindowAsync::ShowWindowAsync($hwnd, 0)
  } else {
    Write-Host "Failed to hide the console window."
  }
}
樱花落人离去 2024-08-19 10:19:57
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
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
孤凫 2024-08-19 10:19:57

我发现编译为 exe 是实现此目的的最简单方法。编译脚本的方法有很多种,但您可以尝试 ISE Steroids

打开“Windows PowerShell ISE”,安装并运行 ISESteroids:

Install-Module -Name "ISESteroids" -Scope CurrentUser -Repository PSGallery -Force

Start-Steroids

然后转到“工具”->“将代码转换为 EXE”,选择“隐藏控制台窗口”,然后创建该应用程序。
您可以直接从任务计划程序运行它,而不需要包装器或第三方应用程序。

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.

刘备忘录 2024-08-19 10:19:57

我所做的就是使用一个名为 Ps1 To Exe 的出色应用程序将 .ps1 文件转换为不可见的 .exe 文件,您可以在此处下载该应用程序:https://www.majorgeeks.com/files/details/ps1_to_exe.html

也许这会有所帮助(尽管我希望 12 年后你已经找到了合适的解决方案......

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... ????)

心病无药医 2024-08-19 10:19:57

换句话说,脚本应该在后台安静地运行,而不向用户发出任何信号。
对于不使用第三方组件的答案,请额外加分:)

我找到了一种方法,通过将 PowerShell 脚本编译为 Windows 可执行文件来实现此目的。需要第三方模块来构建可执行文件,但不需要运行它。我的最终目标是编译一行 PowerShell 脚本,在我的系统上弹出 DVD:

(New-Object -com "WMPlayer.OCX.7").cdromcollection.item(0).eject()

我的目标系统正在运行 Windows 7。所需的特定 WMF 更新因 Windows 版本而异:

下载并安装 WMF 5.1 软件包

所需的 PowerShell 模块应适用于任何 Windows 版本。以下是我用来安装必要模块和编译 exe 的确切命令。您需要调整系统的驱动器、目录和文件名详细信息:

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

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
晨光如昨 2024-08-19 10:19:57

我很懒,所以我使用这些 powershell 命令来创建计划任务,其中包含上面 Adam Taylor 的解决方案。您可以稍后编辑创建的任务(例如,从每天运行更改为其他任务):

#---adjust this part---
$script = "C:\Users\user\some-script.ps1"
$time = '5:15 AM'
$user = 'user'
$title = "Some title"
#-----------------------------------
$arguments = @'
vbscript:Execute("CreateObject(""Wscript.Shell"").Run ""powershell -NoProfile -ExecutionPolicy bypass -NoLogo -Command """"& '{script}'"""""", 0 : window.close")
'@ 
$arguments = $arguments -replace "{script}",$script
$actions = (New-ScheduledTaskAction -Execute "mshta" -Argument $arguments)
$trigger = New-ScheduledTaskTrigger -Daily -At $time
$principal = New-ScheduledTaskPrincipal -UserId $user 
$settings = New-ScheduledTaskSettingsSet -RunOnlyIfNetworkAvailable 
$task = New-ScheduledTask -Action $actions -Principal $principal -Trigger $trigger -Settings $settings
Register-ScheduledTask $title -InputObject $task

I am lazy so I use these powershell commands to create scheduled tasks that incorporate Adam Taylor's solution above. You can edit the created task later (e.g. to change from running daily to something else):

#---adjust this part---
$script = "C:\Users\user\some-script.ps1"
$time = '5:15 AM'
$user = 'user'
$title = "Some title"
#-----------------------------------
$arguments = @'
vbscript:Execute("CreateObject(""Wscript.Shell"").Run ""powershell -NoProfile -ExecutionPolicy bypass -NoLogo -Command """"& '{script}'"""""", 0 : window.close")
'@ 
$arguments = $arguments -replace "{script}",$script
$actions = (New-ScheduledTaskAction -Execute "mshta" -Argument $arguments)
$trigger = New-ScheduledTaskTrigger -Daily -At $time
$principal = New-ScheduledTaskPrincipal -UserId $user 
$settings = New-ScheduledTaskSettingsSet -RunOnlyIfNetworkAvailable 
$task = New-ScheduledTask -Action $actions -Principal $principal -Trigger $trigger -Settings $settings
Register-ScheduledTask $title -InputObject $task
一抹苦笑 2024-08-19 10:19:57

在命令之上只需编写以下脚本:

echo off

on top of your commands just write the below script:

echo off
是伱的 2024-08-19 10:19:56

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

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

或者您使用我创建的帮助程序文件来避免名为 PsRun.exe 的窗口执行此操作。您可以从 在 PowerShell 中使用 WinForm GUI 运行计划任务。我用它来执行计划任务。

编辑:正如 Marco 指出的,此 -WindowStyle 参数仅适用于 V2 及更高版本。

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.

半仙 2024-08-19 10:19:56

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


缺点:脚本无法与登录用户的屏幕交互(例如显示通知或任何 GUI 元素)。

先决条件:用户必须具有“作为批处理作业登录”权限。

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.


Drawbacks: the script can not interact with the screen of the logged on user (e.g. to display notifications or any GUI element).

Prerequisites: The user must have the "Log on as Batch Job" privilege.

陌伤ぢ 2024-08-19 10:19:56

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

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

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

1. 调用文件

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

文件

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

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

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 文件的路径中包含空格时,所有示例都有效。

输入图像描述这里

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

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.

enter image description here

路还长,别太狂 2024-08-19 10:19:56

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

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

您也可以使用 VBScript 执行此操作:< a href="http://blog.sapien.com/index.php/2006/12/26/more-fun-with-scheduled-powershell/" rel="noreferrer">http://blog.sapien.com /index.php/2006/12/26/more-fun-with-scheduled-powershell/

(通过 此论坛帖子。)

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

温柔嚣张 2024-08-19 10:19:56

这里有一句俏皮话:

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

虽然这可能会非常短暂地闪烁一个窗口,但这应该是一种罕见的情况。

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.

我为君王 2024-08-19 10:19:56

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

将其放在脚本的前面:

$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 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)
心病无药医 2024-08-19 10:19:56

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

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

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")
吲‖鸣 2024-08-19 10:19:56

我认为运行后台脚本时隐藏 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”在他的这篇文章的回答中。

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.

蒲公英的约定 2024-08-19 10:19:56

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

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

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

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
};
无风消散 2024-08-19 10:19:56

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

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

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.

独自←快乐 2024-08-19 10:19:56

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

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"

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"
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文