284

我有一个 .ps1 文件,我想在其中定义自定义函数。

想象一下这个文件叫MyFunctions.ps1,内容如下:

Write-Host "Installing functions"
function A1
{
    Write-Host "A1 is running!"
}
Write-Host "Done"

要运行此脚本并在理论上注册 A1 函数,我导航到 .ps1 文件所在的文件夹并运行该文件:

.\MyFunctions.ps1

这输出:

Installing functions
Done

然而,当我尝试调用 A1 时,我只是收到错误消息,指出没有该名称的命令/函数:

The term 'A1' 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.
At line:1 char:3
+ A1 <<<<
    + CategoryInfo          : ObjectNotFound: (A1:String) [], CommandNotFoundException
    + FullyQualifiedErrorId : CommandNotFoundException

我必须误解一些 PowerShell 概念。我不能在脚本文件中定义函数吗?

请注意,我已经将执行策略设置为“RemoteSigned”。而且我知道在文件名前使用一个点来运行 .ps1 文件:.\myFile.ps1

4

7 回答 7

299

在 PowerShell 命令行上试试这个:

. .\MyFunctions.ps1
A1

点运算符用于脚本包括,又名“点源”(或“点源符号”

于 2011-05-16T11:22:42.630 回答
266

您所说的称为点源。这是邪恶的。但是不用担心,有一种更好、更简单的方法可以用模块来做你想做的事情(听起来比实际更可怕)。使用模块的主要好处是,如果需要,您可以从 shell 中卸载它们,并且它可以防止函数中的变量潜入 shell(一旦您点源函数文件,请尝试从在 shell 中运行,你会明白我的意思)。

因此,首先,将包含所有函数的 .ps1 文件重命名为 MyFunctions.psm1(您刚刚创建了一个模块!)。现在要正确加载模块,您必须对文件执行一些特定操作。首先要让 Import-Module 查看模块(您使用此 cmdlet 将模块加载到 shell 中),它必须位于特定位置。模块文件夹的默认路径是 $home\Documents\WindowsPowerShell\Modules。

在该文件夹中,创建一个名为 MyFunctions 的文件夹,并将 MyFunctions.psm1 文件放入其中(模块文件必须位于与 PSM1 文件同名的文件夹中)。

完成后,打开 PowerShell,然后运行以下命令:

Get-Module -listavailable

如果您看到一个名为 MyFunctions 的功能,那么您做对了,并且您的模块已准备好加载(这只是为了确保设置正确,您只需执行一次)。

要使用该模块,请在 shell 中键入以下内容(或将此行放在 $profile 中,或将其作为脚本的第一行):

Import-Module MyFunctions

您现在可以运行您的函数。很酷的一点是,一旦你有 10-15 个函数,你就会忘记一对夫妇的名字。如果您将它们放在模块中,则可以运行以下命令来获取模块中所有函数的列表:

Get-Command -module MyFunctions

它非常可爱,而且在前端设置所需的一点点努力是值得的。

于 2011-05-18T06:29:55.833 回答
20

. "$PSScriptRoot\MyFunctions.ps1" MyA1Func

从 v3 开始可用,在此之前请参阅如何获取 PowerShell 脚本的文件系统位置?. 这是很常见的。

PS 我不订阅“一切都是模块”规则。我的脚本被 GIT 之外的其他开发人员使用,所以我不喜欢在我的脚本运行之前将东西放在特定的地方或修改系统环境变量。它只是一个脚本(或两个,或三个)。

于 2015-02-05T15:33:43.873 回答
7

You certainly can define functions in script files (I then tend to load them through my Powershell profile on load).

First you need to check to make sure the function is loaded by running:

ls function:\ | where { $_.Name -eq "A1"  }

And check that it appears in the list (should be a list of 1!), then let us know what output you get!

于 2011-05-16T11:30:22.647 回答
6

您可以将功能添加到:

c:\Users\David\Documents\WindowsPowerShell\profile.ps1

该功能将可用。

于 2017-06-24T19:35:57.880 回答
4

如果您的文件只有一个您想要调用/公开的主要功能,那么您也可以使用以下方式启动文件:

Param($Param1)

然后你可以调用它,例如如下:

.\MyFunctions.ps1 -Param1 'value1'

如果您想轻松调用该函数而无需导入该函数,这将变得更加方便。

于 2017-10-01T22:10:30.573 回答
1

假设您有一个名为 Dummy-Name.psm1 的模块文件,其中有一个名为 Function-Dumb() 的方法

Import-Module "Dummy-Name.psm1";
Get-Command -Module "Function-Dumb";
#
#
Function-Dumb;
于 2018-10-02T00:17:59.447 回答