¿Hay alguna manera de hacer que un script de PowerShell funcione haciendo doble clic en un archivo .ps1?

139

Estoy distribuyendo un script de PowerShell a mi equipo. La secuencia de comandos es buscar una dirección IP del cliente Vsphere, establecer una conexión mstsc e iniciar sesión en un archivo compartido.

En el momento en que usaron el script, llegaron a conocer la dirección IP de la máquina. Después de eso, siempre tienden a usar mstsc directamente en lugar de ejecutar el script de PowerShell. (Como están usando mstsc, no puedo saber si están usando la VM con frecuencia o no).

Principalmente me dicen que ejecutar PowerShell no es sencillo.

Estoy enfermo por su pereza.

¿Hay alguna manera de hacer que un script de PowerShell funcione haciendo doble clic en un archivo .ps1?

Samselvaprabu
fuente
3
¿Qué tal el uso de registros en el servidor? "No confíes en el usuario" puede significar que no puedes confiar en él con tus datos, pero más a menudo significa que no confíes en él para no ser flojo.
Ver también howtogeek.com/204166/…
Michael Freidgeim
Compilación de un script PS utilizando Powershell studio sapien.com/software/powershell_studio
Root Loop
Prefiero ejecutarlo a través de vscode (para poder ver el consol y depurarlo)
JinSnow

Respuestas:

132

Cree un acceso directo con algo como esto como "Destino":

powershell.exe -command "& 'C:\A path with spaces\MyScript.ps1' -MyArguments blah"
David Brabant
fuente
3
Como Jeffery Hicks (Él es un recurso autorizado en powershell) informó que no se recomienda cambiar la configuración, votaría su respuesta es la mejor respuesta y la respuesta de JPBlanc como respuesta útil.
Samselvaprabu
66
use esto con: `-noLogo -ExecutionPolicy sin restricciones -file <path>` como respondió: @ user3071883
Ujjwal Singh
1
@UjjwalSingh: -NoProfiletambién es útil, ya que el perfil puede hacer todo tipo de cosas que el script no espera.
Joey
55
Para futuros lectores: hay un hack de registro en las respuestas a continuación que logra lo que OP solicitó. La respuesta aceptada no.
Wouter
2
¿Hay alguna manera de hacer esto pero usando una ruta relativa / actual?
mythofechelon
79

O si desea que todos los archivos de PS1 funcionen como lo hacen los archivos VBS, puede editar el registro de esta manera:

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

Edite el valor predeterminado para que sea algo así ...

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

Luego puede hacer doble clic en todos sus archivos .PS1 como le gustaría. en mi humilde opinión, poder salir de la caja.

Voy a llamar a esto "The Powershell De-castration Hack". LOL disfruta!

usuario3071883
fuente
27
Este es el único que funcionó para mí en esta lista de respuestas. No estoy preparado para aceptar "No se aconseja" como respuesta: le digo a la PC qué hacer, la PC no me lo dice.
Matt
77
Esto es en realidad un doble bypass. Elimina la restricción contra doble clic para ejecutar, y evita la ExecutionPolicy de PowerShell, que está destinada a evitar la ejecución de scripts no confiables incluso desde la consola.
Iszi
44
Esta es la forma incorrecta de hacerlo. Estás cambiando lo que hace el comando "Abrir" en lugar de configurar "Ejecutar con PowerShell" como predeterminado. Ver itgala.xyz respuesta a continuación.
Indy411
44
Si desea utilizar este método, el valor predeterminado correcto para la clave de registro es "C:\Windows\System32\WindowsPowerShell\v1.0\powershell.exe" -NoLogo -File "%1"%*donde puede incluir opcionalmente el -ExecutionPolicy unrestricted. Tenga en cuenta el cambio al final del comando que permite pasar cero o más parámetros al script de PowerShell. Las comillas y el espacio alrededor de los signos de porcentaje deben ser exactamente como se muestran.
Glenn Slayden
2
Para una solución de línea de comandos en lugar de editar el registro, puede escribir lo ftype Microsoft.PowerShellScript.1=^"^%SystemRoot^%\System32\WindowsPowerShell\v1.0\powershell.exe^" -NoLogo -ExecutionPolicy Unrestricted -File ^"%1^" %*que logrará lo mismo.
Damian T.
21

