Есть ли способ заставить скрипт PowerShell работать, дважды щелкнув файл .ps1?


139

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

В тот момент, когда они использовали скрипт, они узнали IP-адрес компьютера. После этого они всегда склонны использовать mstsc напрямую вместо запуска сценария PowerShell. (Поскольку они используют mstsc, я не могу знать, часто ли они используют виртуальную машину или нет.)

В основном они говорят мне, что запуск PowerShell не прост.

Меня тошнит от их лени.

Есть ли способ заставить скрипт PowerShell работать, дважды щелкнув файл .ps1?


3
Как насчет использования журналов на сервере? «Не доверяйте пользователю» может означать, что вы не можете доверять ему свои данные, но чаще это означает, что не доверяйте ему, чтобы он не ленился.


Компиляция сценария PS с использованием Powershell studio sapien.com/software/powershell_studio
Root Loop

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

Ответы:


132

Создайте ярлык с именем типа «Цель»:

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

3
Как сказал Джеффри Хикс (он является авторитетным ресурсом в powershell), менять настройки не рекомендуется, я бы проголосовал, чтобы ваш ответ был лучшим, а ответ JPBlanc - полезным.
Самсельвапрабу

6
используйте это с: `-noLogo -ExecutionPolicy unrestricted -file <path>` в ответ на это: @ user3071883
Singh

1
@UjjwalSingh: -NoProfileтакже полезно, так как профиль может делать все то, что сценарий не ожидает.
Джои

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

2
Есть ли способ сделать это, но используя относительный / текущий путь?
Мифофешелон

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 De-кастрации». LOL наслаждайся!


27
Это единственный, который работал для меня в этом списке ответов. Я не готов принять «Это не рекомендуется» в качестве ответа - я говорю ПК, что делать, ПК не говорит мне.
Мэтт

7
Это на самом деле двойной обход. Снимает ограничение на двойной щелчок при запуске и обходит PowerShell ExecutionPolicy, который предназначен для предотвращения запуска ненадежных сценариев даже из консоли.
Изи

4
Это неправильный способ сделать это. Вы изменяете то, что делает команда «Открыть», вместо того, чтобы установить «Запуск с PowerShell» по умолчанию. Смотрите ответ itgala.xyz ниже.
Indy411 10.10.16

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, но затем они могут дважды щелкнуть исполняемый файл. И, похоже, ваша команда нуждается в небольшом образовании.


3
Это функция безопасности, потому что она задерживает хакеров как минимум на несколько минут, пока они не найдут альтернативу!
марше

23
Это глупая и бесполезная функция безопасности. Можете ли вы запустить партию двойным циклом? Да, Отлично? Да. VBScript? Да. Я не могу понять, почему сценарий «Poweshell» будет считаться более опасным, чем все остальные
Мауро Ф.

12
Я не знаю, как вы, ребята, но я определенно запустил файл с битой на неправильном компьютере, предварительно дважды щелкнув по нему. Что-то предназначенное для автоматизации администрирования, имеет смысл ограничить это.
Lordcheeto

1
Вы можете дважды щелкнуть по файлу EXE, поэтому я не вижу, как это помогает. Но, несомненно, команда Powershell знает об этом основном аргументе. Там должно быть больше к этому.
USR

1
Если вы пишете сценарии, которые «опасны» для выполнения, и вы не добавляете базовый процесс подтверждения ... Я считаю, вам нравится жить опасно.
Ромен Винсент

18

Это работало для меня на Windows 10 и powershell 5.1:

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

2
Вероятно, вам нужно установить политику выполнения на хост-машине на что-то разумное, например RemoteSigned
vizmi,

4
Это несколько лет, и никто не думал об этом до полугода назад? - Я также сделал это, и он отлично работает, хотя вам придется сделать еще несколько настроек, или PowerShell вообще откажется запускать любые сценарии .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
Мне пришлось изменить его в этом месте, чтобы он работал: Computer \ HKEY_CLASSES_ROOT \ Applications \ powershell.exe \ Shell \ Open \ Command. Я не понимаю реестра достаточно, чтобы объяснить, почему это так. Может быть, потому что я использую Powershell 3.0? В любом случае, спасибо за сценарий.
Воутер

15

Вам нужно настроить реестр. Во-первых, настройте PSDrive для HKEY_CLASSES_ROOT, так как он не установлен по умолчанию. Команда для этого:

