Esiste un modo per far funzionare uno script PowerShell facendo doppio clic su un file .ps1?


139

Sto distribuendo uno script PowerShell al mio team. Lo script è quello di recuperare un indirizzo IP dal client Vsphere, stabilire una connessione mstsc e registrarlo in un file condiviso.

Nel momento in cui hanno usato lo script hanno avuto modo di conoscere l'indirizzo IP della macchina. Successivamente, tendono sempre a utilizzare mstsc direttamente anziché eseguire lo script PowerShell. (Dato che utilizzano mstsc, non sono in grado di sapere se utilizzano frequentemente la VM o meno.)

Principalmente mi stanno dicendo che eseguire PowerShell non è semplice.

Sono malato per la loro pigrizia.

Esiste un modo per far funzionare uno script PowerShell facendo doppio clic su un file .ps1?


3
Che ne dici di usare i log sul server? "Non fidarti dell'utente" può significare che non puoi fidarti di lui con i tuoi dati, ma più spesso significa non fidarti di lui per non essere pigro.


Compilazione di uno script PS utilizzando Powershell studio sapien.com/software/powershell_studio
Root Loop

Preferisco eseguirlo tramite vscode (così posso vedere la console e debug)
JinSnow,

Risposte:


132

Crea una scorciatoia con qualcosa del genere come "Target":

powershell.exe -command "& 'C:\A path with spaces\MyScript.ps1' -MyArguments blah"

3
Come Jeffery Hicks (è una risorsa autorevole in PowerShell) ha segnalato che non è consigliabile modificare le impostazioni, voterei la tua risposta come la migliore e JPBlanc come utile.
Samselvaprabu,

6
usalo con: `-noLogo -ExecutionPolicy senza restrizioni -file <percorso>` come risposto da: @ user3071883
Ujjwal Singh

1
@UjjwalSingh: -NoProfileè anche utile, poiché il profilo può fare tutti i tipi di cose che lo script non si aspetta.
Joey,

5
Per i futuri lettori: c'è una modifica del registro nelle risposte che segue che soddisfa ciò che OP ha richiesto. La risposta accettata no.
Wouter,

2
C'è un modo per farlo ma usando un percorso relativo / corrente?
mythofechelon,

79

O se vuoi che tutti i file PS1 funzionino come fanno i file VBS, puoi modificare il registro in questo modo:

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

Modifica il valore predefinito in modo che sia simile ...

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

Quindi puoi semplicemente fare doppio clic su tutti i tuoi file .PS1 come vorresti. a mio modesto parere, essere in grado di uscire dalla scatola.

Chiamerò questo "The Powershell De-castration Hack". Divertiti LOL!


27
Questo è l'unico che ha funzionato per me in questo elenco di risposte. Non sono disposto ad accettare "Non è consigliato" come risposta - Dico al PC cosa fare, il PC non me lo dice.
Matt,

7
Questo è in realtà un doppio bypass. Rimuove la restrizione contro il doppio clic per l'esecuzione e aggira ExecutionPolicy di PowerShell che ha lo scopo di impedire l'esecuzione di script non attendibili anche dalla console.
Iszi,

4
Questo è il modo sbagliato di farlo. Stai cambiando il comando "Apri" anziché impostare "Esegui con PowerShell" come predefinito. Vedi la risposta itgala.xyz di seguito.
Indy411,

4
Se si desidera utilizzare questo metodo, il valore predefinito corretto per la chiave di registro è effettivamente "C:\Windows\System32\WindowsPowerShell\v1.0\powershell.exe" -NoLogo -File "%1"%*dove è possibile includere facoltativamente il file -ExecutionPolicy unrestricted. Notare la modifica alla fine del comando che consente di trasmettere zero o più parametri allo script PowerShell. Le virgolette e la spaziatura attorno ai segni di percentuale devono essere esattamente come mostrato.
Glenn Slayden,

2
Per una soluzione a riga di comando anziché modificare il registro, è possibile digitare ftype Microsoft.PowerShellScript.1=^"^%SystemRoot^%\System32\WindowsPowerShell\v1.0\powershell.exe^" -NoLogo -ExecutionPolicy Unrestricted -File ^"%1^" %*quale eseguirà lo stesso.
Damian T.,

21

