Czy istnieje sposób, aby skrypt programu PowerShell działał przez dwukrotne kliknięcie pliku .ps1?


139

Rozprowadzam skrypt PowerShell do mojego zespołu. Skrypt ma na celu pobranie adresu IP z klienta Vsphere, nawiązanie połączenia mstsc i zarejestrowanie go w udostępnionym pliku.

W chwili, gdy użyli skryptu, poznali adres IP maszyny. Następnie zawsze używają bezpośrednio mstsc zamiast uruchamiania skryptu PowerShell. (Ponieważ używają mstsc, nie jestem w stanie wiedzieć, czy często używają maszyny wirtualnej, czy nie).

Przede wszystkim mówią mi, że uruchomienie PowerShell nie jest proste.

Jestem chory przez ich lenistwo.

Czy istnieje sposób, aby skrypt programu PowerShell działał przez dwukrotne kliknięcie pliku .ps1?


3
A co powiesz na używanie logów na serwerze? „Nie ufaj użytkownikowi” może oznaczać, że nie możesz mu powierzyć swoich danych, ale częściej oznacza to, że nie ufaj mu, aby nie był leniwy.


Kompilowanie skryptu PS przy użyciu Powershell studio sapien.com/software/powershell_studio
Root Loop

Wolę uruchomić to przez vscode (żeby zobaczyć konsolę i zdebugować ją)
JinSnow

Odpowiedzi:


132

Utwórz skrót z czymś takim jak „Cel”:

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

3
Ponieważ Jeffery Hicks (jest autorytatywnym źródłem informacji w PowerShell) powiedział, że nie zaleca się zmiany ustawień, uznałbym, że twoja odpowiedź jest najlepszą odpowiedzią, a odpowiedź JPBlanc jako użyteczną.
Samselvaprabu

6
użyj tego z: `-noLogo -ExecutionPolicy unrestricted -file <ścieżka>`, zgodnie z odpowiedzią: @ user3071883
Ujjwal Singh

1
@UjjwalSingh: -NoProfilejest również pomocny, ponieważ profil może robić różne rzeczy, których skrypt nie oczekuje.
Joey

5
Dla przyszłych czytelników: w odpowiedziach poniżej znajduje się hack rejestru, który spełnia to, o co prosił OP. Przyjęta odpowiedź nie.
Wouter

2
Czy można to zrobić, ale używając ścieżki względnej / bieżącej?
mythofechelon

79

Lub jeśli chcesz, aby wszystkie pliki PS1 działały tak, jak pliki VBS, możesz edytować rejestr w następujący sposób:

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

Edytuj wartość domyślną, aby była podobna ...

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

Następnie możesz po prostu dwukrotnie kliknąć wszystkie pliki .PS1, tak jak chcesz. moim skromnym zdaniem, być w stanie po wyjęciu z pudełka.

Mam zamiar nazwać to „Hack do usuwania kastracji z Powershell”. LOL ciesz się!


26
To jest jedyna odpowiedź, która zadziałała dla mnie na tej liście odpowiedzi. Nie jestem przygotowany na przyjęcie odpowiedzi „To nie jest zalecane” - mówię komputerowi, co ma robić, komputer mi nie mówi.
Matt

7
W rzeczywistości jest to podwójne obejście. Usuwa ograniczenie dotyczące podwójnego kliknięcia, aby uruchomić i omija zasady wykonywania programu PowerShell, które mają zapobiegać uruchamianiu niezaufanych skryptów nawet z konsoli.
Iszi

4
To jest zły sposób, aby to zrobić. Zmieniasz działanie polecenia „Otwórz” zamiast ustawiania opcji „Uruchom z PowerShell” jako domyślnej. Zobacz odpowiedź itgala.xyz poniżej.
Indy411

