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

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

不使用第三方组件的答案可获得额外分数:)


当前回答

下面是一行代码:

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

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

其他回答

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

等待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

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

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

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

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

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

Powershell内容为3。调用带有函数和参数的文件是:

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

如果你需要在任务调度器中运行这个,那么调用%comspec%作为程序/脚本,然后调用上面文件的代码作为参数。

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