【问题标题】:Where to put PowerShell scripts?在哪里放置 PowerShell 脚本?
【发布时间】:2009-06-18 07:22:35
【问题描述】:

(我不敢相信我真的在问这个问题,但我一天都没有脑力。)

我刚刚编写了我的第一个严肃的 PowerShell 脚本,我对此非常满意。我计划每天左右使用它。我希望能够从 Posh 命令行调用它。我会给它一个动词-名词类型的名称,但现在它是一个简单的 .ps1,而不是那些接受参数等的花哨的高级函数。

那么它应该去哪里以及如何从 Posh 命令行调用它?我打算写更多!他们应该去哪里?

  • 它应该是我个人资料中的一个功能吗?
  • 它应该走上我的路吗?
  • 它是否进入 PSMODULEPATH?到底什么样的东西去那里?它看起来是递归的还是和普通的 PATH 一样?

你们都将 PowerShell 脚本放在哪里以及如何组织它们?我有很多制作 C# 和 C++ 工具的经验,并且知道如何命名它们以及将它们放在哪里。在另一个极端,我做了很多糟糕的 .bat 文件,这些文件通常是独立的,或者堆积在某个文件夹中。但 PowerShell 似乎非常不同。您可以非常快速地在其中制作蹩脚的 .bat 文件类型的东西,或者您可以使用它构建库和复杂的服务。

我真的很喜欢在开始之前我应该​​如何开始组织这些事情的一些想法。显然每个人都是不同的,所以我希望有一些讨论。谢谢!

【问题讨论】:

    标签: powershell


    【解决方案1】:

    我将我的个人脚本与我的个人资料放在同一个文件夹中。然后我可以一起备份和版本化它们。我的个人资料开头是:

    $ProfileRoot = (Split-Path -Parent $MyInvocation.MyCommand.Path)
    $env:path += ";$ProfileRoot"
    

    【讨论】:

    • 使用 $script:MyInvocation.MyCommand.Path,参见 source path of an executing script。即使使用配置文件脚本,您也会遇到嵌套调用者的问题,例如,我有一个帮助函数来重新加载您的配置文件(在函数/变量编辑之后)但跳过所有一次性初始化(如加载 .NET 程序集)。
    • 这个脚本是幂等的吗?或者您是否可能会在每次运行时一遍又一遍地重新附加同一个目录?
    【解决方案2】:

    我的建议: - 根据需要将脚本存储在目录中,例如c:\豪华 - 将目录添加到 $env:path

    $env:path += ";c:\posh"
    

    这确保您可能在其他目录中,例如 c:\windows,但您可以调用脚本

    [c:\windows] > sampl[TAB] # it expands the name of file to sample.ps1, then hit enter
    

    如果您的文件 sample.ps1 包含函数定义并且您每次都导入它,那么我会考虑将此行添加到您的 $profile 文件中

    . c:\posh\sample.ps1
    

    关于脚本组织.. 根据脚本的目的,只需几个目录 :) Personal, dev, external (downloaded), samples,...

    【讨论】:

    • 这是最直接的答案,并且有效。此外,它不会破坏您的个人组织。至于备份等。这些是非常自定义的,因此您应该根据具体情况存储用于备份的脚本等。另外,“备份”与问题并不真正相关:)。
    【解决方案3】:

    使用 V2,您可以在配置文件所在的 WindowsPowerShell 目录中创建模块目录。当您运行 import-module 时,PS 会自动在该目录中查找以加载模块。我还在 WindowsPowerShell 下创建了一个“Scripts”目录,它是 Modules 的同级目录。

    我使用我的配置文件通过以下代码使用变量设置一些目录:

    PS>  cat $Profile
    $scripts = "$(split-path $profile)\Scripts"
    $modules = "$(split-path $profile)\Modules"
    $docs    =  $(resolve-path "$Env:userprofile\documents")
    $desktop =  $(resolve-path "$Env:userprofile\desktop")
    
    PS> cat variable:\scripts
    C:\Users\andy.schneider\Documents\WindowsPowerShell\Scripts
    
    PS>  cat variable:\modules
    C:\Users\andy.schneider\Documents\WindowsPowerShell\Modules
    

    【讨论】:

    • 我也是这样做的。虽然我也有一个“库”目录,其中包含我的配置文件自动执行以定义全局函数的脚本。我在 PowerShell v1 中做到了这一点,我最终可能会用模块替换所有这些。
    【解决方案4】:

    这就是我的工作:

    注意:用“ModuleName”代替有意义的东西。

    创建一个模块并将其保存在全局模块文件夹中 “C:\Windows\System32\WindowsPowerShell\v1.0\Modules\ModuleName\ModuleName.psm1”。例如:

    function global:FancyFunction() {
       # do something interesting here.
    }
    
    Export-ModuleMember -function FancyFunction 
    

    打开您的 powershell 配置文件并添加以下行以确保每次启动 powershell 会话时都加载您的模块:

    Import-Module ModuleName -Force
    

    您可以通过键入以下内容轻松找到您的 powershell 配置文件:

    notepad $profile
    

    当您打开一个新的 powershell 会话时,您应该能够从控制台或其他脚本调用您的函数,而无需执行任何其他操作。

    【讨论】:

      【解决方案5】:

      powershell 7.1 中使用的 PowerShellGet 模块中有一个导出的变量

      $PSGetPath
      

      它有 4 个属性

      AllUsersModules    : C:\Program Files\PowerShell\Modules
      AllUsersScripts    : C:\Program Files\PowerShell\Scripts
      CurrentUserModules : C:\Users\username\Documents\PowerShell\Modules
      CurrentUserScripts : C:\Users\username\Documents\PowerShell\Scripts
      

      您可以使用其中一个脚本位置。 Install-Script 也在使用它们。

      【讨论】: