代码之家  ›  专栏  ›  技术社区  ›  Thomas Bratt

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

  •  95
  • Thomas Bratt  · 技术社区  · 16 年前

    PowerShell 不向用户显示窗口或任何其他标志的脚本?

    换句话说,脚本应该在后台安静地运行,而不向用户显示任何迹象。

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

    8 回复  |  直到 16 年前
        1
  •  154
  •   stej    16 年前

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

    或者,您可以使用我创建的帮助文件来避免名为PsRun.exe的窗口,该窗口正是这样做的。您可以下载源代码和exe文件 Run scheduled tasks with WinForm GUI in PowerShell

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

        2
  •  46
  •   Yusha    7 年前

    我也有同样的问题。我发现如果你去 在里面 任务调度器 父进程 脚本,您可以单击“ “当任务运行时,它将永远不会显示powershell窗口。

        3
  •  19
  •   Danilo Roascio ToTamire    8 年前

    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/

    (Via this forum thread

        4
  •  16
  •   Andy Lowry    11 年前

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

    将以下内容放在脚本的前面:

    $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)
    
        5
  •  13
  •   Adam Taylor    9 年前

    这是一条单行线:

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

        6
  •  10
  •   Garric    6 年前

    ps1对任务计划程序和快捷方式隐藏

        mshta vbscript:Execute("CreateObject(""WScript.Shell"").Run ""powershell -ExecutionPolicy Bypass & 'C:\PATH\NAME.ps1'"", 0:close")
    
        7
  •  6
  •   gavraham    8 年前

    我认为在运行后台脚本时隐藏PowerShell控制台屏幕的最佳方法是 this code (" Bluecakes “回答。

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

        8
  •  6
  •   Vincent K    8 年前

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

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

    答案是 -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.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'"
    

    的Powershell内容 是:

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

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

    enter image description here

        10
  •  4
  •   js2010    6 年前

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

    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"
    
        11
  •  3
  •   Leathan    5 年前

    解决方案

    制作一个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.
    
        12
  •  2
  •   Chris    7 年前

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

    https://github.com/Vittel/RunHiddenConsole

    然后,您可以使用常用参数调用例如powershellw.exe,它不会弹出窗口。

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

        13
  •  2
  •   neobihli    6 年前

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

    -转到运行并键入“regedit”。单击ok,然后让它运行。

    -粘贴此路径“HKEY\U CLASSES\U ROOT\Microsoft.PowerShellScript.1\Shell”,然后按enter键。

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

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

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

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

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

    如果这对你有用,一定要投票!

        14
  •  2
  •   Sandeep Verma    5 年前

    当您计划任务时,只需选择 根据"基本法", 一般的

    另一种方法是让任务作为另一个用户运行。

        15
  •  2
  •   John Stankievich    5 年前

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

        16
  •  2
  •   stax76    5 年前

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

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

    run-hidden powershell -command calc.exe
    
        17
  •  1
  •   Garric    5 年前

    这是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
    
        18
  •  0
  •   Garric    5 年前
    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
    
        19
  •  0
  •   Suraj Rao Raas Masood    5 年前
    powershell.exe -windowstyle hidden -noexit -ExecutionPolicy Bypass -File <path_to_file>
    

    然后设置运行:最小化

    只是执行稍微有点延迟。