Чи є спосіб зробити так, щоб сценарій PowerShell працював, двічі клацнувши файл .ps1?


139

Я поширюю сценарій PowerShell своїй команді. Сценарій полягає в тому, щоб отримати IP-адресу від клієнта Vsphere, встановити mstsc-з'єднання та записати його у спільний файл.

Щойно вони використали сценарій, вони дізналися IP-адресу машини. Після цього вони завжди прагнуть використовувати mstsc безпосередньо замість запуску сценарію PowerShell. (Оскільки вони використовують mstsc, я не можу знати, чи часто вони використовують VM чи ні.)

В основному вони мені кажуть, що запуск PowerShell не є простим.

Мене нудить їх лінь.

Чи є спосіб зробити так, щоб сценарій PowerShell працював, двічі клацнувши файл .ps1?


3
Як щодо використання журналів на сервері? "Не довіряйте користувачеві" може означати, що ви не можете довіряти йому свої дані, але частіше це означає, що не довіряйте йому, щоб він не лінувався.

Дивіться також howtogeek.com/204166/…
Michael Freidgeim

Складання сценарію PS за допомогою студії Powershell sapien.com/software/powershell_studio
Root Loop

Я вважаю за краще запустити його через vscode (щоб я міг побачити консоль і налагоджувати його)
JinSnow

Відповіді:


132

Створіть ярлик із чимось таким, як "Ціль":

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

3
Оскільки Джеффрі Хікс (він є авторитетним ресурсом у Powerhell) радив, що не рекомендується змінювати налаштування, я б проголосував, що ваша відповідь є найкращою, а відповідь JPBlanc - корисною відповіддю.
Самсельвапрабу

6
використовуйте це з: `-noLogo -ExecutionPolicy unrestricted -file <path>` як відповів: @ user3071883
Ujjwal Singh

1
@UjjwalSingh: -NoProfileтакож корисно, оскільки профіль може робити всі речі, які сценарій не очікує.
Джої

5
Для майбутніх читачів: У відповідях нижче є злом реєстру, який забезпечує те, про що вимагав ОП. Прийнята відповідь не відповідає.
Wouter

2
Чи є спосіб це зробити, але використовуючи відносний / поточний шлях?
mythofechelon

79

Або якщо ви хочете, щоб усі файли PS1 працювали так, як це виконують файли VBS, ви можете редагувати реєстр так:

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

Відредагуйте значення за замовчуванням, щоб воно було щось подібне ...

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

Тоді ви можете просто двічі клацнути всі файли .PS1 так, як хотіли б. на мою скромну думку, бути в змозі вийти з коробки.

Я буду називати це "Злом де-кастрації Powershell". LOL насолоджуйтесь!


26
Це єдиний, хто працював на мене в цьому списку відповідей. Я не готовий прийняти "Це не радиться" як відповідь - я кажу ПК, що робити, ПК мені не каже.
Мет

7
Це насправді подвійний байпас. Видаляє обмеження щодо подвійного натискання на запуск і обходить PowerShell's ExecutionPolicy, що покликане запобігти запуску ненадійних сценаріїв навіть з консолі.
Іссі

4
Це неправильний спосіб зробити це. Ви змінюєте те, що робить команда "Відкрити", замість того, щоб встановити "Запуск із PowerShell" як типовий. Дивіться відповідь itgala.xyz нижче.
Indy411

4
Якщо ви хочете використовувати цей метод, правильне значення за замовчуванням для ключа реєстру насправді є тим, "C:\Windows\System32\WindowsPowerShell\v1.0\powershell.exe" -NoLogo -File "%1"%*де ви можете необов'язково включати -ExecutionPolicy unrestricted. Зверніть увагу на зміну в кінці команди, яка дозволяє передавати нульовий або більше параметрів до сценарію PowerShell. Лапки та пробіли навколо знаків відсотків повинні бути точно такими, як показано.
Гленн Слейден

2
Для рішення командного рядка, а не для редагування реєстру, ви можете ввести те, ftype Microsoft.PowerShellScript.1=^"^%SystemRoot^%\System32\WindowsPowerShell\v1.0\powershell.exe^" -NoLogo -ExecutionPolicy Unrestricted -File ^"%1^" %*що виконає те саме.
Даміан Т.

21

