Toplu iş dosyasından bir PowerShell betiği çalıştırma


197

Bu komut dosyasını PowerShell'de çalıştırmaya çalışıyorum. Aşağıdaki betiği ps.ps1masaüstümdeki gibi kaydettim .

$query = "SELECT * FROM Win32_DeviceChangeEvent WHERE EventType = 2"
Register-WMIEvent -Query $query -Action { invoke-item "C:\Program Files\abc.exe"}

Bu PowerShell betiğini çalıştırmak için bir toplu iş komut dosyası yaptım

@echo off
Powershell.exe set-executionpolicy remotesigned -File  C:\Users\SE\Desktop\ps.ps1
pause

Ama bu hatayı alıyorum:

Resim açıklamasını buraya girin

Yanıtlar:


267

-ExecutionPolicyParametreye ihtiyacınız var :

Powershell.exe -executionpolicy remotesigned -File  C:\Users\SE\Desktop\ps.ps1

Aksi takdirde PowerShell argümanlardır yürütmek için bir çizgi dikkate alır ve süre Set-ExecutionPolicy olan bir komutu konusunda hiçbir vardır -Fileparametre.


2
@ joey teşekkürler çalıştı ... ama yarasa dosyasını çalıştırdıktan sonra bu hatayı aldım "Waring: sütun 'komut' ekrana sığmaz ve kaldırıldı"
Eka

Bu bir uyarı, bir hata değil. Ve daha başka bir soru için bir konu.
Joey

@ joey Yığına başka bir soru yazmak akıllıca olur.
Eka

2
@Joey Haha, yönetici olmadan bu politikayı geçersiz kılabilirsiniz. Bu bir güvenlik sorunu mu?
Kolob Kanyonu

2
@KolobCanyon: PowerShell'i çalıştırabileceğiniz bir konumdaysanız, diğer her şeyi de yapabilirsiniz. Yürütme ilkesinin, PowerShell'in aksi takdirde olacağından daha fazla ayrıcalığa sahip olduğu anlamına gelmediğini unutmayın. Bir şekilde, çalıştırmak istemeyebileceğiniz şeyleri yanlışlıkla çalıştırmamaktan kaçınmak sadece bir kolaylıktır. Geçerli dizindeki komutların önüne ön ek eklemek ./ve Unix'te yürütülebilir bir bayrağa sahip olmak gibi.
Joey

117

Hem toplu iş dosyasından neden bir PowerShell betiği çağırmak istediğinizi hem de buradaki blog yazımda nasıl yapılacağını açıklıyorum .

Temelde aradığınız şey budur:

PowerShell -NoProfile -ExecutionPolicy Bypass -Command "& 'C:\Users\SE\Desktop\ps.ps1'"

PowerShell betiğinizi yönetici olarak çalıştırmanız gerekirse, bunu kullanın:

PowerShell -NoProfile -ExecutionPolicy Bypass -Command "& {Start-Process PowerShell -ArgumentList '-NoProfile -ExecutionPolicy Bypass -File ""C:\Users\SE\Desktop\ps.ps1""' -Verb RunAs}"

Tüm PowerShell betiğinin yolunu sabit olarak kodlamak yerine, toplu iş dosyasını ve PowerShell komut dosyasını blog gönderimin açıkladığı gibi aynı dizine yerleştirmenizi öneririm.


Bir cmd penceresine komut satırını yazdığımda Invoke-WebRequest iyi çalışıyor, ancak bir toplu iş dosyasından çalıştırdığımda 404 döndürüyor. Deniyorum PowerShell -NoProfile -ExecutionPolicy Bypass -Command "& {Start-Process PowerShell -ArgumentList '-NoProfile -ExecutionPolicy Bypass Invoke-WebRequest https://www.example.com/example.ics -OutFile C:\_my\script.ics' -Verb RunAs}";veya powershell -Command "Invoke-WebRequest https://www.example.com/example.ics -OutFile c:\_my\file.ics", veya .ps1 dosyasında aynı -File seçeneğini kullanarak veya (New-Object Net.WebClient).DownloadFile. Herhangi bir fikir?
Chris

-ExecutionPolicy Sınırsız kullanmayı deneyin. Baypas seçeneğinin PowerShell ağ erişimine izin vermediğini tahmin ediyorum.
deadlydog

1
@Belun Başvurulan blog gönderisi, parametrelere komut dosyasına nasıl geçirileceğini gösterir.
deadlydog

19

Geçerli dizinden tam olarak nitelenmiş bir yol olmadan çalıştırmak istiyorsanız, aşağıdakileri kullanabilirsiniz:

PowerShell -NoProfile -ExecutionPolicy Bypass -Command "& './ps.ps1'"

16

PowerShell'i yönetici olarak çağıran bir toplu iş dosyası çalıştırırsanız, bu şekilde çalıştırsanız daha iyi bir sorunla karşılaşırsınız:

powershell.exe -ExecutionPolicy Bypass -Command "Path\xxx.ps1"

Kullanmak daha iyidir Bypass...


3

Birkaç komut dosyası çalıştırmak istiyorsanız, tuşunu kullanarak Set-executionpolicy -ExecutionPolicy Unrestrictedve ardından sıfırlayabilirsiniz Set-executionpolicy -ExecutionPolicy Default.

Yürütme ilkesinin yalnızca yürütmeyi başlattığınızda (veya öyle görünüyorsa) denetlendiğini ve böylece işleri arka planda çalıştırabileceğiniz ve yürütme ilkesini hemen sıfırlayabileceğinizi unutmayın.

# Check current setting
Get-ExecutionPolicy

# Disable policy
Set-ExecutionPolicy -ExecutionPolicy Unrestricted
# Choose [Y]es

Start-Job { cd c:\working\directory\with\script\ ; ./ping_batch.ps1 example.com | tee ping__example.com.txt }
Start-Job { cd c:\working\directory\with\script\ ; ./ping_batch.ps1 google.com  | tee ping__google.com.txt  }

# Can be run immediately
Set-ExecutionPolicy -ExecutionPolicy Default
# [Y]es

2

Bir ps komut dosyasını toplu işlemden yürütmenin başka bir kolay yolu, onu ECHO ve Yönlendirme karakterleri arasına dahil etmektir (> ve >>), örnek:

@echo off
set WD=%~dp0
ECHO New-Item -Path . -Name "Test.txt" -ItemType "file" -Value "This is a text string." -Force > "%WD%PSHELLFILE.ps1"
ECHO add-content -path "./Test.txt" -value "`r`nThe End" >> "%WD%PSHELLFILE.ps1"
powershell.exe -ExecutionPolicy Bypass -File "%WD%PSHELLFILE.ps1"
del "%WD%PSHELLFILE.ps1"

Son satır, oluşturulan geçici dosyayı siler.


1

PowerShell oturum açma komut dosyanız 2012 sunucusunda 5 dakika sonra (benimki gibi) çalışıyorsa, sunucuda GPO ayarı vardır - 'Oturum Açma komut dosyası Gecikmesini Yapılandır' varsayılan ayar 'yapılandırılmamış', bu 5 dakikalık bir gecikme bırakacak oturum açma komut dosyasını çalıştırmadan önce.


1

Küçük örnek testi. Cmd

<# :
  @echo off
    powershell /nologo /noprofile /command ^
         "&{[ScriptBlock]::Create((cat """%~f0""") -join [Char[]]10).Invoke(@(&{$args}%*))}"
  exit /b
#>
Write-Host Hello, $args[0] -fo Green
#You programm...
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.