Tenga en cuenta que una de las características de seguridad de PowerShell es que los usuarios NO pueden iniciar secuencias de comandos con un doble clic. Tenga mucho cuidado si modifica esta configuración. Una alternativa podría ser empaquetar su script. Algunos editores como PrimalScript pueden hacer eso. Los usuarios aún necesitan instalar PowerShell, pero luego pueden hacer doble clic en el archivo exe. Y parece que su equipo necesita un poco de educación.

Jeffery Hicks
fuente
3
¡Es una característica de seguridad porque retrasa a los hackers al menos unos minutos hasta que encuentren una alternativa!
MarcH
23
Es una característica de seguridad estúpida e inútil. ¿Se puede ejecutar un lote haciendo doble clic en él? Sí, un exe? Si. ¿Un VBScript? Si. No me doy cuenta de por qué un script de Poweshell se consideraría más peligroso que todos los demás
Mauro F.
12
No sé ustedes, pero definitivamente he ejecutado un archivo bat en la computadora incorrecta antes con un doble clic accidental. Con algo destinado a automatizar la administración, tiene mucho sentido restringir eso.
lordcheeto
1
Puede hacer doble clic en un archivo EXE, así que no veo cómo esto ayuda. Pero seguramente el equipo de Powershell es consciente de este argumento básico. Debe haber más que eso.
Usr
1
Si escribe secuencias de comandos que son "peligrosas" de ejecutar, y no agrega un proceso de confirmación básico ... Creo que le gusta vivir peligrosamente.
Romain Vincent
18

Esto funcionó para mí en Windows 10 y powershell 5.1:

  • haga clic derecho en el archivo .ps1
  • Abrir con...
  • Elige otra aplicación
  • Copie la ubicación de powershell.exe en la barra de direcciones (de forma predeterminada, no mostrará la carpeta de Windows), es decir, C: \ Windows \ System32 \ WindowsPowerShell \ v1.0
  • seleccione powershell.exe
  • seleccione "Usar siempre esta aplicación para abrir archivos .ps1"
  • haga clic en Aceptar
vizmi
fuente
2
Probablemente lo que necesita para establecer la política de ejecución en el ordenador central a algo razonable decir RemoteSigned
vizmi
44
¿Esto tiene varios años y nadie ha pensado en esto hasta hace medio año? - También hice esto y funciona perfectamente, aunque tienes que hacer una configuración más o PowerShell se negará a ejecutar ningún script .ps1 (ver Set-ExecutionPolicy).
DarkWiiPlayer
Parece que el nombre del script no debe contener espacios si desea que esto funcione. Aparte de eso, parece funcionar perfectamente.
Lucas
2
¿Cómo es que esta no es la respuesta más votada? ¿Por qué deberíamos editar el registro directamente o usar archivos por lotes cuando puede hacerlo de la manera prevista por Windows, a través de asociaciones de archivos?
Dr. Kickass
@ Dr.Kickass Probablemente sea una de las respuestas más nuevas, supongo
vizmi
17

