Existe uma maneira de fazer um script do PowerShell funcionar clicando duas vezes em um arquivo .ps1?

139

Estou distribuindo um script do PowerShell para minha equipe. O script é buscar um endereço IP do cliente Vsphere, estabelecer uma conexão mstsc e registrá-lo em um arquivo compartilhado.

No momento em que usaram o script, eles conheceram o endereço IP da máquina. Depois disso, eles sempre tendem a usar o mstsc diretamente, em vez de executar o script do PowerShell. (Como eles estão usando o mstsc, não sou capaz de saber se eles estão usando a VM com frequência ou não.)

Principalmente, eles estão me dizendo que executar o PowerShell não é simples.

Estou doente por sua preguiça.

Existe uma maneira de fazer um script do PowerShell funcionar clicando duas vezes em um arquivo .ps1?

Samselvaprabu
fonte
3
Que tal usar logs no servidor? "Não confie no usuário" pode significar que você não pode confiar nele com seus dados, mas mais frequentemente significa que não confia nele para não ser preguiçoso.
Veja também howtogeek.com/204166/…
Michael Freidgeim
Compilando um script PS usando o Powershell studio sapien.com/software/powershell_studio
Root Loop
Eu prefiro executá-lo através vscode (para que eu possa ver a consola, e depurá-lo)
JinSnow

Respostas:

132

Crie um atalho com algo como este como o "Destino":

powershell.exe -command "& 'C:\A path with spaces\MyScript.ps1' -MyArguments blah"
David Brabant
fonte
3
Como Jeffery Hicks (Ele é um recurso autoritário no PowerShell) recomendou que não seja recomendável alterar as configurações, eu votaria na sua resposta como a melhor e JPBlanc como resposta útil.
Samselvaprabu
6
use isso com: `-noLogo -ExecutionPolicy unrestricted -file <path>` como respondido por: @ user3071883
Ujjwal Singh
1
@UjjwalSingh: -NoProfiletambém é útil, pois o perfil pode fazer todos os tipos de coisas que o script não espera.
Joey #
5
Para futuros leitores: Existe uma falha de registro nas respostas abaixo que realiza o que o OP solicitou. A resposta aceita não.
Wouter
2
Existe uma maneira de fazer isso, mas usando um caminho relativo / atual?
Mythofechelon
79

Ou, se quiser que todos os arquivos PS1 funcionem da maneira que os arquivos VBS, você poderá editar o registro da seguinte maneira:

HKEY_CLASSES_ROOT\Microsoft.PowerShellScript.1\Shell\open\command

Edite o valor padrão para algo mais ou menos assim ...

"C:\Windows\System32\WindowsPowerShell\v1.0\powershell.exe" -noLogo -ExecutionPolicy unrestricted -file "%1"

Depois, basta clicar duas vezes em todos os seus arquivos .PS1 como você gostaria. na minha humilde opinião, ser capaz de sair da caixa.

Vou chamar isso de "The Powershell De-castration Hack". LOL divirta-se!

user3071883
fonte
26
Este é o único que funcionou para mim nesta lista de respostas. Não estou preparado para aceitar "Não é recomendado" como resposta - digo ao PC o que fazer, o PC não me diz.
Matt
7
Este é realmente um desvio duplo. Remove a restrição do clique duplo para executar e contorna o ExecutionPolicy do PowerShell, que visa impedir a execução de scripts não confiáveis, mesmo a partir do console.
Iszi
4
Esta é a maneira errada de fazer isso. Você está alterando o que o comando "Abrir" faz em vez de definir o "Executar com o PowerShell" como padrão. Veja a resposta itgala.xyz abaixo.
Indy411
4
Se você deseja usar esse método, o valor padrão correto para a chave do Registro é realmente "C:\Windows\System32\WindowsPowerShell\v1.0\powershell.exe" -NoLogo -File "%1"%*onde você pode opcionalmente incluir o -ExecutionPolicy unrestricted. Observe a alteração no final do comando que permite que zero ou mais parâmetros sejam passados ​​para o script do PowerShell. Aspas e espaçamento entre os sinais de porcentagem devem ser exatamente como mostrado.
Glenn Slayden
2
Para uma solução de linha de comando, em vez de editar o registro, você pode digitar o ftype Microsoft.PowerShellScript.1=^"^%SystemRoot^%\System32\WindowsPowerShell\v1.0\powershell.exe^" -NoLogo -ExecutionPolicy Unrestricted -File ^"%1^" %*que realizará o mesmo.
Damian T.
21

