我可以使用PowerShell编写一个类吗?

时间:2011-07-27 17:38:28

标签: powershell

我还在学习powershell,到目前为止,尽管进行了一些搜索,但我还没有在这个网站上找到答案。 由于Powershell是在.NET框架之上构建的,我可以使用Powershell编写自己的自定义类吗?

我不是在谈论实例化.NET类......那部分很简单。我想使用PowerShell脚本编写自己的自定义类。可能?到目前为止,我的研究让我说这是不可能的。但我想先和大师一起确认......

3 个答案:

答案 0 :(得分:48)

查看Add-Type cmdlet。它允许您在PowerShell中编写C#和其他代码。 例如(来自上面的链接),

C:\PS>$source = @"
public class BasicTest
{
    public static int Add(int a, int b)
    {
        return (a + b);
    }

    public int Multiply(int a, int b)
    {
        return (a * b);
    }
}
"@

C:\PS> Add-Type -TypeDefinition $source

C:\PS> [BasicTest]::Add(4, 3)

C:\PS> $basicTestObject = New-Object BasicTest 
C:\PS> $basicTestObject.Multiply(5, 2)

答案 1 :(得分:43)

我怀疑您正在寻找的解决方案是Powershell Modules。它们执行类通常在其他语言中执行的角色。它们为您提供了一种非常简单但结构化的方式来重用您的代码。

以下是如何使用模块获取PS中的类的功能。在命令行,您可以这样做:

New-Module -ScriptBlock {function add($a,$b){return $a + $b}; function multiply($a,$b){return $a * $b}; function supersecret($a,$b){return multiply $a $b}; export-modulemember -function add, supersecret}

然后你就可以:

PS C:\> add 2 4
6
PS C:\> multiply 2 4
The term 'multiply' 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 inc
luded, verify that the path is correct and try again.
At line:1 char:9
+ multiply <<<<  2 4
    + CategoryInfo          : ObjectNotFound: (multiply:String) [], CommandNotFoundException
    + FullyQualifiedErrorId : CommandNotFoundException

PS C:\> supersecret 2 4
8

正如您所见,multiply在模块中是私有的。传统上,您会将一个对象作为模块的实例。这是通过-AsCustomObject参数完成的:

$m = New-Module -ScriptBlock {function add($a,$b){return $a + $b}; function multiply($a,$b){return $a * $b}; function supersecret($a,$b){return multiply $a $b}; export-modulemember -function add, supersecret} -AsCustomObject

然后你可以:

PS C:\> $m.add(2,4)
6
PS C:\> $m.multiply(2,4)
Method invocation failed because [System.Management.Automation.PSCustomObject] doesn't contain a method named 'multiply'.
At line:1 char:12
+ $m.multiply <<<< (2,4)
    + CategoryInfo          : InvalidOperation: (multiply:String) [], RuntimeException
    + FullyQualifiedErrorId : MethodNotFound

PS C:\> $m.supersecret(2,4)

8

这一切都演示了动态模块的使用,这意味着没有任何内容存储到磁盘中以供重用。这对于非常简单的功能来说很好。如果您希望实际能够读取代码并在将来的会话或脚本中重复使用它,但是您希望将其存储在.psm1文件中,然后将该文件存储在与文件具有相同名称(减去扩展名)的文件夹中。然后,您可以在命令行或其他脚本中将模块导入会话。

作为一个例子,假设我使用了这段代码:

function Add{
    param(
            $a,
            $b
         )
    return $a + $b
}
function Multiply{
    param(
            $a,
            $b
         )
    return $a + $b
}
function SuperSecret{
    param(
            $a,
            $b
         )
    return Multiply $a $b
}
Export-ModuleMember -Function Add, SuperSecret

并将其保存到文件夹中名为TestModule.psm1的文件中:C:\ Windows \ System32 \ WindowsPowerShell \ v1.0 \ Modules \ TestModule

Powershell安装文件夹中的Modules文件夹是一个魔术文件夹,其中存储的所有模块对Import-Module cmdlet都是可见的,无需指定路径。现在,如果我们在命令行运行Get-Module -List,我们会看到:

ModuleType Name                      ExportedCommands
---------- ----                      ----------------
Script     DotNet                    {}
Manifest   FileSystem                {Get-FreeDiskSpace, New-Zip, Resolve-ShortcutFile, Mount-SpecialFolder...}
Manifest   IsePack                   {Push-CurrentFileLocation, Select-CurrentTextAsVariable, ConvertTo-Short...
Manifest   PowerShellPack            {New-ByteAnimationUsingKeyFrames, New-TiffBitmapEncoder, New-Viewbox, Ne...
Manifest   PSCodeGen                 {New-Enum, New-ScriptCmdlet, New-PInvoke}
Manifest   PSImageTools              {Add-CropFilter, Add-RotateFlipFilter, Add-OverlayFilter, Set-ImageFilte...
Manifest   PSRss                     {Read-Article, New-Feed, Remove-Article, Remove-Feed...}
Manifest   PSSystemTools             {Test-32Bit, Get-USB, Get-OSVersion, Get-MultiTouchMaximum...}
Manifest   PSUserTools               {Start-ProcessAsAdministrator, Get-CurrentUser, Test-IsAdministrator, Ge...
Manifest   TaskScheduler             {Remove-Task, Get-ScheduledTask, Stop-Task, Add-TaskTrigger...}
Manifest   WPK                       {Get-DependencyProperty, New-ModelVisual3D, New-DiscreteVector3DKeyFrame...
Manifest   AppLocker                 {}
Manifest   BitsTransfer              {}
Manifest   PSDiagnostics             {}
Script     **TestModule**                {}
Manifest   TroubleshootingPack       {}
Manifest   Citrix.XenApp.Commands... {}

我们可以看到我们的模块已准备好导入。我们可以将它导入到会话中并使用原始文件使用它:

Import-Module TestModule

或者我们可以再次实例化一个对象:

$m = Import-Module TestModule -AsCustomObject

答案 2 :(得分:24)

您可以使用the class keyword

中引入的PowerShell 5.0

这是example by Trevor Sullivan。 (已存档here。)

##################################################
####### WMF 5.0 November 2014 Preview ###########
##################################################
class Beer {
    # Property: Holds the current size of the beer.
    [Uint32] $Size;
    # Property: Holds the name of the beer's owner.
    [String] $Name;

    # Constructor: Creates a new Beer object, with the specified
    #              size and name / owner.
    Beer([UInt32] $NewSize, [String] $NewName) {
        # Set the Beer size
        $this.Size = $NewSize;
        # Set the Beer name
        $this.Name = $NewName;
    }

    # Method: Drink the specified amount of beer.
    # Parameter: $Amount = The amount of beer to drink, as an 
    #            unsigned 32-bit integer.
    [void] Drink([UInt32] $Amount) {
        try {
            $this.Size = $this.Size - $Amount;
        }
        catch {
            Write-Warning -Message 'You tried to drink more beer than was available!';
        }
    }

    # Method: BreakGlass resets the beer size to 0.
    [void] BreakGlass() {
        Write-Warning -Message 'The beer glass has been broken. Resetting size to 0.';
        $this.Size = 0;
    }
}

这适用于Windows 10专业版。

像这样试驾:

# Create a new 33 centilitre beer, named 'Chimay'
$chimay = [Beer]::new(33, 'Chimay');

$chimay.Drink(10)
$chimay.Drink(10)

# Need more beer!
$chimay.Drink(200)

$chimay.BreakGlass()