Como executar um script do PowerShell sem exibir uma janela?


127

Como é possível executar um script do PowerShell sem exibir uma janela ou qualquer outro sinal para o usuário?

Em outras palavras, o script deve ser executado silenciosamente em segundo plano, sem nenhum sinal para o usuário.

Crédito extra por uma resposta que não usa componentes de terceiros :)


Confira esta pergunta se você estiver interessado em aprender: stackoverflow.com/questions/573623/powershell-vs-unix-shells
Thomas Bratt

Esta solução também funciona para o Agendador de tarefas: stackoverflow.com/a/51007810/571591
Hilydrow

Respostas:


128

Você pode executá-lo assim (mas isso mostra uma janela por um tempo):

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

Ou você usa um arquivo auxiliar que eu criei para evitar a janela chamada PsRun.exe que faz exatamente isso. Você pode baixar o arquivo de origem e exe. Executar tarefas agendadas com a GUI do WinForm no PowerShell . Eu o uso para tarefas agendadas.

Editado: como Marco notou, este parâmetro -windowstyle está disponível apenas para V2.


6
Eu compilei o PsRun, no entanto, se eu adicioná-lo à tarefa agendada, ele também piscará uma janela ...
Ciantic

2
O mesmo aqui, também não funciona, porque a janela ainda aparece para executar o script. Ele sai rapidamente, mas estamos tentando executar isso em segundo plano sem interrupção.
Nathan McKaskle 23/08/16

1
Sim, é por isso que existe "mas isso mostra uma janela por um tempo" na resposta.
stej

21
@ThomasBratt Para tarefas agendadas, eu encontrei os scripts do PowerShell executados silenciosamente sem, -WindowStyle Hiddense a tarefa estiver definida Run whether user is logged on or notna guia Geral, na seção "Opções de segurança".
21416 adam

1
Usar a conta de usuário no sistema também evita que uma janela seja exibida.
Jon Eldridge

27

Eu estava tendo esse mesmo problema. Descobri se você acessa a Tarefa no Agendador de Tarefas que está executando o powershell.exe script , poderá clicar em " Executar se o usuário estiver conectado ou não " e isso nunca mostrará a janela do PowerShell quando a tarefa for executada.


3
A melhor solução sem depender de scripts de extensão, executável ou wrapper de terceiros.
Invert

1
Note-se que esta opção requer que o usuário tenha o "logon como Batch Job" privilégio
GB96

Essa solução faz com que meu script não seja executado corretamente .
Martin Argerami

18

Você pode usar as extensões da comunidade do PowerShell e fazer o seguinte:

start-process PowerShell.exe -arg $pwd\foo.ps1 -WindowStyle Hidden

Você também pode fazer isso com o VBScript: http://blog.sapien.com/index.php/2006/12/26/more-fun-with-scheduled-powershell/

(Através deste tópico do fórum .)


Existe um paclage do NuGet para isso, para que eu possa executá-lo no Visual Studio?
Piotr Kula

13

Aqui está uma abordagem que não requer argumentos de linha de comando ou um iniciador separado. Não é completamente invisível porque uma janela aparece momentaneamente na inicialização. Mas então desaparece rapidamente. Onde está tudo bem, acho que é a abordagem mais fácil se você deseja iniciar seu script clicando duas vezes no explorer ou através de um atalho do menu Iniciar (incluindo, é claro, o submenu Inicialização). E eu gosto que isso faz parte do código do próprio script, não algo externo.

Coloque isso na frente do seu script:

$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)

10

Aqui está uma frase:

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

Embora seja possível exibir uma janela muito brevemente, isso deve ser uma ocorrência rara.


Na maioria dos casos, a execução do Powershell.exe no contexto de usuários conectados mostrará uma janela completa ou piscará brevemente se você usar -windowstyle hidden. Para remover totalmente a janela, você pode fazer uma de duas coisas: 1: Executar em um contexto de usuário diferente, como uma conta de administrador (não exibirá nenhuma janela para o usuário conectado). Ou 2: use um vbscript com objshell.run com um sinalizador de janela oculta para iniciar o cmd.exe / c powershel.exe - arquivo c: \ script.ps1. Quando o powershell é chamado a partir do cmd, ele será executado na janela existente do cmd, que já está oculta pelo wscript.exe // b / nologo c: \ launcher.vbs.
Iconiu 26/03/19