Пам’ятайте, що однією з особливостей безпеки PowerShell є те, що користувачі НЕ можуть запускати скрипт подвійним клацанням. Будьте обережні, якщо ви змінюєте цей параметр. Альтернативою може бути упаковка сценарію. Деякі редактори, такі як PrimalScript, можуть це зробити. Користувачі все ще потребують встановлення PowerShell, але потім вони можуть двічі клацнути exe. І звучить так, що ваша команда потребує трохи освіти.


3
Це функція безпеки, оскільки вона затримує хакерів хоча б на кілька хвилин, поки вони не знайдуть альтернативу!
Марч

23
Це дурна і марна функція безпеки. Чи можете ви запустити пакет, подвійним клацанням по ньому? Так, Ексе? Так. VBScript? Так. Я не усвідомлюю, чому сценарій з першою оболонкою вважатиметься більш небезпечним, ніж усі інші
Мауро Ф.

12
Я не знаю про вас, хлопці, але я, безумовно, раніше запустив файл bat на неправильному комп'ютері, випадковим подвійним клацанням. Щось для автоматизації управління, має сенс обмежити це.
lordcheeto

1
Ви можете двічі клацнути файл EXE, щоб я не бачив, як це допомагає. Але, безумовно, команда Powershell знає цей основний аргумент. Має бути більше.
usr

1
Якщо ви пишете сценарії, які є "небезпечними" для виконання, і ви не додаєте базового процесу підтвердження ... Я вважаю, що ви любите жити небезпечно.
Ромен Вінсент

18

Це працювало для мене в Windows 10 та поворотах 5.1:

  • клацніть правою кнопкою миші на файл .ps1
  • Відкрити за допомогою ...
  • Виберіть інший додаток
  • Скопіюйте розташування powershell.exe в адресний рядок (за замовчуванням він не відображатиме папку Windows), тобто C: \ Windows \ System32 \ WindowsPowerShell \ v1.0
  • виберіть powershell.exe
  • виберіть "Завжди використовувати цю програму для відкриття .ps1 файлів"
  • натисніть кнопку ОК

2
Ймовірно, вам потрібно встановити політику виконання на хост-машині на щось розумне, тобто RemoteSigned
vizmi

4
Це кілька років, і ніхто про це не думав до півроку тому? - Я це також зробив, і він працює відмінно, хоча вам доведеться зробити ще якусь конфігурацію, або повноваження взагалі відмовляться запускати будь-які сценарії .ps1 (див. Set-ExecutionPolicy).
DarkWiiPlayer

Здається, що ім'я сценарію не повинно містити пробілів, якщо ви хочете, щоб це працювало. Крім цього, здається, він ідеально працює.
Лука

2
Як це не відповідь з найвищим голосом? Чому ми б редагувати реєстр безпосередньо або використовувати пакетні файли, коли ви можете просто робити це так, як планував Windows, через асоціації файлів?
Доктор Кікасс

@ Dr.Kickass Це, мабуть, одна з нових відповідей, я думаю
vizmi

17

Я написав це кілька років тому (запустіть його з правами адміністратора):

<#
.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
Мені довелося змінити його в цьому місці, щоб він працював: Комп'ютер \ HKEY_CLASSES_ROOT \ Приклади \ powershell.exe \ Shell \ Open \ Command. Я не розумію реєстру достатньо, щоб пояснити, чому це. Можливо тому, що я керую Powershell 3.0? У будь-якому випадку, дякую за сценарій.
Wouter

15

Вам потрібно буде налаштувати реєстр. Спочатку налаштуйте PSDrive для HKEY_CLASSES_ROOT, оскільки він не встановлений за замовчуванням. Команда для цього:

New-PSDrive HKCR Registry HKEY_CLASSES_ROOT

Тепер ви можете переміщатись та редагувати ключі реєстру та значення у HKEY_CLASSES_ROOT так, як це було б у звичайних HKCU та HKLM PSDrives.

Щоб налаштувати подвійне клацання, щоб безпосередньо запустити сценарії PowerShell:

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

Щоб налаштувати подвійне клацання, щоб відкрити сценарії PowerShell в ISS PowerShell:

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

Щоб відновити значення за замовчуванням (встановлює подвійне клацання, щоб відкрити сценарії PowerShell в Блокноті):

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

