从特定目录将所有函数加载到PowerShell中

时间:2009-04-18 17:25:33

标签: powershell

假设您是使用PowerShell管理其系统上许多内容的系统管理员。

你可能已经编写了很多功能,可以做你经常需要检查的事情。但是,如果你需要移动很多,使用不同的机器等等,你必须一次又一次地重新输入所有功能才能使用它们。每次我因为某些原因退出并重新启动PowerShell时,我甚至必须这样做,因为它不会记住这些功能......

我已经为我编写了一个函数。我在这里发帖是因为我想确定它是万无一失的。函数本身存储在allFunctions.ps1中,这就是我在代码中排除它的原因。

基本思想是你有一个文件夹,你可以在其中存储所有ps1文件,每个文件都包含一个函数。在PowerShell中,您转到该目录,然后输入:

. .\allFunctions.ps1

该脚本的内容是:

[string]$items = Get-ChildItem -Path . -Exclude allFunctions.ps1
$itemlist = $items.split(" ")
foreach($item in $itemlist)
{
    . $item
}

此脚本将首先收集目录中的每个文件,这意味着您可能还拥有所有非ps1文件。将排除allFunctions.ps1。

然后我根据空格分割长字符串,这是常用的分隔符。然后我用Foreach循环遍历它,每次将函数初始化为PowerShell。

假设你有超过100个功能,你永远不知道你需要哪些功能,哪些不会?为什么不输入所有而不是挑剔?

所以我想知道,这里会出现什么问题?我希望这是非常安全的,因为我可能会使用它很多。

6 个答案:

答案 0 :(得分:15)

将它们包含在PowerShell配置文件中,以便每次启动PS时它们都会自动加载。

查看Windows PowerShell Profiles,了解有关在何处查找个人资料脚本的详细信息。

PS将您的个人资料默认为“我的文档”文件夹。我的网络驱动器,所以我登录的任何地方,PowerShell都指向相同的配置文件夹。

答案 1 :(得分:11)

您可以更简单的方式执行此操作。我在我的个人资料中有这个:

##-------------------------------------------
## Load Script Libraries
##-------------------------------------------
Get-ChildItem ($lib_home + "*.ps1") | ForEach-Object {& (Join-Path $lib_home $_.Name)} | Out-Null

其中$ lib_home是一个存储我想要自动包含的脚本的文件夹。在这种情况下,它执行它们。所以我有脚本定义全局函数。你也可以点源它们(用“。”代替“&”。)。

答案 2 :(得分:6)

功能明智我认为有两种方法可以改进您的脚本。

首先,您的脚本取决于脚本名称不变。虽然我认为你可能不会改变这个剧本的名字,但你永远不知道从现在开始几年你会有什么样的心情。相反,为什么不动态地计算脚本的名称。

$scriptName = split-path -leaf $MyInvocation.MyCommand.Definition

下一个问题是,如果您将目录放在包含空格的路径中,我相信您的拆分功能将失败。这将导致像“c:\ foo bar \ baz.ps1”这样的路径显示为“c:\ foo”,“bar \ baz.ps1”。删除拆分更好,只需使用get-childitem命令进行枚举即可。

此外,您依赖当前路径作为包含脚本的路径。你应该使它成为一个显式参数或使用包含allFunctions.ps1文件的路径(我更喜欢后者)

这是我将使用的更新版本。

$scriptName = split-path -leaf $MyInvocation.MyCommand.Definition
$rootPath = split-path -parent $MyInvocation.MyCommand.Definition
$scripts = gci -re $rootPath -in *.ps1 | ?{ $_.Name -ne $scriptName }
foreach ( $item in $scripts ) {
  . $item.FullName
}

从安全角度来看,您必须考虑恶意用户将错误脚本添加到目标目录的可能性。如果他们这样做,它将使用您的allFunctions.ps1文件执行,并可能对计算机造成损害。但是在恶意用户可以访问您的文件系统的时候,他们可能会在没有您的脚本帮助的情况下造成损害,所以这可能是一个小问题。

答案 3 :(得分:0)

简单的解决方案:

$Path - file location
$Name - exluded file

Get-ChildItem -Path $Path | Where {$_.psIsContainer -eq $false}|Where { $_.Name -like "*.ps1" }|Where { $_.Name -ne $Name }|foreach-object -process {.$_.FullName}|out-null

read all object|file only| powershell file only|exclude file $Name| run ...|out-null

答案 4 :(得分:0)

另一种解决方案是将函数组合到模块(psm1)文件中,并使用Import-Module命令将其导入。您可以如上所述将Import-Module命令添加到配置文件,但语法更简单。

一种简单的方法是在WindowsPowerShell目录中创建一个名为Modules的文件夹。在该文件夹中,创建另一个包含模块名称的文件夹。您的psm1文件保存在此处。然后将Import-Module ModuleName.psm1添加到WindowsPowerShell目录中的配置文件。如果要使用其他配置文件或将模块保存在其他位置,则需要相应地操作路径。

另一个提示是对模块文件中的每个函数使用Export-ModuleMember FunctionName。这将模糊您可能将其分发给最终用户的支持功能。

答案 5 :(得分:0)

我在Microsoft.PowerShell_profile.ps1中使用PowerShell 4和以下两行:

$modules = $env:USERPROFILE + "\..\*.psm1"
Import-Module $modules

此外:A tutorial to create advanced modules