Esteja ciente de que um dos recursos de segurança do PowerShell é que os usuários NÃO podem iniciar o script com um clique duplo. Tenha muito cuidado se você modificar essa configuração. Uma alternativa pode ser empacotar seu script. Alguns editores como o PrimalScript podem fazer isso. Os usuários ainda precisam do PowerShell instalado, mas podem clicar duas vezes no exe. E parece que sua equipe precisa de um pouco de educação.

Jeffery Hicks
fonte
3
É um recurso de segurança, porque atrasa os hackers por pelo menos alguns minutos até encontrar uma alternativa!
MarcH
23
É um recurso de segurança estúpido e inútil. Você pode executar um lote dando um duplo clique nele? Sim, um exe? Sim. Um VBScript? Sim. Não consigo perceber por que um script poweshell seria considerado mais dangrous que todos os outros
Mauro F.
12
Eu não sei sobre vocês, mas eu definitivamente corri um arquivo bat no computador errado antes com um clique duplo acidental. Com algo destinado a automatizar a administração, faz todo o sentido restringir isso.
lordcheeto 19/09/17
1
Você pode clicar duas vezes em um arquivo EXE para não ver como isso ajuda. Mas certamente a equipe do Powershell está ciente desse argumento básico. Deve haver mais do que isso.
usr
1
Se você escreve scripts que são "perigosos" para executar e não adiciona um processo básico de confirmação ... Acho que você gosta de viver perigosamente.
Romain Vincent
18

Isso funcionou para mim no Windows 10 e no PowerShell 5.1:

  • clique com o botão direito no arquivo .ps1
  • Abrir com...
  • Escolha outro aplicativo
  • Copie o local do powershell.exe na barra de endereços (por padrão, ele não mostrará a pasta do Windows), ou seja, C: \ Windows \ System32 \ WindowsPowerShell \ v1.0
  • selecione powershell.exe
  • selecione "Sempre use este aplicativo para abrir arquivos .ps1"
  • Clique OK
vizmi
fonte
2
Provavelmente você precisa diretiva de execução definida na máquina host a algo ou seja razoável RemoteSigned
vizmi
4
Isso tem vários anos e ninguém pensou nisso até meio ano atrás? - Fiz isso também e funciona perfeitamente, embora você precise fazer mais alguma configuração ou o PowerShell se recusará a executar qualquer script .ps1 (veja Set-ExecutionPolicy).
DarkWiiPlayer 02/02
Parece que o nome do script não precisa conter espaços se você quiser que isso funcione. Fora isso, parece funcionar perfeitamente.
Lucas
2
Como essa não é a resposta mais votada? Por que editaríamos o registro diretamente ou usaríamos arquivos em lote quando você pode fazer da maneira que o Windows pretendia, através de associações de arquivos?
Dr. Kickass 16/01
@ Dr.Kickass É provavelmente uma das respostas mais recentes, eu acho
vizmi
17

Escrevi isso há alguns anos (execute-o com direitos de administrador):

<#
.SYNOPSIS
    Change the registry key in order that double-clicking on a file with .PS1 extension
    start its execution with PowerShell.
.DESCRIPTION
    This operation bring (partly) .PS1 files to the level of .VBS as far as execution
    through Explorer.exe is concern.
    This operation is not advised by Microsoft.