Escribí esto hace unos años (ejecútelo con derechos 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
fuente
2
Tuve que cambiarlo en esta ubicación para que funcione: Computer \ HKEY_CLASSES_ROOT \ Applications \ powershell.exe \ Shell \ Open \ Command. No entiendo el registro lo suficiente como para explicar por qué es esto. ¿Tal vez porque estoy ejecutando Powershell 3.0? De todos modos, gracias por el guión.
Wouter
15

Tendrá que ajustar el registro. Primero, configure un PSDrive para HKEY_CLASSES_ROOT ya que esto no está configurado de manera predeterminada. El comando para esto es:

New-PSDrive HKCR Registry HKEY_CLASSES_ROOT

Ahora puede navegar y editar claves y valores de registro en HKEY_CLASSES_ROOT tal como lo haría en los HKDU y HKLM PSDrives normales.

Para configurar hacer doble clic para iniciar scripts de PowerShell directamente:

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

Para configurar hacer doble clic para abrir los scripts de PowerShell en el ISE de PowerShell:

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

Para restaurar el valor predeterminado (establece doble clic para abrir los scripts de PowerShell en el Bloc de notas):

Set-ItemProperty HKCR:\Microsoft.PowerShellScript.1\Shell '(Default)' 'Open'
Alex Langer
fuente
Intenté restaurar el valor predeterminado utilizando la última línea de un ISE Elevated PowerShell, pero aparentemente si ha utilizado un comando como el que describe Thermionix, reemplaza el valor predeterminado, por lo que debe restablecer el comando Shell.com explícitamente (pero no he encontrado el sintaxis correcta para eso, así que tuve que pasar por el Panel de control> Programas> Asociaciones de archivos).
dragon788
13

Estoy de acuerdo en que establecer una configuración del sistema puede ser demasiado, pero el acceso directo que requiere una ruta codificada no es ideal. Un archivo bat realmente resuelve bien el problema

RunMyPowershellScript.bat

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

Ahora se puede hacer doble clic en este archivo por lotes, se pueden crear accesos directos fácilmente al archivo por lotes y el script se puede implementar en cualquier carpeta.

Almiar
fuente
Tenga en cuenta que necesita el script ps1 en la misma carpeta que el archivo bat. Obtiene la capacidad de copiar y pegar a costa de mantener 2 archivos.
jiggunjer
11

Comandos simples de PowerShell para configurar esto en el 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
fuente
55
Para un poco más de seguridad, sugeriría usarlo ExecutionPolicy RemoteSignedpara que un script aleatorio descargado de la red / internet (con los metadatos que denotan que no se creó localmente) no se ejecute con un doble clic, pero cualquier archivo que haya creado por copia y pegar código en un archivo .ps1 se ejecutará porque no tiene esos metadatos asociados.
dragon788
6
  1. Navegue REGEDIT a HKEY_LOCAL_MACHINE \ SOFTWARE \ Classes \ Microsoft.PowerShellScript.1 \ Shell
  2. En el panel derecho, haga doble clic en "(Predeterminado)"
  3. Elimine el valor existente de "Abrir" (que inicia el Bloc de notas) y escriba "0" (siendo cero, que inicia Powershell directamente).

Revierta el valor si desea volver a usar el Bloc de notas como predeterminado.

gth
fuente
5

Puede configurar la asociación de ps1archivos predeterminada para powershell.exeque le permita ejecutar un script de PowerShell haciendo doble clic en él.

En Windows 10

  1. Haga clic derecho en un ps1archivo
  2. Hacer clic Open with
  3. Hacer clic Choose another app
  4. En la ventana emergente, seleccione More apps
  5. Desplácese hasta la parte inferior y seleccione Look for another app on this PC.
  6. Busque y seleccione C:\Windows\System32\WindowsPowerShell\v1.0\powershell.exe.
  7. Elemento de la lista

Eso cambiará la asociación de ps1archivos y los archivos se ejecutarán haciendo doble clic en ellos. Puede volver a cambiar su comportamiento predeterminado configurando notepad.exela aplicación predeterminada.

Fuente

elBradford
fuente
1
Esto funciona bien pero casi duplica la respuesta de vizmi.
Marteng
4

poner un archivo .cmd simple en mi subcarpeta con mi archivo .ps1 con el mismo nombre, por lo que, por ejemplo, un script llamado "foobar" tendría "foobar.ps1" y "foobar.cmd". Entonces, para ejecutar el .ps1, todo lo que tengo que hacer es hacer clic en el archivo .cmd desde el explorador o ejecutar el .cmd desde el símbolo del sistema. Uso el mismo nombre base porque el archivo .cmd buscará automáticamente el .ps1 usando su propio nombre.

::====================================================================
:: 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

Pushd / popd le permite iniciar el archivo .cmd desde el símbolo del sistema sin tener que cambiar al directorio específico donde se encuentran los scripts. Cambiará al directorio de secuencia de comandos y, cuando finalice, vuelva al directorio original.

También puede detener la pausa si desea que la ventana de comandos desaparezca cuando finalice el script.

Si mi script .ps1 tiene parámetros, los solicito con avisos de GUI usando .NET Forms, pero también hago que los scripts sean lo suficientemente flexibles como para aceptar parámetros si quiero pasarlos. De esta manera, puedo hacer doble clic en el Explorador y no tener que conocer los detalles de los parámetros, ya que me pedirá lo que necesito, con cuadros de lista u otros formularios.

KoZm0kNoT
fuente
2
Gracias por el archivo por lotes. Para que lo sepas, puedes reemplazar la declaración "for" con solo: "set SCRIPT_PATH =% ~ p0" (sin comillas). De hecho, usaría ~ dp0 en lugar de ~ p0 para que funcione en todas las unidades. Lo usaré yo mismo.
zumalifeguard
2

Esto se basa en la respuesta de KoZm0kNoT. Lo modifiqué para que funcione en todas las unidades.

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

Los dos pushd / popds son necesarios en caso de que el cwd del usuario se encuentre en una unidad diferente. Sin el conjunto externo, el cwd en la unidad con el script se perderá.

zumalifeguard
fuente
2

Esto es lo que uso para que las secuencias de comandos se ejecuten como administrador de forma predeterminada:

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

Deberá pegarlo en regedit como el valor predeterminado para:

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

O aquí hay un script que lo hará por usted:

$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
fuente
2

Si está familiarizado con la administración avanzada de Windows, puede usar este paquete ADM (las instrucciones se incluyen en esa página) y permitir la ejecución de scripts de PowerShell después de hacer doble clic a través de esta plantilla y el GPO local. Después de esto, simplemente puede cambiar el programa predeterminado asociado al tipo de archivo .ps1 a powershell.exe(use search, está bastante oculto) y estará listo para ejecutar scripts de PowerShell con doble clic.

De lo contrario, recomendaría seguir con otras sugerencias, ya que puede arruinar todo el sistema con estas herramientas de administración.

Creo que la configuración predeterminada es demasiado estricta. Si alguien logra poner un código malicioso en su computadora, entonces él / ella también puede eludir esta restricción (envolverla en un archivo .cmd o .exe, o truco con acceso directo) y todo lo que al final logra es solo evitar usted de manera fácil de ejecutar el script que ha escrito.

Jirrick
fuente
Una vez instalado, puede encontrar esta configuración en el "Editor de políticas de grupo local" en: Política de computadora local -> Configuración de la computadora -> Plantillas administrativas -> Componentes de Windows. Allí, puede habilitarlo y asegurarse de seleccionar una política en la lista desplegable que se habilita en ese momento.
Wouter
1

Puede usar la funcionalidad 'SendTo' de Windows para facilitar la ejecución de scripts de PS1. Con este método, puede hacer clic derecho en un script de PS1 y ejecutar. Esto no responde exactamente la pregunta de OP pero está cerca. Con suerte, esto es útil para otros. Por cierto ... esto es útil para una variedad de otras tareas.

  • Localizar / Buscar Powershell.exe
  • Haga clic derecho en Powershell.exe y elija Abrir ubicación de archivo
  • Haga clic derecho en Powershell.exe y elija Crear acceso directo. Guarde temporalmente algún lugar como su escritorio
  • Es posible que desee abrir como administrador de forma predeterminada. Seleccione Acceso directo> Propiedades> Avanzado> Abrir como administrador
  • Abre la carpeta Sendto. Inicio> Ejecutar> Shell: Sendto
  • Mueva el acceso directo Powershell.exe a la carpeta Sendto
  • Ahora debería poder hacer clic derecho en un script de PS1.
  • Haga clic derecho en un archivo PS1, seleccione la opción de contexto Enviar a> Seleccione el acceso directo de Powershell
  • Tu script PS1 debería ejecutarse.
MrRobot
fuente
1
¿Cómo es esto mejor que la opción predeterminada del menú contextual 'Ejecutar con Powershell'?
elBradford
1

Usé esto (necesito ejecutarlo solo una vez); También asegúrese de tener derechos para ejecutar:

de PowerShell con derechos elevados:

Set-ExecutionPolicy=RemoteSigned

luego de un archivo bat:

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

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

 assoc .ps1=Microsoft.PowerShellScript.1

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

y voilá; haciendo doble clic en un * .ps1 lo ejecutará.

Paul Fijma
fuente
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 el
Solo la combinación de la respuesta aceptada con esta respuesta funcionó para mí, una vez que usé el comando de la respuesta aceptada en la clave de registro. Aparentemente assocse requiere correr .
ajeh
@ajeh (perdón por bieng leet a la fiesta. Si obtiene ese error, es porque tiene las comillas simples incorrectas. asegúrese de usar UTF-8. (use notepad ++; suelte las dos cadenas, guárdelas como un archivo runme.cmd) )
Paul Fijma
1

En Windows 10 también es posible que desee eliminar la anulación del Explorador de Windows para la asociación de extensiones de archivo:

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

Además del HKEY_CLASSES_ROOT\Microsoft.PowerShellScript.1\Shell\open\commandcambio mencionado en otras respuestas.

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

Chris Xue
fuente