Uau, de repente. Eu nem percebi sua resposta a princípio. Eu respondi com um script muito semelhante. É bom ver uma pessoa experiente que dá uma resposta real.
Gosha

Essa deve ser a resposta aceita, é o único método que parece funcionar em todas as situações (inclusive dentro do agendador de tarefas, que era o meu problema).
Martin Argerami

6

Eu estava tendo esse problema ao executar a partir do c #, no Windows 7, o serviço "Detecção de serviços interativos" estava aparecendo ao executar uma janela oculta do PowerShell como a conta SYSTEM.

O uso do parâmetro "CreateNoWindow" impediu que o serviço ISD aparecesse como aviso.

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

5

Acho que a melhor maneira de ocultar a tela do console do PowerShell quando você estiver executando scripts em segundo plano é esse código (" Bluecakes resposta " ").

Eu adiciono esse código no início de todos os meus scripts do PowerShell que preciso executar em segundo plano.

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

Se essa resposta foi útil , vote em "Bluecakes" em sua resposta nesta postagem.


Para mim, o console ainda é exibido por cerca de um segundo.
thdoan

3

ps1 oculto no Agendador de tarefas e atalho também

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

2

Eu criei uma pequena ferramenta passando a chamada para qualquer ferramenta do console que você deseja iniciar sem janelas no arquivo original:

https://github.com/Vittel/RunHiddenConsole

Após a compilação, apenas renomeie o executável como "<targetExecutableName> w.exe" (adicione um "w") e coloque-o ao lado do executável original. Você pode chamar o eG powershellw.exe com os parâmetros usuais e ele não abrirá uma janela.

Se alguém tiver uma idéia de como verificar se o processo criado está aguardando entrada, será um prazer incluir sua solução :)


1
Esta é a melhor resposta se você deseja executar scripts do PowerShell usando MessageBoxsem nenhum flash da janela na inicialização (exigindo um EXE compilado como um Winexe, não um aplicativo de console e exigindo que o Agendador de tarefas seja definido como "Executar apenas quando o usuário estiver conectado em "para que as caixas de diálogo sejam exibidas na sessão atual da área de trabalho.) Obrigado por implementar isso, o powershellw.exe está na minha lista de desejos há anos!
Carl Walsh

PS: Eu incluí a solução para "aguardar entrada" há um tempo (e algumas correções)!
31419 Chris

@CarlWalsh Presumo que você queira dizer que não é um aplicativo de console, mas um aplicativo de formulários de vitória, o que está correto. apenas não inclui nenhuma janela. mas o tipo de projeto deve ser definido no arquivo csproj e você não precisa definir um tipo de saída específica após abri-lo com o visual studio
Chris

2

Aqui está uma solução funcional no Windows 10 que não inclui nenhum componente de terceiros. Ele funciona envolvendo o script do PowerShell no VBScript.

Etapa 1: precisamos alterar alguns recursos do Windows para permitir que o VBScript execute o PowerShell e abra arquivos .ps1 com o PowerShell por padrão.

-vá para executar e digite "regedit". Clique em ok e depois permita que ele seja executado.

- cole esse caminho "HKEY_CLASSES_ROOT \ Microsoft.PowerShellScript.1 \ Shell" e pressione enter.

Agora, abra a entrada à direita e altere o valor para 0.

- abra o PowerShell como administrador e digite "Set-ExecutionPolicy -ExecutionPolicy RemoteSigned", pressione enter e confirme a alteração com "y" e, em seguida, insira.

Etapa 2: Agora podemos começar a agrupar nosso script.

-salve seu script do Powershell como um arquivo .ps1.

-crie um novo documento de texto e cole este script.

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

Agora, altere o caminho do arquivo para o local do script .ps1 e salve o documento de texto.

-Agora clique com o botão direito do mouse no arquivo e vá para renomear. Em seguida, altere a extensão do nome do arquivo para .vbs, pressione enter e clique em ok.

FEITO! Se você agora abrir o arquivo .vbs, não verá uma janela do console enquanto o script estiver sendo executado em segundo plano.

certifique-se de votar se isso funcionou para você!


1

Aqui está uma demonstração divertida de controlar os vários estados do console, incluindo minimizar e ocultar.

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"
Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.