.NOTES
    File Name   : ModifyExplorer.ps1
    Author      : J.P. Blanc - jean-paul_blanc@silogix-fr.com
    Prerequisite: PowerShell V2 on Vista and later versions.
    Copyright 2010 - Jean Paul Blanc/Silogix
.LINK
    Script posted on:
    http://www.silogix.fr
.EXAMPLE
    PS C:\silogix> Set-PowAsDefault -On
    Call Powershell for .PS1 files.
    Done!
.EXAMPLE
    PS C:\silogix> Set-PowAsDefault
    Tries to go back
    Done!
#>
function Set-PowAsDefault
{
  [CmdletBinding()]
  Param
  (
    [Parameter(mandatory=$false, ValueFromPipeline=$false)]
    [Alias("Active")]
    [switch]
    [bool]$On
  )

  begin
  {
    if ($On.IsPresent)
    {
      Write-Host "Call PowerShell for .PS1 files."
    }
    else
    {
      Write-Host "Try to go back."
    }
  }

  Process
  {
    # Text Menu
    [string]$TexteMenu = "Go inside PowerShell"

    # Text of the program to create
    [string] $TexteCommande = "%systemroot%\system32\WindowsPowerShell\v1.0\powershell.exe -Command ""&'%1'"""

    # Key to create
    [String] $clefAModifier = "HKLM:\SOFTWARE\Classes\Microsoft.PowerShellScript.1\Shell\Open\Command"

    try
    {
      $oldCmdKey = $null
      $oldCmdKey = Get-Item $clefAModifier -ErrorAction SilentlyContinue
      $oldCmdValue = $oldCmdKey.getvalue("")

      if ($oldCmdValue -ne $null)
      {
        if ($On.IsPresent)
        {
          $slxOldValue = $null
          $slxOldValue = Get-ItemProperty $clefAModifier -Name "slxOldValue" -ErrorAction SilentlyContinue
          if ($slxOldValue -eq $null)
          {
            New-ItemProperty $clefAModifier -Name "slxOldValue" -Value $oldCmdValue  -PropertyType "String" | Out-Null
            New-ItemProperty $clefAModifier -Name "(default)" -Value $TexteCommande  -PropertyType "ExpandString" | Out-Null
            Write-Host "Done !"
          }
          else
          {
            Write-Host "Already done!"
          }
        }
        else
        {
          $slxOldValue = $null
          $slxOldValue = Get-ItemProperty $clefAModifier -Name "slxOldValue" -ErrorAction SilentlyContinue
          if ($slxOldValue -ne $null)
          {
            New-ItemProperty $clefAModifier -Name "(default)" -Value $slxOldValue."slxOldValue"  -PropertyType "String" | Out-Null
            Remove-ItemProperty $clefAModifier -Name "slxOldValue"
            Write-Host "Done!"
          }
          else
          {
            Write-Host "No former value!"
          }
        }
      }
    }
    catch
    {
      $_.exception.message
    }
  }
  end {}
}
JPBlanc
fonte
2
Eu tive que alterá-lo neste local para que funcionasse: Computer \ HKEY_CLASSES_ROOT \ Applications \ powershell.exe \ Shell \ Open \ Command. Não entendo o registro o suficiente para explicar por que isso acontece. Talvez porque eu esteja executando o Powershell 3.0? De qualquer forma, obrigado pelo script.
Wouter
15

Você precisará ajustar o registro. Primeiro, configure um PSDrive para HKEY_CLASSES_ROOT, pois isso não é configurado por padrão. O comando para isso é:

New-PSDrive HKCR Registry HKEY_CLASSES_ROOT

Agora você pode navegar e editar as chaves e os valores do Registro em HKEY_CLASSES_ROOT, como faria nos PSDrives HKCU e HKLM regulares.

Para configurar o clique duplo para iniciar os scripts do PowerShell diretamente:

Set-ItemProperty HKCR:\Microsoft.PowerShellScript.1\Shell '(Default)' 0