Tenere presente che una delle funzionalità di sicurezza di PowerShell è che gli utenti NON possono avviare lo script con un doppio clic. Fare molta attenzione se si modifica questa impostazione. Un'alternativa potrebbe essere quella di impacchettare il tuo script. Alcuni editor come PrimalScript possono farlo. Gli utenti devono ancora installare PowerShell ma possono fare doppio clic su exe. E sembra che la tua squadra abbia bisogno di un po 'di educazione.


3
È una funzione di sicurezza perché ritarda gli hacker di almeno alcuni minuti fino a quando non trovano un'alternativa!
MarcH,

23
È una funzionalità di sicurezza stupida e inutile. Puoi eseguire un batch facendo doppio ciclismo su di esso? Sì, un'exe? Sì. Un VBScript? Sì. Non riesco a capire perché una sceneggiatura di Poweshell sarebbe considerata più pericolosa di tutte le altre
Mauro F.

12
Non so voi ragazzi, ma ho sicuramente eseguito un file bat sul computer sbagliato prima con un doppio clic accidentale. Con qualcosa che ha lo scopo di automatizzare l'amministrazione, ha perfettamente senso limitarlo.
lordcheeto,

1
Puoi fare doppio clic su un file EXE, quindi non vedo come questo aiuti. Ma sicuramente il team Powershell è a conoscenza di questo argomento di base. Deve esserci di più.
usr

1
Se scrivi script "pericolosi" da eseguire e non aggiungi un processo di conferma di base ... Immagino che ti piaccia vivere pericolosamente.
Romain Vincent,

18

Questo ha funzionato per me su Windows 10 e PowerShell 5.1:

  • fare clic con il tasto destro sul file .ps1
  • Aperta con...
  • Scegli un'altra app
  • Copia la posizione di powershell.exe nella barra degli indirizzi (per impostazione predefinita non mostrerà la cartella di Windows) cioè C: \ Windows \ System32 \ WindowsPowerShell \ v1.0
  • seleziona powershell.exe
  • seleziona "Usa sempre questa app per aprire i file .ps1"
  • fai clic su OK

2
Probabilmente devi impostare i criteri di esecuzione sul computer host su qualcosa di ragionevole, ad esempio RemoteSigned
vizmi,

4
Ha diversi anni e nessuno ci ha pensato fino a sei mesi fa? - Ho fatto anche questo e funziona perfettamente, anche se devi fare qualche configurazione in più o PowerShell rifiuterà di eseguire qualsiasi script .ps1 (vedi Set-ExecutionPolicy).
DarkWiiPlayer

Sembra che il nome dello script non debba contenere spazi se vuoi che funzioni. A parte questo sembra funzionare perfettamente.
Luca

2
In che modo questa non è la risposta più votata? Perché dovremmo modificare direttamente il registro o utilizzare i file batch quando puoi farlo nel modo previsto da Windows, tramite associazioni di file?
Dr. Kickass,

@ Dr.Kickass Probabilmente è una delle risposte più recenti credo
vizmi

17

L'ho scritto qualche anno fa (eseguilo con i diritti di amministratore):

<#
.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 {}
}

2
Ho dovuto cambiarlo in questa posizione affinché funzioni: Computer \ HKEY_CLASSES_ROOT \ Applications \ powershell.exe \ Shell \ Open \ Command. Non capisco abbastanza il registro per spiegare perché. Forse perché sto usando Powershell 3.0? Comunque, grazie per la sceneggiatura.
Wouter,

15

Dovrai modificare il registro. Innanzitutto, configura un PSDrive per HKEY_CLASSES_ROOT poiché questo non è impostato per impostazione predefinita. Il comando per questo è:

New-PSDrive HKCR Registry HKEY_CLASSES_ROOT

Ora puoi navigare e modificare chiavi e valori di registro in HKEY_CLASSES_ROOT proprio come faresti con i normali PSDrive HKCU e HKLM.

Per configurare il doppio clic per avviare direttamente gli script di PowerShell:

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

Per configurare il doppio clic per aprire gli script di PowerShell in PowerShell ISE:

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

Per ripristinare il valore predefinito (imposta il doppio clic per aprire gli script di PowerShell nel Blocco note):

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

