是否可以通过双击.ps1文件来使PowerShell脚本正常工作?


139

我正在向我的团队分发PowerShell脚本。该脚本是要从Vsphere客户端获取IP地址,建立mstsc连接并将其记录在共享文件中。

他们使用脚本的那一刻,他们就知道了机器的IP地址。之后,他们总是倾向于直接使用mstsc而不是运行PowerShell脚本。(由于他们使用的是mstsc,所以我不知道他们是否经常使用VM。)

主要是他们告诉我,运行PowerShell并不简单。

他们的懒惰使我感到恶心。

是否可以通过双击.ps1文件来使PowerShell脚本正常工作?


3
如何在服务器上使用日志?“不信任用户”可能意味着您无法信任自己的数据,但更多的情况是意味着不要信任他不要偷懒。


使用Powershell Studio编译PS脚本 sapien.com/software/powershell_studio
根循环

我更喜欢通过vscode运行它(这样我就可以看到
consol

Answers:


132

创建一个类似以下内容的快捷方式作为“目标”:

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

3
正如Jeffery Hicks(他是powershell中的权威资源)建议不要更改设置一样,我将您的答案投票为最佳答案,而JPBlanc答案将作为有用的答案。
Samselvaprabu 2012年

6
结合使用:`-noLogo -ExecutionPolicy unrestricted -file <path>`,方法是:@ user3071883
Ujjwal Singh,

1
@UjjwalSingh:-NoProfile也很有用,因为配置文件可以执行脚本不希望发生的所有事情。
乔伊,

5
对于未来的读者:下面的答案中有一个注册表破解可以完成OP的要求。接受的答案不是。
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文件。以我的拙见,能够开箱即用。

我将其称为“ The Powershell De-castration Hack”。大声笑享受!


26
这是此答案列表中唯一对我有用的选项。我不准备接受“不建议使用”作为答案-我告诉PC怎么做,PC没有告诉我。
马特2014年

7
这实际上是两次旁路。消除了对双击运行的限制,绕过了PowerShell的ExecutionPolicy,该策略旨在防止甚至从控制台运行不受信任的脚本。
Iszi 2014年

4
这是错误的方法。您正在更改“打开”命令的功能,而不是将“使用PowerShell运行”作为默认设置。请参阅下面的itgala.xyz答案。
Indy411 '16

4
如果确实要使用此方法,则实际上"C:\Windows\System32\WindowsPowerShell\v1.0\powershell.exe" -NoLogo -File "%1"%*可以在其中可选地包含注册表项的正确默认值-ExecutionPolicy unrestricted。请注意命令末尾的更改,该更改允许将零个或多个参数传递到PowerShell脚本。引号和百分号周围的间距应完全如图所示。
Glenn Slayden '16

2
对于命令行解决方案,而不是编辑注册表,您可以键入ftype Microsoft.PowerShellScript.1=^"^%SystemRoot^%\System32\WindowsPowerShell\v1.0\powershell.exe^" -NoLogo -ExecutionPolicy Unrestricted -File ^"%1^" %*将完成相同的操作。
Damian T.

21

请注意,PowerShell的一项安全功能是用户无法双击启动脚本。如果您修改此设置,请格外小心。另一种选择是打包脚本。像PrimalScript这样的编辑器可以做到这一点。用户仍然需要安装PowerShell,但是他们可以双击exe。听起来您的团队需要一点教育。


3
这是一项安全功能,因为它使黑客至少延迟了几分钟,直到他们找到替代方案为止!
MarcH '16

23
这是一个愚蠢且无用的安全功能。您可以通过双击对它进行批处理吗?是的,exe?是。VBScript?是。我不知道为什么一个poweshell脚本比其他所有脚本都更令人浮躁
Mauro F.

12
我不知道你们是谁,但在意外双击之前,我肯定已经在错误的计算机上运行了bat文件。有了一些旨在使管理自动化的工具,将其加以限制是很有意义的。
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预期的方式通过文件关联来完成注册表时,为什么我们直接编辑注册表或使用批处理文件?
Kickass博士

@ 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?无论如何,感谢您的脚本。
Wouter 2012年

15

您需要调整注册表。首先,为HKEY_CLASSES_ROOT配置PSDrive,因为默认情况下未设置。该命令是:

New-PSDrive HKCR Registry HKEY_CLASSES_ROOT

现在,您可以像在常规HKCU和HKLM PSDrives中一样在HKEY_CLASSES_ROOT中导航和编辑注册表项和值。

要配置双击以直接启动PowerShell脚本,请执行以下操作:

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

要配置双击以在PowerShell ISE中打开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 '16

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”(启动记事本)的现有值,然后键入“ 0”(为零,直接启动Powershell)。

如果希望再次使用记事本作为默认值,请还原该值。


5

您可以将文件的默认文件关联设置ps1powershell.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的答案。
Marteng

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

通过push / popd,您可以从命令提示符启动.cmd文件,而不必更改到脚本所在的特定目录。它将更改为脚本目录,然后在完成后返回原始目录。

如果您希望脚本完成后命令窗口消失,也可以暂停一下。

如果我的.ps1脚本具有参数,我会使用.NET Forms进行GUI提示,以提示它们,但也可以使脚本足够灵活以接受参数(如果我想传递它们)。这样,我可以从资源管理器中双击它,而不必知道参数的详细信息,因为它将以列表框或其他形式询问我需要什么。


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

如果用户的cwd在不同的驱动器上,则需要两个压入/弹出操作。没有外部设置,带有脚本的驱动器上的cwd将丢失。


2

这就是我默认使用scrip以admin身份运行的方式:

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程序包(该页中包含说明),并通过此模板和本地GPO双击后允许运行PowerShell脚本。此后,您可以简单地将与.ps1文件类型关联的默认程序更改为powershell.exe(使用搜索,它已隐藏),您可以双击运行PowerShell脚本。

否则,我建议您坚持其他建议,因为您可以使用这些管理工具弄乱整个系统。

我认为默认设置太严格了。如果有人设法在您的计算机上放置了一些恶意代码,那么他/她也可以绕过此限制(将其包装到.cmd文件或.exe中,或使用快捷方式进行欺骗),最终它所做的一切仅仅是为了防止您可以通过简单的方式来运行编写的脚本。


安装完成后,您可以在“本地组策略编辑器”中的以下位置找到此设置:本地计算机策略->计算机配置->管理模板-> Windows组件。您可以在此处启用它,并确保在随后启用的下拉列表中选择一个策略。
Wouter 2012年

1

您可以使用Windows的“ SendTo”功能来简化PS1脚本的运行。使用这种方法,您可以右键单击PS1脚本并执行。这不能完全回答OP问题,但是很接近。希望这对其他人有用。顺便说一句..这对于其他各种任务很有帮助。

  • 找到/搜索Powershell.exe
  • 右键单击Powershell.exe,然后选择“打开文件位置”
  • 右键单击Powershell.exe,然后选择“创建快捷方式”。暂时保存桌面等位置
  • 默认情况下,您可能想以管理员身份打开。选择快捷方式>属性>高级>以管理员身份打开
  • 打开Sendto文件夹。开始>运行> Shell:Sendto
  • 将Powershell.exe快捷方式移动到Sendto文件夹
  • 现在,您应该可以右键单击PS1脚本。
  • 右键单击PS1文件,选择SendTo上下文选项>选择Powershell快捷方式
  • 您的PS1脚本应执行。

1
这比默认的“使用Powershell运行”上下文菜单选项有什么好处?
elBradford

1

我用了这个(只需要运行一次)。还请确保您有权执行:

从具有提升权限的PowerShell中:

Set-ExecutionPolicy=RemoteSigned

然后从蝙蝠文件:

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

 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文件) )
Paul Fijma

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



By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.