4
Jeśli chcesz użyć tej metody, prawidłowa wartość domyślna klucza rejestru to faktycznie miejsce, w "C:\Windows\System32\WindowsPowerShell\v1.0\powershell.exe" -NoLogo -File "%1"%*którym możesz opcjonalnie dołączyć rozszerzenie -ExecutionPolicy unrestricted. Zwróć uwagę na zmianę na końcu polecenia, która umożliwia przekazanie zerowej lub większej liczby parametrów do skryptu programu PowerShell. Cudzysłowy i odstępy wokół znaków procentowych powinny być dokładnie takie, jak pokazano.
Glenn Slayden

2
W przypadku rozwiązania wiersza polecenia zamiast edycji rejestru można wpisać, ftype Microsoft.PowerShellScript.1=^"^%SystemRoot^%\System32\WindowsPowerShell\v1.0\powershell.exe^" -NoLogo -ExecutionPolicy Unrestricted -File ^"%1^" %*co spowoduje to samo.
Damian T.

21

Należy pamiętać, że jedną z funkcji zabezpieczeń programu PowerShell jest to, że użytkownicy NIE mogą uruchamiać skryptu za pomocą dwukrotnego kliknięcia. Zachowaj szczególną ostrożność, modyfikując to ustawienie. Alternatywą może być spakowanie skryptu. Niektóre edytory, takie jak PrimalScript, potrafią to zrobić. Użytkownicy nadal potrzebują zainstalowanego programu PowerShell, ale mogą kliknąć dwukrotnie plik exe. Wygląda na to, że Twój zespół potrzebuje trochę edukacji.


3
Jest to funkcja bezpieczeństwa, ponieważ opóźnia hakerów o co najmniej kilka minut, zanim znajdą alternatywę!
MarcH

23
To głupia i bezużyteczna funkcja bezpieczeństwa. Czy możesz uruchomić partię przez podwójne kliknięcie na niej? Tak, exe? Tak. VBScript? Tak. Nie rozumiem, dlaczego skrypt Poweshell byłby uważany za bardziej niebezpieczny niż wszystkie inne
Mauro F.

12
Nie wiem jak wy, ale na pewno wcześniej uruchomiłem plik nietoperza na niewłaściwym komputerze z przypadkowym dwukrotnym kliknięciem. W przypadku czegoś, co ma zautomatyzować administrację, ograniczenie tego ma sens.
lordcheeto

1
Możesz dwukrotnie kliknąć plik EXE, więc nie widzę, jak to pomaga. Ale z pewnością zespół Powershell jest świadomy tego podstawowego argumentu. Musi być w tym coś więcej.
usr

1
Jeśli piszesz skrypty, których wykonanie jest „niebezpieczne” i nie dodajesz podstawowego procesu potwierdzania… Myślę, że lubisz niebezpiecznie żyć.
Romain Vincent

18

To zadziałało dla mnie w systemie Windows 10 i PowerShell 5.1:

  • kliknij prawym przyciskiem myszy plik .ps1
  • Otwierać z...
  • Wybierz inną aplikację
  • Skopiuj lokalizację powershell.exe do paska adresu (domyślnie nie pokaże folderu Windows), tj. C: \ Windows \ System32 \ WindowsPowerShell \ v1.0
  • wybierz powershell.exe
  • wybierz „Zawsze używaj tej aplikacji do otwierania plików .ps1”
  • Kliknij OK

2
Prawdopodobnie musisz ustawić zasady wykonywania na maszynie hosta na coś rozsądnego, np. RemoteSigned
vizmi

4
To ma kilka lat i nikt o tym nie pomyślał jeszcze pół roku temu? - Ja też to zrobiłem i działa idealnie, chociaż musisz zrobić więcej konfiguracji, inaczej PowerShell odmówi uruchomienia jakichkolwiek skryptów .ps1 (zobacz Set-ExecutionPolicy).
DarkWiiPlayer

Wygląda na to, że nazwa skryptu nie musi zawierać spacji, jeśli chcesz, aby to zadziałało. Poza tym wydaje się działać idealnie.
Łukasz