Ho provato a ripristinare il valore predefinito utilizzando l'ultima riga di un ISE PowerShell elevato, ma a quanto pare se hai usato un comando come descritto da Thermionix sostituisce il valore predefinito, quindi devi ripristinare esplicitamente Shell.command (ma non ho trovato il sintassi corretta per questo, quindi ho dovuto passare dal Pannello di controllo> Programmi> Associazioni di file).
dragon788,

13

Concordo sul fatto che l'impostazione di un'impostazione di sistema potrebbe essere un po 'troppo, ma il collegamento che richiede un percorso hardcoded non è l'ideale. Un file bat risolve effettivamente il problema

RunMyPowershellScript.bat

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

Ora è possibile fare doppio clic su questo file batch, è possibile creare facilmente collegamenti al file batch e lo script può essere distribuito in qualsiasi cartella.


Nota che hai bisogno dello script ps1 nella stessa cartella del file bat. Ottieni la capacità di copia incolla al costo di mantenere 2 file.
jiggunjer,

11

Semplici comandi di PowerShell per impostarlo nel 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"'

5
Per un po 'più di sicurezza suggerirei di utilizzare in ExecutionPolicy RemoteSignedmodo che uno script casuale scaricato dalla rete / internet (con i metadati che indicano che non è stato creato localmente) non venga eseguito da un doppio clic, ma qualsiasi file creato da copia e incollare il codice in un file .ps1 verrà eseguito perché non ha quei metadati associati.
dragon788,

6
  1. Passare a REGEDIT su HKEY_LOCAL_MACHINE \ SOFTWARE \ Classes \ Microsoft.PowerShellScript.1 \ Shell
  2. Nel riquadro destro, fare doppio clic su "(Predefinito)"
  3. Elimina il valore esistente di "Apri" (che avvia Blocco note) e digita "0" (essendo zero, che avvia direttamente Powershell).

Ripristinare il valore se si desidera utilizzare nuovamente Blocco note come predefinito.


5

È possibile impostare l'associazione di ps1file predefinita dei file supowershell.exe che consentirà di eseguire uno script PowerShell facendo doppio clic su di esso.

In Windows 10,

  1. Fare clic con il tasto destro su a ps1 file
  2. Clic Open with
  3. Clic Choose another app
  4. Nella finestra popup, selezionare More apps
  5. Scorri verso il basso e seleziona Look for another app on this PC .
  6. Sfoglia e seleziona C:\Windows\System32\WindowsPowerShell\v1.0\powershell.exe .
  7. Voce di elenco

Ciò modificherà l'associazione dei file e i ps1file verranno eseguiti facendo doppio clic su di essi. È possibile riportarlo al suo comportamento predefinito impostandonotepad.exe l'app predefinita.

fonte


1
Funziona bene ma praticamente duplica la risposta di Vizmi.
Marteng,

4

metto un semplice file .cmd nella mia sottocartella con il mio file .ps1 con lo stesso nome, quindi, per esempio, uno script chiamato "foobar" avrebbe "foobar.ps1" e "foobar.cmd". Quindi, per eseguire .ps1, tutto quello che devo fare è fare clic sul file .cmd da explorer o eseguire .cmd dal prompt dei comandi. Uso lo stesso nome di base perché il file .cmd cercherà automaticamente .ps1 usando il proprio 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

Il pushd / popd consente di avviare il file .cmd da un prompt dei comandi senza dover passare alla directory specifica in cui si trovano gli script. Passerà alla directory degli script, quindi al termine tornerà alla directory originale.

È inoltre possibile interrompere la pausa se si desidera che la finestra di comando scompaia al termine dello script.

Se il mio script .ps1 ha dei parametri, li richiedo con i prompt della GUI usando .NET Forms, ma rende anche gli script abbastanza flessibili da accettare i parametri se voglio invece passarli. In questo modo posso semplicemente fare doppio clic da Explorer e non dover conoscere i dettagli dei parametri poiché mi chiederà ciò di cui ho bisogno, con caselle di riepilogo o altri moduli.


2
Grazie per il file batch. Solo per questo, puoi sostituire l'istruzione "for" con just: "set SCRIPT_PATH =% ~ p0" (senza virgolette). In effetti, userei ~ dp0 invece di ~ p0, quindi funzionerà su tutte le unità. Lo userò io stesso.
zumalifeguard,

2

Questo si basa sulla risposta di KoZm0kNoT. L'ho modificato per funzionare su più unità.

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

