Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/windows/15.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Windows 如何在不显示窗口的情况下运行PowerShell脚本?_Windows_Powershell_Scripting_Batch File_Silent - Fatal编程技术网

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

Windows 如何在不显示窗口的情况下运行PowerShell脚本?,windows,powershell,scripting,batch-file,silent,Windows,Powershell,Scripting,Batch File,Silent,如何在不向用户显示窗口或任何其他标志的情况下运行脚本 换句话说,脚本应该在后台安静地运行,而不向用户显示任何迹象 不使用第三方组件的答案的额外积分:)您可以使用并执行以下操作: start-process PowerShell.exe -arg $pwd\foo.ps1 -WindowStyle Hidden 也可以使用VBScript执行此操作: (互联网档案) (互联网档案) (Via.)您可以这样运行它(但这显示了一段时间的窗口): 或者,您可以使用我创建的帮助文件来避免名为PsRu

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

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

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

您可以使用并执行以下操作:

start-process PowerShell.exe -arg $pwd\foo.ps1 -WindowStyle Hidden
也可以使用VBScript执行此操作:

  • (互联网档案)

  • (互联网档案)


(Via.)

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

或者,您可以使用我创建的帮助文件来避免名为PsRun.exe的窗口,该窗口正是这样做的。您可以下载源代码和exe文件。我用它来完成预定的任务


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

我在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
};

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

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

$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)
这是一条单行线:

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

虽然可以非常短暂地闪烁窗口,但这种情况应该很少发生。

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

我将此代码添加到需要在后台运行的所有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
如果这个答案对你有帮助,请投赞成票


我也有同样的问题。我发现,如果您转到运行powershell.exe脚本的任务调度程序中的任务,您可以单击“运行,无论用户是否登录”当任务运行时,这将永远不会显示powershell窗口。

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

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


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

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

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"

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

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

这里有一个在windows 10中运行的解决方案,它不包括任何第三方组件。它通过将PowerShell脚本包装到VBScript中来工作。

步骤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键

步骤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,当脚本在后台运行时,将不会看到任何控制台窗口

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

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

我真的厌倦了看答案,结果却发现它没有按预期的那样起作用

解决方案

制作一个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.

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

这是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

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

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

powershell.exe-windowstyle hidden-noexit-ExecutionPolicy Bypass-File
powershell.exe -windowstyle hidden -noexit -ExecutionPolicy Bypass -File <path_to_file>
然后设置运行:最小化

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

隐藏了
-WindowStyle
的答案很好,但是窗口仍然会闪烁

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

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

1.调用文件
2.用参数调用文件
3.使用函数调用文件
powershell.exe -windowstyle hidden -noexit -ExecutionPolicy Bypass -File <path_to_file>
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'"
cmd /c start /min "" powershell -WindowStyle Hidden -ExecutionPolicy Bypass -Command ". 'C:\Users\username\Desktop\test.ps1'; Get-Test -stringTest 'Hello World'"
function Get-Test() {
  [cmdletbinding()]
  Param
  (
    [Parameter(Mandatory = $true, HelpMessage = 'The test string.')]
    [String]$stringTest
    )
  Write-Host $stringTest
  return
}