2
Dlaczego nie jest to największa liczba głosów? Dlaczego mielibyśmy edytować rejestr bezpośrednio lub używać plików wsadowych, skoro można to zrobić zgodnie z zamierzeniami systemu Windows, za pośrednictwem skojarzeń plików?
Dr. Kickass

@ Dr.Kickass Jest to prawdopodobnie jedna z nowszych odpowiedzi, jak sądzę
vizmi

17

Napisałem to kilka lat temu (uruchom z uprawnieniami administratora):

<#
.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
Musiałem go zmienić w tej lokalizacji, aby działał: Komputer \ HKEY_CLASSES_ROOT \ Applications \ powershell.exe \ Shell \ Open \ Command. Nie rozumiem rejestru na tyle, aby wyjaśnić, dlaczego tak jest. Może dlatego, że używam Powershell 3.0? W każdym razie dzięki za scenariusz.
Wouter

15

Musisz dostosować rejestr. Najpierw skonfiguruj PSDrive dla HKEY_CLASSES_ROOT, ponieważ nie jest to ustawione domyślnie. Polecenie to:

New-PSDrive HKCR Registry HKEY_CLASSES_ROOT

Teraz możesz nawigować i edytować klucze rejestru i wartości w HKEY_CLASSES_ROOT, tak jak w zwykłych HKCU i HKLM PSDrives.

Aby skonfigurować dwukrotne kliknięcie w celu bezpośredniego uruchamiania skryptów PowerShell:

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

Aby skonfigurować dwukrotne kliknięcie, aby otworzyć skrypty PowerShell w PowerShell ISE:

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

Aby przywrócić wartość domyślną (ustawia dwukrotne kliknięcie, aby otworzyć skrypty PowerShell w Notatniku):

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

Próbowałem przywrócić wartość domyślną za pomocą ostatniej linii z Elevated PowerShell ISE, ale najwyraźniej jeśli użyłeś polecenia takiego jak Thermionix, zastępuje ono wartość domyślną, więc musisz jawnie zresetować Shell.command (ale nie znalazłem poprawna składnia, więc musiałem przejść przez Panel sterowania> Programy> Skojarzenia plików).
dragon788

13

Zgadzam się, że ustawienie ustawień systemowych może być trochę za duże, ale skrót wymagający zakodowanej ścieżki nie jest idealny. Plik nietoperza faktycznie ładnie rozwiązuje problem

RunMyPowershellScript.bat

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

Ten plik wsadowy można teraz kliknąć dwukrotnie, można łatwo utworzyć skróty do pliku wsadowego, a skrypt można wdrożyć w dowolnym folderze.


Zauważ, że potrzebujesz skryptu ps1 w tym samym folderze co plik bat. Zyskujesz możliwość kopiowania wklejania kosztem utrzymania 2 plików.
jiggunjer

11

Proste polecenia programu PowerShell, aby ustawić to w rejestrze;

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
Dla nieco większego bezpieczeństwa sugerowałbym użycie ExecutionPolicy RemoteSignedtak, aby losowy skrypt pobrany z sieci / internetu (z metadanymi wskazującymi, że nie został utworzony lokalnie) nie byłby wykonywany po dwukrotnym kliknięciu, ale każdy plik utworzony przez skopiowanie i wklejanie kodu do pliku .ps1 zostanie wykonane, ponieważ nie ma skojarzonych z nim metadanych.
dragon788

6
  1. Przejdź REGEDIT do HKEY_LOCAL_MACHINE \ SOFTWARE \ Classes \ Microsoft.PowerShellScript.1 \ Shell
  2. W prawym okienku kliknij dwukrotnie „(Domyślne)”
  3. Usuń istniejącą wartość „Otwórz” (która uruchamia Notatnik) i wpisz „0” (zero, co powoduje bezpośrednie uruchomienie programu Powershell).

