Come eseguire uno script PowerShell da un file batch


197

Sto cercando di eseguire questo script in PowerShell. Ho salvato lo script seguente come ps.ps1sul mio desktop.

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

Ho creato uno script batch per eseguire questo script PowerShell

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

Ma sto ricevendo questo errore:

Inserisci qui la descrizione dell'immagine

Risposte:


267

È necessario il -ExecutionPolicyparametro:

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

Altrimenti PowerShell considera gli argomenti una riga da eseguire e sebbene Set-ExecutionPolicy sia un cmdlet, non ha -Fileparametri.


2
@joey ha funzionato grazie..ma dopo aver eseguito il file bat ho ricevuto questo errore "Avvertenza: la colonna" comando "non si adatta al display ed è stata rimossa"
Eka,

Questo è un avvertimento, non un errore. E più di un argomento per un'altra domanda.
Joey,

@joey è saggio scrivere un'altra domanda nello stack.SE per questo avviso minore?
Eka,

2
@Joey Haha, così efficacemente puoi ignorare questa politica senza essere un amministratore. È un problema di sicurezza?
Kolob Canyon,

2
@KolobCanyon: se sei in una posizione in cui puoi eseguire PowerShell, puoi fare praticamente tutto il resto. Si noti che la politica di esecuzione non significa che PowerShell abbia più privilegi di quanto avrebbe altrimenti. In un certo senso è semplicemente una comodità evitare di eseguire accidentalmente cose che potresti non voler eseguire. Simile a dover precedere i comandi nella directory corrente con ./e avere un flag eseguibile su Unix.
Joey,

117

Spiego sia il motivo per cui si vorrebbe chiamare uno script PowerShell da un file batch sia come farlo nel mio post sul blog qui .

Questo è fondamentalmente quello che stai cercando:

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

E se devi eseguire lo script di PowerShell come amministratore, usa questo:

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

Invece di codificare a fondo l'intero percorso dello script di PowerShell, consiglio di posizionare il file batch e il file di script di PowerShell nella stessa directory, come descritto nel mio post sul blog.


Invoke-WebRequest funziona correttamente quando scrivo la riga di comando in una finestra cmd, ma restituisce un 404 ogni volta che lo eseguo da un file batch. Sto provando 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}";o powershell -Command "Invoke-WebRequest https://www.example.com/example.ics -OutFile c:\_my\file.ics", o usando l'opzione -File per lo stesso in un file .ps1, o (New-Object Net.WebClient).DownloadFile. Qualche idea?
Chris,

Prova a usare -ExecutionPolicy Unrestricted. Immagino che l'opzione Bypass non dia accesso alla rete PowerShell.
cane mortale,

1
@Belun Il post sul blog di riferimento mostra come passare i parametri allo script.
cane mortale,

19

Se si desidera eseguire dalla directory corrente senza un percorso completo, è possibile utilizzare:

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

16

Se esegui un file batch che chiama PowerShell come amministratore, è meglio eseguirlo in questo modo, risparmiando tutti i problemi:

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

È meglio usare Bypass...


3

Se si desidera eseguire alcuni script, è possibile utilizzare Set-executionpolicy -ExecutionPolicy Unrestrictede ripristinare con Set-executionpolicy -ExecutionPolicy Default.

Si noti che la politica di esecuzione viene verificata solo quando si avvia la sua esecuzione (o almeno così sembra) e quindi è possibile eseguire processi in background e reimpostare immediatamente la politica di esecuzione.

# 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

Un altro modo semplice per eseguire uno script ps da batch è semplicemente incorporarlo tra i caratteri ECHO e Redirection, (> e >>), ad esempio:

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

L'ultima riga elimina il file temporaneo creato.


1

Se lo script di accesso di PowerShell è in esecuzione dopo 5 minuti (come lo era il mio) su un server 2012, è presente un'impostazione oggetto Criteri di gruppo su un server: "Configura ritardo script di accesso", l'impostazione predefinita "non configurato", ciò lascerà un ritardo di 5 minuti prima di eseguire lo script di accesso.


1

Piccolo campione 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...
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.