Para configurar o clique duplo para abrir os scripts do PowerShell no PowerShell ISE:

Set-ItemProperty HKCR:\Microsoft.PowerShellScript.1\Shell '(Default)' 'Edit'

Para restaurar o valor padrão (define clique duplo para abrir scripts do PowerShell no bloco de notas):

Set-ItemProperty HKCR:\Microsoft.PowerShellScript.1\Shell '(Default)' 'Open'
Alex Langer
fonte
Tentei restaurar o valor padrão usando a última linha de um Elevated PowerShell ISE, mas, aparentemente, se você usou um comando como o Thermionix descrito, ele substitui o padrão, então é necessário redefinir o comando Shell.com explicitamente (mas não encontrei o sintaxe correta para isso, então tive que passar pelo Painel de controle> Programas> Associações de arquivos).
precisa saber é o seguinte
13

Concordo que definir uma configuração do sistema pode ser um pouco demais, mas o atalho que requer um caminho codificado não é o ideal. Um arquivo bat resolve realmente o problema

RunMyPowershellScript.bat

 start powershell -command "& '.\MyPowershellScript.ps1' -MyArguments blah"

Agora, esse arquivo em lote pode ser clicado duas vezes, os atalhos podem ser facilmente criados para o arquivo em lotes e o script pode ser implantado em qualquer pasta.

Rick
fonte
Observe que você precisa do script ps1 na mesma pasta que o arquivo bat. Você ganha a capacidade de copiar e colar com o custo de manter 2 arquivos.
precisa saber é
11

Comandos simples do PowerShell para definir isso no registro;

New-PSDrive -Name HKCR -PSProvider Registry -Root HKEY_CLASSES_ROOT
Set-ItemProperty -Path "HKCR:\Microsoft.PowerShellScript.1\Shell\open\command" -name '(Default)' -Value '"C:\Windows\System32\WindowsPowerShell\v1.0\powershell.exe" -noLogo -ExecutionPolicy unrestricted -file "%1"'
Thermionix
fonte
5
Para um pouco mais de segurança, sugiro usar ExecutionPolicy RemoteSignedum script aleatório baixado da rede / internet (com os metadados indicando que não foi criado localmente) não será executado com um clique duplo, mas qualquer arquivo criado por cópia e colar o código em um arquivo .ps1 será executado porque não possui esses metadados associados.
precisa saber é o seguinte
6
  1. Navegue REGEDIT para HKEY_LOCAL_MACHINE \ SOFTWARE \ Classes \ Microsoft.PowerShellScript.1 \ Shell
  2. No painel direito, clique duas vezes em "(Padrão)"
  3. Exclua o valor existente de "Abrir" (que inicia o Bloco de notas) e digite "0" (sendo zero, que inicia o Powershell diretamente).

Reverta o valor se desejar usar o Bloco de notas como padrão novamente.

gth
fonte
5

Você pode definir a associação padrão dos ps1arquivos para powershell.exepermitir que você execute um script do PowerShell clicando duas vezes nele.

No Windows 10,

  1. Clique com o botão direito do mouse em um ps1arquivo
  2. Clique Open with
  3. Clique Choose another app
  4. Na janela pop-up, selecione More apps
  5. Role para baixo e selecione Look for another app on this PC.
  6. Navegue até e selecione C:\Windows\System32\WindowsPowerShell\v1.0\powershell.exe.
  7. Item da lista

Isso mudará a associação e os ps1arquivos serão executados clicando duas vezes neles. Você pode alterá-lo de volta ao seu comportamento padrão, definindo notepad.exeo aplicativo padrão.

Fonte

elBradford
fonte
1
Isso funciona bem, mas praticamente duplica a resposta do vizmi.
Marteng 11/09/18
4