Przywróć wartość, jeśli chcesz ponownie używać Notatnika jako domyślnego.


5

Możesz ustawić domyślne skojarzenie ps1plików, powershell.exektóre umożliwi wykonanie skryptu PowerShell, klikając go dwukrotnie.

W systemie Windows 10

  1. Kliknij ps1plik prawym przyciskiem myszy
  2. Kliknij Open with
  3. Kliknij Choose another app
  4. W wyskakującym okienku wybierz More apps
  5. Przewiń w dół i wybierz Look for another app on this PC.
  6. Przeglądaj i wybierz C:\Windows\System32\WindowsPowerShell\v1.0\powershell.exe.
  7. Element listy

Spowoduje to zmianę skojarzeń ps1plików i pliki zostaną uruchomione, klikając je dwukrotnie. Możesz przywrócić jej domyślne zachowanie, ustawiając notepad.exeaplikację domyślną.

Źródło


1
Działa to dobrze, ale prawie powiela odpowiedź vizmi.
Marteng

4

umieść prosty plik .cmd w moim podfolderze z moim plikiem .ps1 o tej samej nazwie, więc na przykład skrypt o nazwie „foobar” będzie miał „foobar.ps1” i „foobar.cmd”. Aby uruchomić plik .ps1, wszystko, co muszę zrobić, to kliknąć plik .cmd w eksploratorze lub uruchomić .cmd z wiersza poleceń. Używam tej samej nazwy podstawowej, ponieważ plik .cmd automatycznie wyszuka plik .ps1, używając własnej nazwy.

::====================================================================
:: 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 umożliwia uruchomienie pliku .cmd z wiersza poleceń bez konieczności przechodzenia do określonego katalogu, w którym znajdują się skrypty. Nastąpi przejście do katalogu skryptów, a po zakończeniu wróć do oryginalnego katalogu.

Możesz także wyłączyć pauzę, jeśli chcesz, aby okno poleceń zniknęło po zakończeniu działania skryptu.

Jeśli mój skrypt .ps1 ma parametry, pytam o nie za pomocą monitów GUI za pomocą formularzy .NET, ale także dostosowuję skrypty do akceptowania parametrów, jeśli chcę je zamiast tego przekazać. W ten sposób mogę kliknąć go dwukrotnie w Eksploratorze i nie muszę znać szczegółów parametrów, ponieważ zapyta mnie o to, czego potrzebuję, z polami listy lub innymi formularzami.


2
Dzięki za plik wsadowy. Tak dla Twojej wiadomości, możesz zastąpić instrukcję „for” po prostu: „set SCRIPT_PATH =% ~ p0” (bez cudzysłowów). W rzeczywistości użyłbym ~ dp0 zamiast ~ p0, więc będzie działać na różnych dyskach. Sam tego użyję.
zumalifeguard

2

Jest to oparte na odpowiedzi KoZm0kNoT. Zmodyfikowałem go, aby działał na różnych dyskach.

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

Dwa pushd / popds są niezbędne w przypadku, gdy cwd użytkownika znajduje się na innym dysku. Bez zestawu zewnętrznego cwd na dysku ze skryptem zostanie utracone.


2

Oto, czego używam, aby domyślnie uruchamiać scrips jako administrator:

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

Musisz wkleić to do regedit jako domyślną wartość dla:

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

Lub oto skrypt, który zrobi to za Ciebie:

$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

Jeśli znasz zaawansowaną administrację Windows, możesz użyć tego pakietu ADM (instrukcje znajdują się na tej stronie) i zezwolić na uruchamianie skryptów PowerShell po dwukrotnym kliknięciu za pomocą tego szablonu i lokalnego obiektu GPO. Następnie możesz po prostu zmienić domyślny program powiązany z typem pliku .ps1 napowershell.exe (użyj wyszukiwania, jest dość schowany) i jesteś gotowy do uruchamiania skryptów PowerShell za pomocą dwukrotnego kliknięcia.

