在PowerShell中,如何在文件中定义函数并从PowerShell命令行调用它?

时间:2011-05-16 11:04:51

标签: powershell

我有一个.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

7 个答案:

答案 0 :(得分:217)

在PowerShell命令行上尝试此操作:

. .\MyFunctions.ps1
A1

点运算符用于脚本include。

答案 1 :(得分:188)

您所谈论的内容称为 dot sourcing 。这是邪恶的。但不用担心,有一种更好,更简单的方法来做你想要的模块(听起来比它更可怕)。使用模块的主要好处是,如果需要,可以从shell中卸载它们,并且它可以使函数中的变量不再嵌入到shell中(一旦你点了一个函数文件,尝试调用一个变量来自一个在shell中运行,你会看到我的意思。)

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

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

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

Get-Module -listavailable

如果你看到一个名为MyFunctions,你就做对了,你的模块已经准备好加载了(这只是为了确保这个设置正确,你只需要这样做一次)。

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

Import-Module MyFunctions

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

Get-Command -module MyFunctions

它非常甜美,在正面设置所需的一点点努力都是值得的。

答案 2 :(得分:15)

. "$PSScriptRoot\MyFunctions.ps1" MyA1Func

可以从v3开始,然后再看How can I get the file system location of a PowerShell script?。这很常见。

P.S。我不赞成“一切都是模块”的规则。我的脚本被GIT中的其他开发人员使用,所以我不喜欢在我的脚本运行之前将内容放在特定的位置或修改系统环境变量。它只是一个脚本(或两个或三个)。

答案 3 :(得分:6)

您当然可以在脚本文件中定义函数(然后我倾向于在加载时通​​过我的Powershell配置文件加载它们)。

首先,您需要检查以确保通过运行来加载该功能:

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

并检查它是否出现在列表中(应该是1的列表!),然后告诉我们你得到的输出!

答案 4 :(得分:3)

您可以将功能添加到:

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

该功能将可用。

答案 5 :(得分:2)

如果您的文件只有一个要调用/公开的主函数,那么您也可以使用以下命令启动该文件:

Param($Param1)

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

.\MyFunctions.ps1 -Param1 'value1'

如果您想在不必导入函数的情况下轻松调用该函数,这将更加方便。

答案 6 :(得分:0)

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

Import-Module "Dummy-Name.psm1";
Get-Command -Module "Function-Dumb";
#
#
Function-Dumb;