Подтвердить что ты не робот

Могу ли я написать класс с помощью powershell?

Я все еще изучаю powershell, и до сих пор я не нашел ответа на этом сайте, несмотря на несколько поисков. С помощью Powershell, построенного поверх платформы .NET, могу ли я написать свой собственный пользовательский класс с помощью Powershell?

Я не говорю о создании экземпляров .NET-классов... эта часть достаточно проста. Я хочу написать свои собственные пользовательские классы, используя сценарии powershell. Возможное? До сих пор мое исследование заставляет меня сказать, что это невозможно. Но я хочу сначала подтвердить гуру...

4b9b3361

Ответ 1

Посмотрите Add-Type cmdlet. Он позволяет писать С# и другой код в PowerShell. Например (из приведенной выше ссылки),

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)

Ответ 2

Я подозреваю, что решение, которое вы ищете, 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

Как вы можете видеть, умножение является частным в модуле. Более традиционно вы должны наследовать объект, являющийся экземпляром модуля. Это делается через параметр -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, сохраните этот файл в папке с тем же именем (минус расширение) в качестве файла, Затем вы можете импортировать модуль в свой сеанс в командной строке или в другой script.

В качестве примера, скажем, я взял этот код:

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 представляет собой волшебную папку, и все хранящиеся там модули видны командлету Import-Module без указания пути. Теперь, если мы запускаем 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... {}

Мы видим, что наш модуль готов к вводу. Мы можем импортировать его в сеанс и использовать его в raw, используя:

Import-Module TestModule

Или еще раз мы можем создать экземпляр объекта:

$m = Import-Module TestModule -AsCustomObject

Ответ 3

Вы можете использовать ключевое слово class, которое было представлено в PowerShell 5.0

Вот пример Тревора Салливана. (Архивировано здесь.)

##################################################
####### 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 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 Pro.

Протестируйте его так:

# 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()