Bir pencere görüntülemeden bir PowerShell betiği nasıl çalıştırılır?


127

Kullanıcıya bir pencere veya başka bir işaret göstermeden bir PowerShell betiğini çalıştırmak nasıl mümkün olabilir ?

Başka bir deyişle, komut dosyası, kullanıcıya herhangi bir işaret vermeden arka planda sessizce çalışmalıdır.

Üçüncü taraf bileşenlerini kullanmayan bir cevap için ekstra kredi :)


Öğrenmekle ilgileniyorsanız bu soruyu kontrol edin: stackoverflow.com/questions/573623/powershell-vs-unix-shells
Thomas Bratt

Bu çözüm Görev Zamanlayıcı için de
işe yarar

Yanıtlar:


128

Ya şu şekilde çalıştırabilirsiniz (ancak bu bir süreliğine bir pencere gösterir):

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

Veya tam olarak bunu yapan PsRun.exe adlı pencereden kaçınmak için oluşturduğum bir yardımcı dosya kullanırsınız. Kaynak ve exe dosyasını yükleyebilirsiniz Zamanlanmış görevleri PowerShell'de WinForm GUI ile çalıştırın . Planlanmış görevler için kullanıyorum.

Düzenlendi: Marco'nun da belirttiği gibi bu pencere stili parametresi yalnızca V2 için kullanılabilir.


6
PsRun'u derledim, ancak planlanan göreve eklersem, bir pencere de yanıp sönüyor ...
Ciantic

2
Burada da aynı şekilde çalışmaz çünkü pencere betiği çalıştırmak için hala açılır. Hızlı bir şekilde çıkıyor, ancak bunu arka planda kesintisiz olarak çalıştırmaya çalışıyoruz.
Nathan McKaskle

1
Evet, bu yüzden yanıtta "ama bu bir süre pencere gösteriyor" var.
stej

21
@ThomasBratt Zamanlanmış görevler için, PowerShell betiklerinin -WindowStyle Hiddengörev Run whether user is logged on or not"Güvenlik Seçenekleri" bölümünün altındaki Genel sekmesinde ayarlanmadan sessizce çalıştığını gördüm .
adam

1
Kullanıcı Hesabını SİSTEM'e kullanmak, bir pencerenin görüntülenmesini de önler.
Jon Eldridge

28

Ben de aynı sorunu yaşıyordum. Eğer gidersen öğrendim Görev içinde Görev Zamanlayıcı çalışırken powershell.exe senaryo, alt köşede bulunan " kullanıcı oturum olup olmadığını Çalıştır " ve ne zaman görev çalışır powershell penceresini hiçbir zaman gösterilmez.


3
Üçüncü taraf bir uzantıya, yürütülebilir veya sarmalayıcı betiğine bağlı olmadan en iyi çözüm.
tersine çevirin

1
Bu seçeneğin, kullanıcının "Toplu İş Olarak Oturum


18

PowerShell Topluluk Uzantılarını kullanabilir ve bunu yapabilirsiniz:

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

Bunu VBScript ile de yapabilirsiniz: http://blog.sapien.com/index.php/2006/12/26/more-fun-with-scheduled-powershell/

( Bu forum başlığıyla .)


Bunun için bir NuGet paketi var mı, böylece onu Visual Studio'dan çalıştırabilirim?
Piotr Kula

13

İşte komut satırı bağımsız değişkenleri veya ayrı bir başlatıcı gerektirmeyen bir yaklaşım. Tamamen görünmez değildir çünkü başlangıçta bir pencere anlık olarak gösterilir. Ama sonra hızla yok olur. Sorun olmayan yerlerde, betiğinizi gezginde çift tıklayarak veya bir Başlat menüsü kısayolu (tabii ki Başlangıç ​​alt menüsü dahil) aracılığıyla başlatmak istiyorsanız en kolay yaklaşım budur. Ve bunun senaryonun kendi kodunun bir parçası olması hoşuma gidiyor, harici bir şey değil.

Bunu senaryonuzun önüne koyun:

$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

İşte tek satırlık:

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

Bunun bir pencereyi çok kısa bir süre yanıp sönmesi mümkün olsa da, bu nadir bir durumdur.


Çoğu durumda, Powershell.exe'yi oturum açmış kullanıcılar bağlamında çalıştırmak ya tam bir pencere gösterir ya da -windowstyle gizli kullanırsanız kısa bir süre yanıp söner. Pencereyi tamamen kaldırmak için iki şeyden birini yapabilirsiniz: 1: Yönetici hesabı gibi farklı bir kullanıcının bağlamında çalıştırın (oturum açmış kullanıcıya herhangi bir pencere göstermez). Veya 2: cmd.exe / c powershel.exe -dosyası c: \ script.ps1'i başlatmak için objshell.run ile gizli pencere bayrağı içeren bir vbscript kullanın. Powershell cmd'den çağrıldığında, wscript.exe // b / nologo c: \ launcher.vbs tarafından zaten gizlenmiş olan mevcut cmd penceresinde çalışacaktır.
Iconiu

vay, Aniden. İlk başta cevabınızı bile fark etmedim. Çok benzer bir senaryo ile cevap verdim. Gerçek bir cevap veren bilgili bir insan görmek güzel.
Gosha