coloque um arquivo .cmd simples na minha subpasta com o meu arquivo .ps1 com o mesmo nome; portanto, por exemplo, um script chamado "foobar" teria "foobar.ps1" e "foobar.cmd". Portanto, para executar o .ps1, tudo o que preciso fazer é clicar no arquivo .cmd do explorer ou executar o .cmd em um prompt de comando. Eu uso o mesmo nome base, porque o arquivo .cmd procurará automaticamente o .ps1 usando seu próprio nome.

::====================================================================
:: Powershell script launcher
::=====================================================================
:MAIN
    @echo off
    for /f "tokens=*" %%p in ("%~p0") do set SCRIPT_PATH=%%p
    pushd "%SCRIPT_PATH%"

    powershell.exe -sta -c "& {.\%~n0.ps1 %*}"

    popd
    set SCRIPT_PATH=
    pause

O pushd / popd permite iniciar o arquivo .cmd a partir de um prompt de comandos sem precisar mudar para o diretório específico em que os scripts estão localizados. Ele será alterado para o diretório do script e, quando terminar, volte para o diretório original.

Você também pode interromper a pausa se desejar que a janela de comando desapareça quando o script terminar.

Se meu script .ps1 tiver parâmetros, eu os solicito com solicitações da GUI usando o .NET Forms, mas também os flexibilizo o suficiente para aceitar parâmetros, se eu quiser passar por eles. Dessa forma, basta clicar duas vezes no Explorer e não precisar conhecer os detalhes dos parâmetros, pois ele me pedirá o que eu preciso, com caixas de listagem ou outros formulários.

KoZm0kNoT
fonte
2
Obrigado pelo arquivo em lote. Só para você saber, você pode substituir a instrução "for" por apenas: "set SCRIPT_PATH =% ~ p0" (sem aspas). De fato, eu usaria ~ dp0 em vez de ~ p0, para que funcione em todas as unidades. Eu vou usar isso sozinho.
Zumalifeguard 12/06
2

Isso é baseado na resposta de KoZm0kNoT. Eu o modifiquei para funcionar entre unidades.

@echo off
pushd "%~d0"
pushd "%~dp0"
powershell.exe -sta -c "& {.\%~n0.ps1 %*}"
popd
popd

Os dois pushd / popds são necessários caso o cwd do usuário esteja em uma unidade diferente. Sem o conjunto externo, o cwd na unidade com o script será perdido.

zumalifeguard
fonte
2

É isso que eu uso para que os scripts sejam executados como administrador por padrão:

