Como executar um script do PowerShell a partir de um arquivo em lotes

196

Estou tentando executar este script no PowerShell. Salvei o script abaixo como ps.ps1na minha área de trabalho.

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

Eu criei um script em lote para executar esse script do PowerShell

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

Mas estou recebendo este erro:

Digite a descrição da imagem aqui

Eka
fonte

Respostas:

266

Você precisa do -ExecutionPolicyparâmetro:

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

Caso contrário, o PowerShell considera os argumentos uma linha para executar e, embora Set-ExecutionPolicy seja um cmdlet, não possui -Fileparâmetro.

Joey
fonte
2
@ joey funcionou obrigado .. mas depois de executar o arquivo bat, recebi este erro "Waring: column 'command' não se encaixa na tela e foi removido"
Eka
Isso é um aviso, não um erro. E mais um assunto para outra pergunta.
Joey #
@joey é prudente escrever outra pergunta na stack.SE para este aviso menor?
Eka
2
@ Joey Haha, tão efetivamente você pode substituir esta política sem ser um administrador. Isso é um problema de segurança?
Kolob Canyon
2
@KolobCanyon: Se você estiver em uma posição em que pode executar o PowerShell, poderá fazer praticamente tudo o resto. Observe que a política de execução não significa que o PowerShell tenha mais privilégios do que teria de outra forma. De certa forma, é apenas uma conveniência evitar a execução acidental de coisas que talvez você não queira. É semelhante ao prefixo de comandos no diretório atual ./e com um sinalizador executável no Unix.
Joey
117

Explico por que você deseja chamar um script do PowerShell a partir de um arquivo em lotes e como fazê-lo na minha postagem no blog aqui .

Isto é basicamente o que você está procurando:

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

E se você precisar executar o script do PowerShell como administrador, use o seguinte:

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

Em vez de codificar o caminho inteiro para o script do PowerShell, recomendo colocar o arquivo em lotes e o arquivo de script do PowerShell no mesmo diretório, como descreve a postagem do meu blog.

cão mortal
fonte
Invoke-WebRequest está funcionando bem quando digito a linha de comando em uma janela de cmd, mas retorna um 404 sempre que eu o executo em um arquivo em lotes. Estou tentando 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}";ou powershell -Command "Invoke-WebRequest https://www.example.com/example.ics -OutFile c:\_my\file.ics", ou usando a opção -File para o mesmo em um arquivo .ps1 ou (New-Object Net.WebClient).DownloadFile. Alguma ideia?
7284 Chris
Tente usar -ExecutionPolicy Unrestricted. Suponho que a opção Ignorar não dê acesso à rede do PowerShell.
deadlydog
1
@Belun A postagem de blog referenciada mostra como passar parâmetros para o script.
deadlydog
19

Se você deseja executar a partir do diretório atual sem um caminho completo, você pode usar:

PowerShell -NoProfile -ExecutionPolicy Bypass -Command "& './ps.ps1'"
por exemplo
fonte
16

Se você executar um arquivo em lotes chamando o PowerShell como administrador, é melhor executá-lo assim, poupando todo o problema:

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

É melhor usar Bypass...

Loop de raiz
fonte
3

Se você quiser executar alguns scripts, poderá usar Set-executionpolicy -ExecutionPolicy Unrestrictede redefinir com Set-executionpolicy -ExecutionPolicy Default.

Observe que a política de execução só é verificada quando você inicia sua execução (ou pelo que parece) e, portanto, é possível executar tarefas em segundo plano e redefinir a política de execução imediatamente.

# 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
fonte
2

Outra maneira fácil de executar um script ps do lote é simplesmente incorporá-lo entre os caracteres ECHO e Redirection, (> e >>), exemplo:

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

A última linha exclui o arquivo temporário criado.

Dobbelina
fonte
1

Se o script de logon do PowerShell estiver em execução após 5 minutos (como o meu) em um servidor de 2012, haverá uma configuração de GPO em um servidor - 'Configurar Atraso do Script de Logon', a configuração padrão 'não configurada', isso deixará um atraso de 5 minutos antes de executar o script de login.

Neil 11111
fonte
1

Amostra pequena 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
fonte