W przeciwnym razie zalecałbym trzymać się innych sugestii, ponieważ możesz zepsuć cały system za pomocą tych narzędzi administracyjnych.

Myślę, że ustawienia domyślne są zbyt surowe. Jeśli komuś uda się umieścić jakiś złośliwy kod na twoim komputerze, może on również ominąć to ograniczenie (zawinąć je w plik .cmd lub .exe, lub sztuczka ze skrótem), a wszystko, co ostatecznie osiąga, to po prostu zapobiec z łatwego sposobu uruchamiania napisanego skryptu.


Po zainstalowaniu możesz znaleźć to ustawienie w „Edytorze lokalnych zasad grupy” w: Lokalne zasady komputera -> Konfiguracja komputera -> Szablony administracyjne -> Składniki systemu Windows. Tam możesz go włączyć i upewnić się, że wybrałeś zasadę z listy rozwijanej, która zostanie wtedy włączona.
Wouter

1

Możesz skorzystać z funkcji „SendTo” systemu Windows, aby ułatwić uruchamianie skryptów PS1. Korzystając z tej metody, możesz kliknąć prawym przyciskiem myszy skrypt PS1 i wykonać. To nie jest dokładną odpowiedzią na pytanie OP, ale jest blisko. Miejmy nadzieję, że przyda się to innym. BTW .. jest to pomocne przy wielu innych zadaniach.

  • Zlokalizuj / wyszukaj Powershell.exe
  • Kliknij prawym przyciskiem myszy Powershell.exe i wybierz Otwórz lokalizację pliku
  • Kliknij prawym przyciskiem myszy Powershell.exe i wybierz Utwórz skrót. Tymczasowo zapisz miejsce, takie jak pulpit
  • Możesz chcieć otworzyć się domyślnie jako administrator. Wybierz Skrót> Właściwości> Zaawansowane> Otwórz jako administrator
  • Otwórz folder Sendto. Start> Uruchom> Shell: Sendto
  • Przenieś skrót Powershell.exe do folderu Sendto
  • Powinieneś teraz móc kliknąć prawym przyciskiem myszy skrypt PS1.
  • Kliknij prawym przyciskiem myszy plik PS1, wybierz opcję kontekstową SendTo> Wybierz skrót Powershell
  • Twój skrypt PS1 powinien zostać wykonany.

1
Jak to jest lepsze niż domyślna opcja menu kontekstowego „Uruchom z Powershell”?
elBradford

1

Użyłem tego (wystarczy uruchomić go tylko raz); upewnij się również, że masz uprawnienia do wykonywania:

z PowerShell z podwyższonymi uprawnieniami:

Set-ExecutionPolicy=RemoteSigned

następnie z pliku nietoperza:

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

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

 assoc .ps1=Microsoft.PowerShellScript.1

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

i voila; dwukrotne kliknięcie * .ps1 spowoduje jego wykonanie.


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,

Tylko połączenie zaakceptowanej odpowiedzi z tą odpowiedzią zadziałało u mnie, gdy użyłem polecenia z zaakceptowanej odpowiedzi w kluczu rejestru. Najwyraźniej bieganie assocjest wymagane.
ajeh,

@ajeh (przepraszam za bieng leet to the party. Jeśli pojawi się ten błąd, to dlatego, że masz złe pojedyncze cudzysłowy. Upewnij się, że używasz UTF-8. (użyj notatnika ++; upuść dwa ciągi znaków, zapisz jako plik runme.cmd )
Paul Fijma

1

W systemie Windows 10 możesz również chcieć usunąć nadpisanie Eksploratora Windows dla skojarzenia rozszerzenia pliku:

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

dodatkowo HKEY_CLASSES_ROOT\Microsoft.PowerShellScript.1\Shell\open\command zmiany wymienionej w innych odpowiedziach.

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



Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.