Powershell.exe -Command "& {Start-Process PowerShell.exe -Verb RunAs -ArgumentList '-File """%1"""'}"

Você precisará colar isso no regedit como o valor padrão para:

HKEY_CLASSES_ROOT\Microsoft.PowerShellScript.1\Shell\Open\Command

Ou aqui está um script que fará isso por você:

$hive = [Microsoft.Win32.RegistryKey]::OpenBaseKey('ClassesRoot', 'Default')
$key = $hive.CreateSubKey('Microsoft.PowerShellScript.1\Shell\Open\Command')
$key.SetValue($null, 'Powershell.exe -Command "& {Start-Process PowerShell.exe -Verb RunAs -ArgumentList ''-File """%1"""''}"')
Mica
fonte
2

Se você estiver familiarizado com a administração avançada do Windows, poderá usar este pacote ADM (instruções estão incluídas nessa página) e permitir a execução de scripts do PowerShell após clicar duas vezes nesse modelo e no GPO local. Depois disso, você pode simplesmente alterar o programa padrão associado ao tipo de arquivo .ps1 para powershell.exe(usar a pesquisa, está bem escondido) e estará pronto para executar os scripts do PowerShell com um clique duplo.

Caso contrário, eu recomendaria seguir outras sugestões, pois você pode atrapalhar todo o sistema com essas ferramentas administrativas.

Eu acho que as configurações padrão são muito rigorosas. Se alguém conseguir colocar algum código malicioso no seu computador, ele também poderá ignorar essa restrição (envolva-a em arquivo .cmd ou .exe ou truque com atalho) e tudo o que conseguirá no final é apenas para evitar você de maneira fácil de executar o script que você escreveu.

Jirrick
fonte
Depois de instalada, você pode encontrar essa configuração no "Editor de Diretiva de Grupo Local" em: Diretiva do Computador Local -> Configuração do Computador -> Modelos Administrativos -> Componentes do Windows. Lá, você pode habilitá-lo e certifique-se de selecionar uma política na lista suspensa que será ativada então.
Wouter
1

Você pode usar a funcionalidade 'SendTo' do Windows para facilitar a execução de scripts PS1. Usando esse método, você pode clicar com o botão direito do mouse em um script PS1 e executar. Isso não responde exatamente à pergunta do OP, mas está próxima. Felizmente, isso é útil para outros. Entre. Isso é útil para uma variedade de outras tarefas.

  • Localize / pesquise Powershell.exe
  • Clique com o botão direito do mouse em Powershell.exe e escolha Abrir local do arquivo
  • Clique com o botão direito do mouse em Powershell.exe e escolha Criar atalho. Salve temporariamente algum lugar como sua área de trabalho
  • Você pode abrir como administrador por padrão. Selecione Atalho> Propriedades> Avançado> Abrir como administrador
  • Abra a pasta Sendto. Iniciar> Executar> Shell: Sendto
  • Mova o atalho Powershell.exe para a pasta Sendto
  • Agora você deve conseguir clicar com o botão direito do mouse em um script PS1.
  • Clique com o botão direito do mouse em um arquivo PS1, selecione a opção de contexto SendTo> Selecione o atalho do PowerShell
  • Seu script PS1 deve ser executado.
MrRobot
fonte
1
Como isso é melhor do que a opção padrão do menu de contexto 'Executar com o PowerShell'?
9788 elBradford
1

Eu usei isso (preciso executá-lo apenas uma vez); Também verifique se você tem direitos para executar:

do PowerShell com direitos elevados:

Set-ExecutionPolicy=RemoteSigned

então a partir de um arquivo bat:

-----------------------------------------

 ftype Microsoft.PowerShellScript.1="C:\WINDOWS\system32\windowspowershell\v1.0\powershell.exe" -noexit ^&'%%1'

 assoc .ps1=Microsoft.PowerShellScript.1

-----------------------------------------
auto exit: remove -noexit 

e voila; clicar duas vezes em um * .ps1 o executará.

Paul Fijma
fonte
The term '%1' is not recognized as the name of a cmdlet, function, script file, or operable program. Check the spelling of the name, or if a path was included, verify that the path is correct and try again.
ajeh
Somente a combinação da resposta aceita com essa resposta funcionou para mim, uma vez que usei o comando da resposta aceita na chave do registro. Aparentemente, assocé necessário executar .
ajeh
@ajeh (desculpe pelo bieng leet para a parte. Se você receber esse erro, é porque você tem as aspas simples erradas. certifique-se de usar UTF-8. (use o bloco de notas ++; solte as duas strings, salve como um arquivo runme.cmd )
Paul Fijma
1

No Windows 10, você também pode excluir a substituição do Windows Explorer para associação de extensão de arquivo:

HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Explorer\FileExts\.ps1\UserChoice

além da HKEY_CLASSES_ROOT\Microsoft.PowerShellScript.1\Shell\open\commandalteração mencionada em outras respostas.

Consulte https://stackoverflow.com/a/2697804/1360907

Chris Xue
fonte
1

Tentei as principais respostas a esta pergunta, mas encontrei mensagens de erro. Então eu encontrei a resposta aqui:

O PowerShell diz que "a execução de scripts está desabilitada neste sistema".

O que funcionou bem para mim foi usar esta solução:

powershell -ExecutionPolicy Bypass -File script.ps1

Você pode colar isso em um arquivo .bat e clicar duas vezes nele.

Francis
fonte