I due pushd / popds sono necessari nel caso in cui il cwd dell'utente si trovi su un'unità diversa. Senza il set esterno, il CWD sull'unità con lo script andrà perso.


2

Questo è quello che uso per far funzionare gli script come amministratore per impostazione predefinita:

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

Dovrai incollarlo in regedit come valore predefinito per:

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

Oppure ecco uno script che lo farà per te:

$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"""''}"')

2

Se si ha familiarità con l'amministrazione avanzata di Windows, è possibile utilizzare questo pacchetto ADM (le istruzioni sono incluse in quella pagina) e consentire l'esecuzione degli script PowerShell dopo aver fatto doppio clic tramite questo modello e l'oggetto Criteri di gruppo locale. Dopodiché puoi semplicemente cambiare il programma predefinito associato al tipo di file .ps1 in powershell.exe(usa la ricerca, è abbastanza nascosto) e sei pronto per eseguire gli script di PowerShell con un doppio clic.

Altrimenti, consiglierei di attenersi ad altri suggerimenti in quanto è possibile rovinare l'intero sistema con questi strumenti di amministrazione.

Penso che le impostazioni predefinite siano troppo rigide. Se qualcuno riesce a mettere un po 'di codice dannoso sul tuo computer, allora è anche in grado di aggirare questa restrizione (avvolgilo in un file .cmd o .exe, o un trucco con un collegamento) e tutto ciò che alla fine compie è solo per impedire tu dal modo semplice di eseguire lo script che hai scritto.


Una volta installato, è possibile trovare questa impostazione in "Editor Criteri di gruppo locali" in: Criteri del computer locale -> Configurazione computer -> Modelli amministrativi -> Componenti di Windows. Lì, è possibile abilitarlo e assicurarsi di selezionare un criterio nell'elenco a discesa che viene attivato successivamente.
Wouter,

1

Puoi utilizzare la funzionalità "SendTo" di Windows per semplificare l'esecuzione degli script PS1. Usando questo metodo puoi fare clic con il tasto destro su uno script PS1 ed eseguire. Questo non risponde esattamente alla domanda OP ma è vicino. Speriamo che questo sia utile per gli altri. A proposito .. questo è utile per una varietà di altre attività.

  • Individua / cerca Powershell.exe
  • Fare clic con il tasto destro su Powershell.exe e selezionare Apri posizione file
  • Fare clic con il tasto destro su Powershell.exe e selezionare Crea collegamento. Salva temporaneamente un posto come il tuo desktop
  • Potresti voler aprire come amministratore per impostazione predefinita. Seleziona Collegamento> Proprietà> Avanzate> Apri come amministratore
  • Apri la cartella Sendto. Start> Esegui> Shell: Sendto
  • Spostare il collegamento Powershell.exe nella cartella Sendto
  • Ora dovresti essere in grado di fare clic con il tasto destro su uno script PS1.
  • Fare clic con il tasto destro su un file PS1, selezionare l'opzione di contesto SendTo> Seleziona il collegamento Powershell
  • Lo script PS1 dovrebbe essere eseguito.

1
In che modo è meglio dell'opzione predefinita del menu di scelta rapida "Esegui con Powershell"?
elBradford,

1

L'ho usato (è necessario eseguirlo solo una volta); assicurati inoltre di disporre dei diritti per eseguire:

da PowerShell con diritti elevati:

Set-ExecutionPolicy=RemoteSigned

quindi da un file 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 voilà; facendo doppio clic su * .ps1 lo eseguirà.


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

Solo la combinazione della risposta accettata con questa risposta ha funzionato per me, una volta che ho usato il comando dalla risposta accettata nella chiave di registro. Apparentemente assocè necessario correre .
ajeh

@ajeh (scusa per il biet leet alla festa. Se ricevi quell'errore, è perché hai sbagliato virgolette singole. Assicurati di usare UTF-8. (usa il blocco note ++; rilascia le due stringhe, salva come file runme.cmd )
Paul Fijma,

1

In Windows 10 potresti anche voler eliminare l'override di Windows Explorer per l'associazione delle estensioni di file:

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

oltre al HKEY_CLASSES_ROOT\Microsoft.PowerShellScript.1\Shell\open\commandcambiamento menzionato in altre risposte.

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



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.