New-PSDrive HKCR Registry HKEY_CLASSES_ROOT

Теперь вы можете перемещаться и редактировать ключи и значения реестра в HKEY_CLASSES_ROOT так же, как и в обычных PSDrive HKCU и HKLM.

Чтобы настроить двойной щелчок для запуска сценариев PowerShell напрямую:

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

Чтобы настроить двойной щелчок для открытия сценариев PowerShell в PowerShell ISE:

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

Чтобы восстановить значение по умолчанию (устанавливает двойной щелчок, чтобы открыть сценарии PowerShell в блокноте):

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

Я попытался восстановить значение по умолчанию, используя последнюю строку из Elevated PowerShell ISE, но, очевидно, если вы использовали команду, подобную описанной в Thermionix, она заменяет Default, поэтому вам нужно явно сбросить 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. Удалите существующее значение «Open» (при запуске Notepad) и введите «0» (равное нулю, при котором непосредственно запускается Powershell).

Восстановите значение, если хотите снова использовать Блокнот по умолчанию.


5

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

В Windows 10

  1. Щелкните правой кнопкой мыши 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 имеет параметры, я запрашиваю их с помощью графического интерфейса, используя .NET Forms, но также делаю сценарии достаточно гибкими, чтобы принимать параметры, если я хочу вместо них передать их. Таким образом, я могу просто дважды щелкнуть по нему из Проводника и не знать детали параметров, так как он спросит меня, что мне нужно, со списками или другими формами.


2
Спасибо за пакетный файл. Просто чтобы вы знали, вы можете заменить выражение «for» просто: «set SCRIPT_PATH =% ~ p0» (без кавычек). На самом деле, я бы использовал ~ dp0 вместо ~ p0, чтобы он работал на разных дисках. Я буду использовать это сам.
zumalifeguard

2

Это основано на ответе KoZm0kNoT. Я изменил его для работы на разных дисках.

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

Два pushd / popds необходимы, если 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 после двойного щелчка по этому шаблону и локальному объекту групповой политики. После этого вы можете просто изменить программу по умолчанию, связанную с типом файла .ps1, на powershell.exe(используйте поиск, она довольно спрятана), и вы готовы запускать сценарии PowerShell двойным щелчком мыши.

В противном случае, я бы порекомендовал придерживаться других предложений, поскольку вы можете испортить всю систему с помощью этих инструментов администрирования.

Я думаю, что настройки по умолчанию слишком строги. Если кому-то удастся разместить вредоносный код на вашем компьютере, он / она также сможет обойти это ограничение (обернуть его в файл .cmd или .exe, или использовать ярлык с ярлыком), и все, что он в конце концов достигнет, это просто предотвратить Вы от простого способа запустить сценарий, который вы написали.


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

1

Вы можете использовать функцию Windows «SendTo», чтобы упростить запуск сценариев PS1. Используя этот метод, вы можете щелкнуть правой кнопкой мыши скрипт PS1 и выполнить. Это не совсем ответ на вопрос ОП, но это близко. Надеюсь, это полезно для других. Кстати ... это полезно для множества других задач.

  • Найдите / найдите Powershell.exe
  • Щелкните правой кнопкой мыши файл Powershell.exe и выберите «Открыть местоположение файла».
  • Щелкните правой кнопкой мыши файл Powershell.exe и выберите «Создать ярлык». Временно сохраните место, например, рабочий стол
  • Вы можете открыть как Admin по умолчанию. Выберите Ярлык> Свойства> Дополнительно> Открыть от имени администратора
  • Откройте папку Sendto. Пуск> Выполнить> Shell: Sendto
  • Переместите ярлык Powershell.exe в папку Sendto
  • Теперь вы сможете щелкнуть правой кнопкой мыши скрипт PS1.
  • Щелкните правой кнопкой мыши файл PS1, выберите контекстную опцию SendTo> выберите ярлык Powershell
  • Ваш скрипт PS1 должен выполнить.

1
Как это лучше, чем опция контекстного меню «Запуск с Powershell» по умолчанию?
ЭльБрадфорд

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 (извините за bieng leet для вечеринки. Если вы получаете эту ошибку, потому что у вас неправильные одинарные кавычки. Убедитесь, что вы используете UTF-8. (используйте notepad ++; удалите две строки, сохраните как файл runme.cmd )
Пол Фийма

1

В Windows 10 вы также можете удалить переопределение проводника Windows для ассоциации расширений файлов:

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.