Bu kabul edilen cevap olmalı, her durumda işe yarayan bir yöntemdir (benim sorunum olan görev planlayıcısının içi dahil).
Martin Argerami

6

Windows 7'de c # üzerinden çalıştırırken bu sorunu yaşıyordum, "Etkileşimli Hizmet Algılama" hizmeti, SYSTEM hesabı olarak gizli bir powershell penceresi çalıştırırken ortaya çıkıyordu.

"CreateNoWindow" parametresinin kullanılması ISD servisinin uyarısını açmasını engelledi.

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

5

Bir arka plan betikleri çalıştırırken PowerShell'in konsol ekranını gizlemenin en iyi yolunun bu kod olduğunu düşünüyorum (" Bluecakes " yanıtı).

Bu kodu, arka planda çalıştırmam gereken tüm PowerShell betiklerimin başına ekliyorum.

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

Bu cevap size yardımcı olduysa , lütfen bu gönderideki cevabında "Bluecakes" e oy verin.


Benim için konsol hala yaklaşık bir saniye görüntüleniyor.
thdoan

3

Görev Zamanlayıcı'dan ve kısayoldan gizlenen ps1

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

2

Penceresiz başlatmak istediğiniz herhangi bir konsol aracına çağrıyı orijinal dosyaya geçiren küçük bir araç oluşturdum:

https://github.com/Vittel/RunHiddenConsole

Derledikten sonra yürütülebilir dosyayı "<targetExecutableName> w.exe" olarak yeniden adlandırın (bir "w" ekleyin) ve orijinal yürütülebilir dosyanın yanına koyun. Daha sonra normal parametrelerle eG powershellw.exe'yi çağırabilirsiniz ve bir pencere açılmaz.

Birinin oluşturulan sürecin girdi bekleyip beklemediğini nasıl kontrol edeceği konusunda bir fikri varsa, çözümünüzü eklemekten memnuniyet duyarız :)


1
Powershell komut dosyalarını başlangıçta herhangi bir pencere flaşı MessageBoxolmadan çalıştırmak istiyorsanız (konsol uygulaması değil, Winexe olarak derlenmiş bir EXE gerektiriyor ve Görev Zamanlayıcı'nın "Yalnızca kullanıcı oturum açtığında çalıştır) olarak ayarlanmasını gerektiriyorsa bu en iyi yanıttır. "bu yüzden iletişim kutuları mevcut masaüstü oturumunda gösteriliyor.) Bunu uyguladığınız için teşekkürler, powershellw.exe yıllardır dilek listemde yer alıyor!
Carl Walsh

Not: Bir süre önce "girdi beklemek" çözümünü ekledim (birkaç hata düzeltmesinin yanı sıra)!
Chris

@CarlWalsh, bunun bir konsol uygulaması olmadığını, bunun yerine bir kazanmanın uygulamayı oluşturduğunu kastettiğinizi varsayıyorum, bu doğru. sadece herhangi bir pencere içermez. ancak proje türü csproj dosyasında tanımlanmalı ve onu görsel stüdyo ile açtıktan sonra belirli bir çıktı türü ayarlamanıza gerek yoktur
Chris

2

İşte Windows 10'da herhangi bir üçüncü taraf bileşeni içermeyen çalışan bir çözüm. PowerShell betiğini VBScript'e sararak çalışır.

Adım 1: VBScript'in PowerShell'i çalıştırmasına ve varsayılan olarak .ps1 dosyalarını PowerShell ile açmasına izin vermek için bazı Windows özelliklerini değiştirmemiz gerekiyor.

- çalıştırıp "regedit" yazın. Tamam'a tıklayın ve ardından çalışmasına izin verin.

-bu yolu "HKEY_CLASSES_ROOT \ Microsoft.PowerShellScript.1 \ Shell" yapıştırın ve enter tuşuna basın.

-şimdi sağdaki girişi açın ve değeri 0 olarak değiştirin.

-PowerShell'i yönetici olarak açın ve "Set-ExecutionPolicy -ExecutionPolicy RemoteSigned" yazın, enter tuşuna basın ve "y" ile değişikliği onaylayın ve ardından girin.

Adım 2: Şimdi betiğimizi sarmaya başlayabiliriz.

-Powershell komut dosyanızı .ps1 dosyası olarak kaydedin.

-yeni bir metin belgesi oluşturun ve bu komut dosyasını yapıştırın.

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

-şimdi .ps1 betiğinizin dosya yolunu değiştirin ve metin belgesini kaydedin.

-Şimdi dosyaya sağ tıklayın ve yeniden adlandırmaya gidin. Ardından dosya adı uzantısını .vbs olarak değiştirin ve enter tuşuna basın ve ardından Tamam'a tıklayın.

YAPILAN! Şimdi .vbs dosyasını açarsanız, komut dosyanız arka planda çalışırken hiçbir konsol penceresi görmemelisiniz.

Bu sizin için işe yaradıysa, olumlu oy verdiğinizden emin olun!


1

Aşağıda, simge durumuna küçültme ve gizleme dahil olmak üzere konsolun çeşitli durumlarını kontrol etmenin eğlenceli bir demosu var.

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"
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.