你们知道是否可以将仅由函数组成的PowerShell项目转换为模块?我想要实现的是创建我所有功能的可分发模块,以便其他人可以使用它。但无需花费时间将所有函数转换为 cmdlet。
我的每个函数都在单独的文件中。当我创建 *.psd1 并尝试通过“FunctionsToExport”包含函数时,它不起作用。加载模块后我看不到我的功能。
当模块(全部)不在 .psm1 文件内时,是否可以从模块导出函数?我仍在尝试找出 *psd1 和 *psm1 文件的真正区别和用途。
我的项目的结构如下:
MyScript.ps1
classes\
Car.ps1
Tesla.ps1
Run Code Online (Sandbox Code Playgroud)
Car.ps1是Tesla.ps1的基类。我试图在Tesla.ps1中这样定义Tesla:
. "$PSScriptRoot\Car.ps1"
class Tesla : Car
{
}
Run Code Online (Sandbox Code Playgroud)
MyScript.ps1需要使用Tesla类,但不必知道它是从Car继承的。
. "$PSScriptRoot\classes\Tesla.ps1"
$tesla = [Tesla]::new()
Run Code Online (Sandbox Code Playgroud)
点采购classes\Tesla.ps1工作正常,但从Tesla文件中抛出此错误:
找不到类型[汽车]
如果我以正确的顺序将所有文件导入MyScript.ps1,则可以正常工作。例:
. "$PSScriptRoot\classes\Car.ps1"
. "$PSScriptRoot\classes\Tesla.ps1"
$tesla = [Tesla]::new()
Run Code Online (Sandbox Code Playgroud)
这很麻烦,尤其是随着复杂性的增长。我的网点采购不正确吗?有没有更好的方法可以使用PSModulePath中没有的相对路径导入自定义PowerShell类?
我刚刚阅读 PowerShell模块指南页面,注意到该Import-Module部分有一行:
以下操作会触发模块的自动导入,也称为“模块自动加载”。
- 在命令中使用 cmdlet。例如,键入 Get-ExecutionPolicy 会导入包含 Get-ExecutionPolicy cmdlet 的 Microsoft.PowerShell.Security 模块。
既然如此,我们为什么要关心使用Import-Module呢?它不是总是自动照顾我们吗?在什么情况下我需要明确写出Import-Module?
我正在用C#编写二进制Powershell模块,我想要一个带有参数的Cmdlet,它提供动态的运行时选项卡完成.但是,我正在努力弄清楚如何在二进制模块中执行此操作.这是我试图让这个工作:
using System;
using System.Collections.ObjectModel;
using System.Management.Automation;
namespace DynamicParameterCmdlet
{
[Cmdlet("Say", "Hello")]
public class MyCmdlet : PSCmdlet
{
[Parameter, PSTypeName("string")]
public RuntimeDefinedParameter Name { get; set; }
public MyCmdlet() : base() {
Collection<Attribute> attributes = new Collection<Attribute>() {
new ParameterAttribute()
};
string[] allowedNames = NameProvider.GetAllowedNames();
attributes.Add(new ValidateSetAttribute(allowedNames));
Name = new RuntimeDefinedParameter("Name", typeof(string), attributes);
}
protected override void ProcessRecord()
{
string name = (string)Name.Value;
WriteObject($"Hello, {Name}");
}
}
public static class NameProvider
{
public static string[] GetAllowedNames()
{
// Hard-coded array …Run Code Online (Sandbox Code Playgroud) 我正在研究一个依赖于 SqlServer 的 PS 模块。
这是模块清单文件:
@{
ModuleVersion = "1.0.19103.11"
GUID = "59bc8fa6-b480-4226-9bcc-ec243102f3cc"
Author = "..."
CompanyName = "..."
Copyright = "..."
Description = "..."
RequiredModules = ""
ScriptsToProcess = "vsts\config.ps1"
NestedModules = @( ... )
PrivateData = @{
PSData = @{
ExternalModuleDependencies = @(
"SqlServer"
)
}
}
}
Run Code Online (Sandbox Code Playgroud)
以下是我用来发布模块的命令:
if (Get-PSRepository $PSRepositoryName -ErrorAction SilentlyContinue)
{
Unregister-PSRepository $PSRepositoryName
}
Register-PSRepository $PSRepositoryName `
-SourceLocation $NuGetRepoUrl `
-PublishLocation $NuGetRepoUrl `
-InstallationPolicy Trusted `
-PackageManagementProvider nuget
Publish-Module -Name $ModuleManifestFile -NuGetApiKey $NuGetApiKey -Repository …Run Code Online (Sandbox Code Playgroud) 我最近开始在 C# 中尝试二进制 PowerShell 编程,但我在 ParameterValidationAttributes(主要是 ValidateScript 属性)方面遇到了一些问题。基本上,我想创建一个名为“ComputerName”的参数并验证当时计算机是否在线。在 PowerShell 中很容易:
[Parameter(ValueFromPipeLine = $true)]
[ValidateScript({ if (Test-Connection -ComputerName $_ -Quiet -Count 1) { $true } else { throw "Unable to connect to $_." }})]
[String]
$ComputerName = $env:COMPUTERNAME,
Run Code Online (Sandbox Code Playgroud)
但我不知道如何在 C# 中复制它。ValidateScript 属性采用 ScriptBlock 对象http://msdn.microsoft.com/en-us/library/system.management.automation.scriptblock(v=vs.85).aspx我只是不确定如何在 C# 中创建它,我真的找不到任何例子。
[Parameter(ValueFromPipeline = true)]
[ValidateScript(//Code Here//)]
public string ComputerName { get; set; }
Run Code Online (Sandbox Code Playgroud)
C# 对我来说很陌生,所以如果这是一个愚蠢的问题,我深表歉意。这是 ValidateScript 属性类的链接:http : //msdn.microsoft.com/en-us/library/system.management.automation.validatescriptattribute(v=vs.85).aspx
我是 PowerShell 新手,刚刚开始创建自己的模块。我创建了脚本和清单文件,并将它们放入C:\Program Files\WindowsPowerShell\Modules\列出的目录之一$env:PSModulePath。
我也可以导入和删除该模块,但当我尝试调用其中一个函数时,它不会被识别为小程序或命令。
我使用导入模块命令:
Import-Module MyModule
Run Code Online (Sandbox Code Playgroud)
我的脚本文件是这样的:
function MyFunction() {}
Export-ModuleMember -Function *
Run Code Online (Sandbox Code Playgroud)
我的清单如下所示:
FunctionsToExport = '*'
Run Code Online (Sandbox Code Playgroud)
我需要将所有导出的函数写入清单吗?
感谢您的帮助。
请注意:
C:\> $TestVariable
C:\> $a
C:\> get-command Test-VariableExport
CommandType Name Version Source
----------- ---- ------- ------
Function Test-VariableExport 0.0.0.1 Test
C:\> (get-command Test-VariableExport).ScriptBlock
$script:TestVariable = Get-Date
C:\> Test-VariableExport
C:\> $TestVariable
C:\> function f() { $script:a = Get-Date }
C:\> f
C:\> $a
Monday, April 15, 2019 2:48:59 PM
C:\> f
C:\> $a
Monday, April 15, 2019 2:49:03 PM
C:\>
Run Code Online (Sandbox Code Playgroud)
当仅在函数内部时,相同的代码可以工作 - 变量a从函数导出到外部作用域。但是,当函数是模块的一部分(就像Test-VariableExport函数的情况一样)时,导出将不起作用。
如何使其适用于模块功能?
#Requires -Version 4 -Modules TestModule当我在第一行运行一个带有语句的简单脚本时,出现错误:
脚本“TestScript.ps1”无法运行,因为缺少脚本的“#requires”语句指定的以下模块: TestModule CategoryInfo : ResourceUnavailable: (TestScript.ps1:String) [], ScriptRequiresException ExcellentQualifiedErrorId : ScriptRequiresMissingModules
一些有趣的事实:
#Requires -Version 4 -Modules TestModule语句,但是当我运行脚本时#Requires,两个模块都会加载,没有任何问题。PSModulePath.Get-Module -ListAvailable列出 TestModule 及其所有命令。Import-Module第一次工作。$PSVersionTable:
Name Value
---- -----
PSVersion 4.0
WSManStackVersion 3.0
SerializationVersion 1.1.0.1
CLRVersion 4.0.30319.18444
BuildVersion 6.3.9600.16406
Run Code Online (Sandbox Code Playgroud)
我不知道发生了什么事。