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

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

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


当前回答

你可以像这样运行它(但这会显示一个窗口):

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

或者您可以使用我创建的一个帮助文件来避免名为PsRun.exe的窗口,它正是这样做的。您可以在PowerShell中使用WinForm GUI运行计划任务中下载源文件和exe文件。我用它来完成计划好的任务。

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

其他回答

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

我找到了一种方法,通过将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

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

在我尝试过的所有解决方案中,这是迄今为止最好和最容易设置的。从这里下载hiddenw.exe - https://github.com/SeidChr/RunHiddenConsole/releases

假设您希望运行Powershell v5无控制台。只需将hiddenw.exe重命名为powershell .exe。如果您想为cmd执行此操作,则重命名为cmdw.exe。如果要为Powershell v7 (pwsh)执行此操作,则重命名为pwshw.exe。您可以创建多个副本的hidden .exe,只是重命名为实际进程与字母w在末尾。然后,只需将该流程添加到系统环境PATH中,这样就可以从任何地方调用它。或者复制到C:\Windows。然后,像这样调用它:

powershellw ps1 \操作。

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

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

下面是一行代码:

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

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