So führen Sie ein PowerShell-Skript aus einer Batchdatei aus

196

Ich versuche, dieses Skript in PowerShell auszuführen. Ich habe das folgende Skript wie ps.ps1auf meinem Desktop gespeichert .

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

Ich habe ein Batch-Skript erstellt, um dieses PowerShell-Skript auszuführen

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

Aber ich bekomme diesen Fehler:

Geben Sie hier die Bildbeschreibung ein

Eka
quelle

Antworten:

266

Sie benötigen den -ExecutionPolicyParameter:

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

Ansonsten Powershell betrachtet eine Linie , die die Argumente auszuführen und während Set-ExecutionPolicy ist ein Cmdlet, hat es keine -FileParameter.

Joey
quelle
2
@joey es hat funktioniert danke .. aber nach dem Ausführen der Bat-Datei bekam ich die Fehlermeldung "Warnung: Spalte 'Befehl' passt nicht in die Anzeige und wurde entfernt"
Eka
Das ist eine Warnung, kein Fehler. Und eher ein Thema für eine andere Frage.
Joey
@joey ist es ratsam, eine weitere Frage in stack.SE für diese kleine Warnung zu schreiben?
Eka
2
@Joey Haha, so effektiv können Sie diese Richtlinie überschreiben, ohne Administrator zu sein. Ist das ein Sicherheitsproblem?
Kolob Canyon
2
@KolobCanyon: Wenn Sie in der Lage sind, PowerShell auszuführen, können Sie so ziemlich alles andere tun. Beachten Sie, dass die Ausführungsrichtlinie nicht bedeutet, dass PowerShell über mehr Berechtigungen verfügt als sonst. In gewisser Weise ist es nur eine Annehmlichkeit, zu vermeiden, dass versehentlich Dinge ausgeführt werden, die Sie möglicherweise nicht ausführen möchten. Ähnlich wie Befehle im aktuellen Verzeichnis mit ./einem ausführbaren Flag unter Unix versehen werden müssen.
Joey
116

Ich erkläre in meinem Blog-Beitrag hier, warum Sie ein PowerShell-Skript aus einer Batch-Datei aufrufen möchten und wie dies zu tun ist .

Dies ist im Grunde das, wonach Sie suchen:

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

Wenn Sie Ihr PowerShell-Skript als Administrator ausführen müssen, verwenden Sie Folgendes:

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

Anstatt den gesamten Pfad zum PowerShell-Skript fest zu codieren, empfehle ich, die Batchdatei und die PowerShell-Skriptdatei im selben Verzeichnis abzulegen, wie in meinem Blogbeitrag beschrieben.

tödlicher Hund
quelle
Invoke-WebRequest funktioniert einwandfrei, wenn ich die Befehlszeile in ein cmd-Fenster eingebe, gibt jedoch eine 404 zurück, wenn ich sie aus einer Batchdatei heraus ausführe. Ich versuche 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}";oder powershell -Command "Invoke-WebRequest https://www.example.com/example.ics -OutFile c:\_my\file.ics", oder verwende die Option -File, um dasselbe in einer .ps1-Datei zu tun, oder (New-Object Net.WebClient).DownloadFile. Irgendwelche Ideen?
Chris
Versuchen Sie es mit -ExecutionPolicy Unrestricted. Ich vermute, dass die Bypass-Option keinen PowerShell-Netzwerkzugriff gewährt.
tödlicher Hund
1
@Belun Der referenzierte Blog-Beitrag zeigt, wie Parameter an das Skript übergeben werden.
tödlicher Hund
19

Wenn Sie aus dem aktuellen Verzeichnis ohne einen vollständig qualifizierten Pfad ausführen möchten, können Sie Folgendes verwenden:

PowerShell -NoProfile -ExecutionPolicy Bypass -Command "& './ps.ps1'"
z.B.
quelle
16

Wenn Sie eine Batchdatei ausführen, die PowerShell als Administrator aufruft, führen Sie sie besser so aus, um sich alle Probleme zu ersparen:

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

Es ist besser zu verwenden Bypass...

Wurzelschleife
quelle
3

Wenn Sie einige Skripte ausführen möchten, können Sie diese verwenden Set-executionpolicy -ExecutionPolicy Unrestrictedund anschließend zurücksetzen Set-executionpolicy -ExecutionPolicy Default.

Beachten Sie, dass die Ausführungsrichtlinie nur überprüft wird, wenn Sie ihre Ausführung starten (oder so scheint es). Sie können also Jobs im Hintergrund ausführen und die Ausführungsrichtlinie sofort zurücksetzen.

# 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
Nux
quelle
2

Eine andere einfache Möglichkeit, ein ps-Skript aus dem Stapel auszuführen, besteht darin, es einfach zwischen den Zeichen ECHO und Redirection (> und >>) einzufügen. Beispiel:

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

Letzte Zeile löscht die erstellte temporäre Datei.

Dobbelina
quelle
1

Wenn Ihr PowerShell-Anmeldeskript nach 5 Minuten (wie meines) auf einem 2012-Server ausgeführt wird, gibt es auf einem Server eine Gruppenrichtlinienobjekteinstellung: "Verzögerung des Anmeldeskripts konfigurieren". Die Standardeinstellung "Nicht konfiguriert" führt zu einer Verzögerung von 5 Minuten bevor Sie das Anmeldeskript ausführen.

Neil 11111
quelle
1

Kleine Probe test.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...
DimoN
quelle