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

时间:2009-11-26 07:45:07

标签: windows powershell scripting batch-file silent

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

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

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

19 个答案:

答案 0 :(得分:106)

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

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

或者您使用我创建的帮助文件来避免名为PsRun.exe的窗口。您可以下载源文件和文件Run scheduled tasks with WinForm GUI in PowerShell。我将它用于计划任务。

编辑:正如Marco所说,这个-windowstyle参数仅适用于V2。

答案 1 :(得分:17)

您可以使用PowerShell Community Extensions并执行此操作:

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/

(通过this forum thread。)

答案 2 :(得分: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)

答案 3 :(得分:8)

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

答案 4 :(得分:5)

从c#运行时遇到此问题,在Windows 7上,当运行隐藏的PowerShell窗口作为SYSTEM帐户时,“Interactive Services Detection”服务弹出。

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

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

答案 5 :(得分:4)

这是一个单行:

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

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

答案 6 :(得分:4)

我认为在运行后台脚本时隐藏PowerShell控制台屏幕的最佳方法是this code(“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" in his answer in this post.

答案 7 :(得分:3)

-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.ps1'; -Arg1 'Hello' -Arg2 ' World'"

3.使用函数和参数调用文件

cmd /c start /min "" powershell -WindowStyle Hidden -ExecutionPolicy Bypass -Command ". 'C:\Users\username\Desktop\test.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
}

如果您需要在 Task Scheduler 中运行此程序,请调用 %comspec% 作为程序/脚本,然后调用上述文件作为参数的代码。

enter image description here

答案 8 :(得分:2)

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

答案 9 :(得分: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

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

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

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

请确保该方法对您有用!

答案 10 :(得分:1)

我已经创建了一个小工具,可以将调用传递到您要启动的任何控制台工具,然后将其无窗口地传递到原始文件:

https://github.com/Vittel/RunHiddenConsole

编译后,只需将可执行文件重命名为“ w.exe”(附加“ w”),然后将其放在原始可执行文件旁边。 然后,您可以致电e.G.具有常规参数的powershellw.exe不会弹出一个窗口。

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

答案 11 :(得分:1)

在安排任务时,只需在“常规”标签下选择“无论用户是否登录都运行”

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

答案 12 :(得分:0)

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

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

示例命令行:

run-hidden powershell -command calc.exe

答案 13 :(得分:0)

powershell.exe -windowstyle hidden -noexit -ExecutionPolicy Bypass -File <path_to_file>

然后设置运行:最小化

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

答案 14 :(得分:0)

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

这是 Omegastripes 代码的改进版本 Hide command prompt window when using 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

答案 15 :(得分: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

答案 16 :(得分:0)

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

解决方案

制作一个vbs脚本来运行一个隐藏的批处理文件,该文件将启动powershell脚本。似乎很傻,无法为此任务制作3个文件,但总大小至少不到2KB,并且可以从Tasker或手动运行(您什么都看不见)完美运行。

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.

答案 17 :(得分:0)

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

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

答案 18 :(得分:0)

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

enum UpLow {
    case Uppercase
    case Lowercase

    func setCase(text: String) -> String {
        switch self {
        case .Uppercase:
            return text.uppercased()

        case .Lowercase:
            return text.lowercased()
        }
    }
    setCase(text: "example", case: .Uppercase)
}