Я спробував відновити значення за замовчуванням за допомогою останнього рядка з Elevated PowerShell ISE, але, мабуть, якщо ви використовували описану команду типу Thermionix, вона замінює за замовчуванням, тому вам доведеться явно скинути Shell.command (але я не знайшов правильний синтаксис для цього, тому мені довелося пройти через Панель управління> Програми> Асоціації файлів.
dragon788

13

Я погоджуюся, що налаштування системної установки може бути небагато, але ярлик, який вимагає твердо кодованого шляху, не є ідеальним. Файл bat фактично вирішує проблему

RunMyPowershellScript.bat

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

Цей пакетний файл тепер можна клацнути подвійним клацанням, ярлики можна легко створити до пакетного файлу, а сценарій можна розгорнути у будь-яку папку.


Зверніть увагу, що вам потрібен скрипт ps1 у тій же папці, що і файл bat Ви отримуєте здатність копіювати пасту ціною підтримки 2 файлів.
jiggunjer

11

Прості команди PowerShell, щоб встановити це в реєстрі;

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
Для трохи більшої безпеки я б запропонував використовувати ExecutionPolicy RemoteSignedтак, щоб випадковий скрипт, завантажений з мережі / Інтернету (метадані, що позначали, що він не створений локально), не виконується подвійним клацанням, але будь-який файл, створений копією та вставлення коду у файл .ps1 буде виконуватися, оскільки у нього не пов'язані метадані.
dragon788

6
  1. Перейдіть до REGEDIT до HKEY_LOCAL_MACHINE \ SOFTWARE \ Classes \ Microsoft.PowerShellScript.1 \ Shell
  2. На правій панелі двічі клацніть "(за замовчуванням)"
  3. Видаліть існуюче значення "Відкрити" (який запускає Блокнот) і введіть "0" (нульове значення, яке запускає Powershell безпосередньо).

Поверніть це значення, якщо ви хочете знову використовувати Блокнот як за замовчуванням.


5

Ви можете встановити файлову асоціацію ps1файлів за замовчуваннямpowershell.exe яка дозволить вам виконати скрипт повноважень, двічі клацнувши на ньому.

У Windows 10

  1. Клацніть правою кнопкою миші на a ps1 файл
  2. Клацніть Open with
  3. Клацніть Choose another app
  4. У спливаючому вікні виберіть More apps
  5. Прокрутіть донизу та виберіть Look for another app on this PC .
  6. Перейдіть до та виберіть C:\Windows\System32\WindowsPowerShell\v1.0\powershell.exe .
  7. Елемент списку

Це змінить асоціацію ps1файлів, і файли виконуватимуться, двічі клацнувши по них. Ви можете змінити його на стандартну поведінку, встановившиnotepad.exe програму за замовчуванням.

Джерело


1
Це добре працює, але в значній мірі дублює відповідь vizmi.
Мартенг

4

помістіть простий .cmd файл у свою підпапку з моїм файлом .ps1 з тим самим іменем, так, наприклад, сценарій під назвою "foobar" мав би "foobar.ps1" і "foobar.cmd". Отже, щоб запустити .ps1, все, що мені потрібно зробити, - це натиснути файл .cmd від провідника або запустити .cmd з командного рядка. Я використовую те саме базове ім'я, оскільки .cmd файл автоматично шукатиме .ps1, використовуючи власне ім’я.

::====================================================================
:: 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 дозволяє запускати .cmd файл із командного рядка без необхідності переходити до конкретного каталогу, де розташовані сценарії. Він зміниться в каталог сценаріїв, після завершення поверніться до початкового каталогу.

Ви також можете зняти паузу, якщо ви хочете, щоб вікно команди зникло після завершення сценарію.

Якщо мій скрипт .ps1 має параметри, я підказую для них підказки GUI, використовуючи .NET Forms, але також роблю сценарії достатньо гнучкими, щоб приймати параметри, якщо я хочу передати їх замість. Таким чином я можу просто двічі клацнути по ньому від Explorer і не повинен знати деталі параметрів, оскільки він запитає, що мені потрібно, зі списками або іншими формами.


2
Дякуємо за пакетний файл. Так, щоб ви знали, ви можете замінити оператор "для" просто: "встановити SCRIPT_PATH =% ~ p0" (без лапок). Насправді, я б використовував ~ dp0 замість ~ p0, тому він буде працювати через диски. Я сам цим скористаюся.
zumalifeguard

2

Це ґрунтується на відповіді KoZm0kNoT. Я змінив його для роботи на різних дисках.

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

Два pushd / popd необхідні у випадку, якщо cwd користувача знаходиться на іншому диску. Без зовнішнього набору cwd на диску з сценарієм загубиться.


2

Це те, що я використовую, щоб сценарії за замовчуванням виконувалися як адміністратор:

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

Вам потрібно буде вставити це в regedit як значення за замовчуванням для:

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

Або ось сценарій, який зробить це за вас:

$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

Якщо ви знайомі з розширеним адмініструванням Windows, ви можете скористатися цим пакетом ADM (інструкції містяться на цій сторінці) та дозволити запускати сценарії PowerShell після подвійного клацання через цей шаблон і Local GPO. Після цього ви можете просто змінити програму за замовчуванням, пов’язану з файлом .ps1, наpowershell.exe (використовувати пошук, це досить приховано), і ви готові запускати сценарії PowerShell подвійним клацанням.

В іншому випадку я рекомендую дотримуватися інших пропозицій, оскільки ви можете зіпсувати всю систему за допомогою цих інструментів адміністрування.

Я думаю, що налаштування за замовчуванням занадто суворі. Якщо комусь вдається нанести якийсь шкідливий код на ваш комп’ютер, він також зможе обійти це обмеження (загорнувши його у .cmd-файл або .exe, або трюк із ярликом), і все, що в кінцевому підсумку виконується - це просто запобігти ви з легкого способу запуску написаного сценарію.


Після встановлення ви можете знайти цей параметр у "Редакторі локальної групової політики" у розділі: Політика локальних комп'ютерів -> Конфігурація комп'ютера -> Адміністративні шаблони -> Компоненти Windows. Там ви можете це ввімкнути та переконайтесь, що виберіть політику у випадаючому списку, яка стає активованою тоді.
Wouter

1

Ви можете використовувати функцію Windows SendTo, щоб полегшити запуск сценаріїв PS1. Використовуючи цей метод, ви можете клацнути правою кнопкою миші на скрипті PS1 і виконати. Це не точно відповідає на питання ОП, але це близько. Сподіваємось, це корисно для інших. До речі .. це корисно для різних інших завдань.

  • Знайдіть / шукайте Powershell.exe
  • Клацніть правою кнопкою миші на Powershell.exe і виберіть Відкрити розташування файлу
  • Клацніть правою кнопкою миші на Powershell.exe та оберіть Створити ярлик. Тимчасово збережіть місце, наприклад робочий стіл
  • Можливо, ви хочете відкрити як адміністратора за замовчуванням. Виберіть ярлик> Властивості> Додатково> Відкрити як адміністратор
  • Відкрийте папку Sendto. Пуск> Виконати> Оболонка: Надіслати
  • Перемістіть ярлик Powershell.exe у папку Sendto
  • Тепер ви можете мати правою кнопкою миші на сценарій PS1.
  • Клацніть правою кнопкою миші на файл PS1, виберіть контекстний параметр SendTo> Виберіть ярлик Powershell
  • Ваш сценарій PS1 повинен виконуватись.

1
Як це краще, ніж за замовчуванням у контекстному меню "Запустити з Powershell"?
elBradford

1

Я використав це (потрібно запустити його лише один раз); також переконайтеся, що у вас є права на виконання:

від PowerShell з підвищеними правами:

Set-ExecutionPolicy=RemoteSigned

потім з файлу bat:

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

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

 assoc .ps1=Microsoft.PowerShellScript.1

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

і вуаля; двічі клацнувши * .ps1, він виконає його.


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

Для мене працювало лише поєднання прийнятої відповіді з цією відповіддю, як тільки я використовував команду із прийнятої відповіді в ключі реєстру. Мабуть, біг assocпотрібен.
ajeh

@ajeh (вибачте за біенг, давайте партії. Якщо ви отримаєте цю помилку, її через те, що у вас є неправильні одиничні цитати. Переконайтеся, що ви використовуєте UTF-8. (використовуйте блокнот ++; киньте два рядки, збережіть як файл runme.cmd )
Пол Фіджма

1

У Windows 10 ви також можете видалити заміщення Windows Explorer для асоціації розширень файлів:

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

на додаток до HKEY_CLASSES_ROOT\Microsoft.PowerShellScript.1\Shell\open\command зміни, зазначеної в інших відповідях.

Дивіться https://stackoverflow.com/a/2697804/1360907


1

Я спробував найкращі відповіді на це питання, але зіткнувся з повідомленнями про помилки. Тоді я знайшов відповідь тут:

PowerShell каже: "виконання скриптів у цій системі відключено".

Для мене добре працювало це рішення:

powershell -ExecutionPolicy Bypass -File script.ps1

Ви можете вставити його у .bat файл і двічі клацнути по ньому.


Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.